blob: a91574e3f0d43287baa5f5864dd1105fcd816545 [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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
27import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070028import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
30import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import static android.view.WindowManager.LayoutParams.MEMORY_TYPE_PUSH_BUFFERS;
32import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
33import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
34import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
35import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070036import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037
38import com.android.internal.app.IBatteryStats;
39import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080040import com.android.internal.policy.impl.PhoneWindowManager;
Christopher Tatea53146c2010-09-07 11:57:52 -070041import com.android.internal.view.BaseInputHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import com.android.internal.view.IInputContext;
43import com.android.internal.view.IInputMethodClient;
44import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080045import com.android.internal.view.WindowManagerPolicyThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import com.android.server.am.BatteryStatsService;
47
48import android.Manifest;
49import android.app.ActivityManagerNative;
50import android.app.IActivityManager;
Jim Millerd6b57052010-06-07 17:52:42 -070051import android.app.admin.DevicePolicyManager;
Jim Miller284b62e2010-06-08 14:27:42 -070052import android.content.BroadcastReceiver;
Christopher Tatea53146c2010-09-07 11:57:52 -070053import android.content.ClipData;
54import android.content.ClipDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070056import android.content.Intent;
57import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.content.pm.ActivityInfo;
59import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070060import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.res.Configuration;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070062import android.graphics.Canvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.graphics.Matrix;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070064import android.graphics.Paint;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import android.graphics.PixelFormat;
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070066import android.graphics.PorterDuff;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.graphics.Rect;
68import android.graphics.Region;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070069import android.graphics.Typeface;
70import android.graphics.Paint.FontMetricsInt;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.os.BatteryStats;
72import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070073import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import android.os.Debug;
75import android.os.Handler;
76import android.os.IBinder;
77import android.os.LocalPowerManager;
78import android.os.Looper;
79import android.os.Message;
80import android.os.Parcel;
81import android.os.ParcelFileDescriptor;
82import android.os.Power;
83import android.os.PowerManager;
84import android.os.Process;
85import android.os.RemoteException;
86import android.os.ServiceManager;
Brad Fitzpatrickec062f62010-11-03 09:56:54 -070087import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088import 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;
101import android.view.IApplicationToken;
102import android.view.IOnKeyguardExitResult;
103import android.view.IRotationWatcher;
104import android.view.IWindow;
105import android.view.IWindowManager;
106import android.view.IWindowSession;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700107import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700108import android.view.InputDevice;
Jeff Brownbbda99d2010-07-28 15:48:59 -0700109import android.view.InputEvent;
Christopher Tatea53146c2010-09-07 11:57:52 -0700110import android.view.InputHandler;
111import android.view.InputQueue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.view.KeyEvent;
113import android.view.MotionEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.view.Surface;
115import android.view.SurfaceSession;
116import android.view.View;
117import android.view.ViewTreeObserver;
118import android.view.WindowManager;
119import android.view.WindowManagerImpl;
120import android.view.WindowManagerPolicy;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700121import android.view.Surface.OutOfResourcesException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122import android.view.WindowManager.LayoutParams;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700123import android.view.animation.AccelerateInterpolator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import android.view.animation.Animation;
125import android.view.animation.AnimationUtils;
126import android.view.animation.Transformation;
127
128import java.io.BufferedWriter;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700129import java.io.DataInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130import java.io.File;
131import java.io.FileDescriptor;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700132import java.io.FileInputStream;
133import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134import java.io.IOException;
135import java.io.OutputStream;
136import java.io.OutputStreamWriter;
137import java.io.PrintWriter;
138import java.io.StringWriter;
139import java.net.Socket;
140import java.util.ArrayList;
141import java.util.HashMap;
142import java.util.HashSet;
143import java.util.Iterator;
144import java.util.List;
145
146/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700147public class WindowManagerService extends IWindowManager.Stub
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700148 implements Watchdog.Monitor {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 static final String TAG = "WindowManager";
150 static final boolean DEBUG = false;
151 static final boolean DEBUG_FOCUS = false;
152 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800153 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800154 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 static final boolean DEBUG_LAYERS = false;
156 static final boolean DEBUG_INPUT = false;
157 static final boolean DEBUG_INPUT_METHOD = false;
158 static final boolean DEBUG_VISIBILITY = false;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -0700159 static final boolean DEBUG_WINDOW_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700161 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static final boolean DEBUG_APP_TRANSITIONS = false;
163 static final boolean DEBUG_STARTING_WINDOW = false;
164 static final boolean DEBUG_REORDER = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700165 static final boolean DEBUG_WALLPAPER = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700166 static final boolean DEBUG_DRAG = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700168 static final boolean HIDE_STACK_CRAWLS = true;
Michael Chan53071d62009-05-13 17:29:48 -0700169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 static final boolean PROFILE_ORIENTATION = false;
171 static final boolean BLUR = true;
Dave Bortcfe65242009-04-09 14:51:04 -0700172 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 /** How much to multiply the policy's type layer, to reserve room
175 * for multiple windows of the same type and Z-ordering adjustment
176 * with TYPE_LAYER_OFFSET. */
177 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
180 * or below others in the same layer. */
181 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 /** How much to increment the layer for each window, to reserve room
184 * for effect surfaces between them.
185 */
186 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 /** The maximum length we will accept for a loaded animation duration:
189 * this is 10 seconds.
190 */
191 static final int MAX_ANIMATION_DURATION = 10*1000;
192
193 /** Amount of time (in milliseconds) to animate the dim surface from one
194 * value to another, when no window animation is driving it.
195 */
196 static final int DEFAULT_DIM_DURATION = 200;
197
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700198 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
199 * compatible windows.
200 */
201 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 /** Adjustment to time to perform a dim, to make it more dramatic.
204 */
205 static final int DIM_DURATION_MULTIPLIER = 6;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700206
207 // Maximum number of milliseconds to wait for input event injection.
208 // FIXME is this value reasonable?
209 private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
Jeff Brown349703e2010-06-22 01:27:15 -0700210
211 // Default input dispatching timeout in nanoseconds.
212 private static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 static final int UPDATE_FOCUS_NORMAL = 0;
215 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
216 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
217 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700220 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221
222 /**
223 * Condition waited on by {@link #reenableKeyguard} to know the call to
224 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500225 * This is set to true only if mKeyguardTokenWatcher.acquired() has
226 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500228 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229
Jim Miller284b62e2010-06-08 14:27:42 -0700230 private static final int ALLOW_DISABLE_YES = 1;
231 private static final int ALLOW_DISABLE_NO = 0;
232 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
233 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
234
Mike Lockwood983ee092009-11-22 01:42:24 -0500235 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
236 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700238 if (shouldAllowDisableKeyguard()) {
239 mPolicy.enableKeyguard(false);
240 mKeyguardDisabled = true;
241 } else {
242 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 }
245 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700246 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500247 synchronized (mKeyguardTokenWatcher) {
248 mKeyguardDisabled = false;
249 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 }
251 }
252 };
253
Jim Miller284b62e2010-06-08 14:27:42 -0700254 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
255 @Override
256 public void onReceive(Context context, Intent intent) {
257 mPolicy.enableKeyguard(true);
258 synchronized(mKeyguardTokenWatcher) {
259 // lazily evaluate this next time we're asked to disable keyguard
260 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
261 mKeyguardDisabled = false;
262 }
263 }
264 };
265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 final Context mContext;
267
268 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
273
274 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 /**
279 * All currently active sessions with clients.
280 */
281 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283 /**
284 * Mapping from an IWindow IBinder to the server's Window object.
285 * This is also used as the lock for all of our state.
286 */
287 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
288
289 /**
290 * Mapping from a token IBinder to a WindowToken object.
291 */
292 final HashMap<IBinder, WindowToken> mTokenMap =
293 new HashMap<IBinder, WindowToken>();
294
295 /**
296 * The same tokens as mTokenMap, stored in a list for efficient iteration
297 * over them.
298 */
299 final ArrayList<WindowToken> mTokenList = new ArrayList<WindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 /**
302 * Window tokens that are in the process of exiting, but still
303 * on screen for animations.
304 */
305 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
306
307 /**
308 * Z-ordered (bottom-most first) list of all application tokens, for
309 * controlling the ordering of windows in different applications. This
310 * contains WindowToken objects.
311 */
312 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
313
314 /**
315 * Application tokens that are in the process of exiting, but still
316 * on screen for animations.
317 */
318 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
319
320 /**
321 * List of window tokens that have finished starting their application,
322 * and now need to have the policy remove their windows.
323 */
324 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
325
326 /**
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700327 * This was the app token that was used to retrieve the last enter
328 * animation. It will be used for the next exit animation.
329 */
330 AppWindowToken mLastEnterAnimToken;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800331
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700332 /**
333 * These were the layout params used to retrieve the last enter animation.
334 * They will be used for the next exit animation.
335 */
336 LayoutParams mLastEnterAnimParams;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800337
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700338 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 * Z-ordered (bottom-most first) list of all Window objects.
340 */
Jeff Browne33348b2010-07-15 23:54:05 -0700341 final ArrayList<WindowState> mWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342
343 /**
344 * Windows that are being resized. Used so we can tell the client about
345 * the resize after closing the transaction in which we resized the
346 * underlying surface.
347 */
348 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
349
350 /**
351 * Windows whose animations have ended and now must be removed.
352 */
353 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
354
355 /**
356 * Windows whose surface should be destroyed.
357 */
358 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
359
360 /**
361 * Windows that have lost input focus and are waiting for the new
362 * focus window to be displayed before they are told about this.
363 */
364 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
365
366 /**
367 * This is set when we have run out of memory, and will either be an empty
368 * list or contain windows that need to be force removed.
369 */
370 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700375 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 Surface mBlurSurface;
377 boolean mBlurShown;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700378 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800379 StrictModeFlash mStrictModeFlash;
Romain Guy06882f82009-06-10 13:36:04 -0700380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800383 final float[] mTmpFloats = new float[9];
384
385 boolean mSafeMode;
386 boolean mDisplayEnabled = false;
387 boolean mSystemBooted = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700388 int mInitialDisplayWidth = 0;
389 int mInitialDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 int mRotation = 0;
391 int mRequestedRotation = 0;
392 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborn321ae682009-03-27 16:16:03 -0700393 int mLastRotationFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 ArrayList<IRotationWatcher> mRotationWatchers
395 = new ArrayList<IRotationWatcher>();
Romain Guy06882f82009-06-10 13:36:04 -0700396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 boolean mLayoutNeeded = true;
398 boolean mAnimationPending = false;
399 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800400 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 boolean mWindowsFreezingScreen = false;
402 long mFreezeGcPending = 0;
403 int mAppsFreezingScreen = 0;
404
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800405 int mLayoutSeq = 0;
406
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800407 // State while inside of layoutAndPlaceSurfacesLocked().
408 boolean mFocusMayChange;
409
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800410 Configuration mCurConfiguration = new Configuration();
411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 // This is held as long as we have the screen frozen, to give us time to
413 // perform a rotation animation when turning off shows the lock screen which
414 // changes the orientation.
415 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 // State management of app transitions. When we are preparing for a
418 // transition, mNextAppTransition will be the kind of transition to
419 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
420 // mOpeningApps and mClosingApps are the lists of tokens that will be
421 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700422 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700423 String mNextAppTransitionPackage;
424 int mNextAppTransitionEnter;
425 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700427 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 boolean mAppTransitionTimeout = false;
429 boolean mStartingIconInTransition = false;
430 boolean mSkipAppTransitionAnimation = false;
431 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
432 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700433 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
434 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700435
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 H mH = new H();
439
440 WindowState mCurrentFocus = null;
441 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 // This just indicates the window the input method is on top of, not
444 // necessarily the window its input is going to.
445 WindowState mInputMethodTarget = null;
446 WindowState mUpcomingInputMethodTarget = null;
447 boolean mInputMethodTargetWaitingAnim;
448 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 WindowState mInputMethodWindow = null;
451 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
452
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700453 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800454
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700455 // If non-null, this is the currently visible window that is associated
456 // with the wallpaper.
457 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700458 // If non-null, we are in the middle of animating from one wallpaper target
459 // to another, and this is the lower one in Z-order.
460 WindowState mLowerWallpaperTarget = null;
461 // If non-null, we are in the middle of animating from one wallpaper target
462 // to another, and this is the higher one in Z-order.
463 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -0800464 // Window currently running an animation that has requested it be detached
465 // from the wallpaper. This means we need to ensure the wallpaper is
466 // visible behind it in case it animates in a way that would allow it to be
467 // seen.
468 WindowState mWindowDetachedWallpaper = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700469 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700470 float mLastWallpaperX = -1;
471 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800472 float mLastWallpaperXStep = -1;
473 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700474 // This is set when we are waiting for a wallpaper to tell us it is done
475 // changing its scroll position.
476 WindowState mWaitingOnWallpaper;
477 // The last time we had a timeout when waiting for a wallpaper.
478 long mLastWallpaperTimeoutTime;
479 // We give a wallpaper up to 150ms to finish scrolling.
480 static final long WALLPAPER_TIMEOUT = 150;
481 // Time we wait after a timeout before trying to wait again.
482 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 AppWindowToken mFocusedApp = null;
485
486 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 float mWindowAnimationScale = 1.0f;
489 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700490
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700491 final InputManager mInputManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492
493 // Who is holding the screen on.
494 Session mHoldingScreenOn;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700495 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700496
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700497 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 /**
Christopher Tatea53146c2010-09-07 11:57:52 -0700500 * Drag/drop state
501 */
502 class DragState {
503 IBinder mToken;
504 Surface mSurface;
505 boolean mLocalOnly;
Chris Tate7b362e42010-11-04 16:02:52 -0700506 IBinder mLocalWin;
Christopher Tatea53146c2010-09-07 11:57:52 -0700507 ClipData mData;
508 ClipDescription mDataDescription;
Chris Tated4533f142010-10-19 15:15:08 -0700509 boolean mDragResult;
Chris Tateb478f462010-10-15 16:02:26 -0700510 float mCurrentX, mCurrentY;
Christopher Tatea53146c2010-09-07 11:57:52 -0700511 float mThumbOffsetX, mThumbOffsetY;
512 InputChannel mServerChannel, mClientChannel;
513 WindowState mTargetWindow;
514 ArrayList<WindowState> mNotifiedWindows;
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700515 boolean mDragInProgress;
Christopher Tatea53146c2010-09-07 11:57:52 -0700516
517 private final Rect tmpRect = new Rect();
518
Chris Tate7b362e42010-11-04 16:02:52 -0700519 DragState(IBinder token, Surface surface, boolean localOnly, IBinder localWin) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700520 mToken = token;
521 mSurface = surface;
522 mLocalOnly = localOnly;
Chris Tate7b362e42010-11-04 16:02:52 -0700523 mLocalWin = localWin;
Christopher Tatea53146c2010-09-07 11:57:52 -0700524 mNotifiedWindows = new ArrayList<WindowState>();
525 }
526
527 void reset() {
528 if (mSurface != null) {
529 mSurface.destroy();
530 }
531 mSurface = null;
532 mLocalOnly = false;
Chris Tate7b362e42010-11-04 16:02:52 -0700533 mLocalWin = null;
Christopher Tatea53146c2010-09-07 11:57:52 -0700534 mToken = null;
535 mData = null;
536 mThumbOffsetX = mThumbOffsetY = 0;
537 mNotifiedWindows = null;
538 }
539
540 void register() {
541 if (DEBUG_DRAG) Slog.d(TAG, "registering drag input channel");
542 if (mClientChannel != null) {
543 Slog.e(TAG, "Duplicate register of drag input channel");
544 } else {
545 InputChannel[] channels = InputChannel.openInputChannelPair("drag");
546 mServerChannel = channels[0];
547 mClientChannel = channels[1];
548 mInputManager.registerInputChannel(mServerChannel);
549 InputQueue.registerInputChannel(mClientChannel, mDragInputHandler,
550 mH.getLooper().getQueue());
551 }
552 }
553
554 void unregister() {
555 if (DEBUG_DRAG) Slog.d(TAG, "unregistering drag input channel");
556 if (mClientChannel == null) {
557 Slog.e(TAG, "Unregister of nonexistent drag input channel");
558 } else {
559 mInputManager.unregisterInputChannel(mServerChannel);
560 InputQueue.unregisterInputChannel(mClientChannel);
561 mClientChannel.dispose();
Chris Tateef70a072010-10-22 19:10:34 -0700562 mServerChannel.dispose();
Christopher Tatea53146c2010-09-07 11:57:52 -0700563 mClientChannel = null;
564 mServerChannel = null;
565 }
566 }
567
Chris Tatea32dcf72010-10-14 12:13:50 -0700568 int getDragLayerLw() {
569 return mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG)
570 * TYPE_LAYER_MULTIPLIER
571 + TYPE_LAYER_OFFSET;
572 }
573
Christopher Tatea53146c2010-09-07 11:57:52 -0700574 /* call out to each visible window/session informing it about the drag
575 */
Chris Tateb8203e92010-10-12 14:23:21 -0700576 void broadcastDragStartedLw(final float touchX, final float touchY) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700577 // Cache a base-class instance of the clip metadata so that parceling
578 // works correctly in calling out to the apps.
Dianne Hackbornf834dfa2010-10-26 12:43:57 -0700579 mDataDescription = mData.getDescription();
Christopher Tatea53146c2010-09-07 11:57:52 -0700580 mNotifiedWindows.clear();
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700581 mDragInProgress = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700582
583 if (DEBUG_DRAG) {
Chris Tateb478f462010-10-15 16:02:26 -0700584 Slog.d(TAG, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
Christopher Tatea53146c2010-09-07 11:57:52 -0700585 }
586
Christopher Tate2c095f32010-10-04 14:13:40 -0700587 final int N = mWindows.size();
588 for (int i = 0; i < N; i++) {
Chris Tateb478f462010-10-15 16:02:26 -0700589 sendDragStartedLw(mWindows.get(i), touchX, touchY, mDataDescription);
Christopher Tatea53146c2010-09-07 11:57:52 -0700590 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700591 }
592
593 /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
594 * designated window is potentially a drop recipient. There are race situations
595 * around DRAG_ENDED broadcast, so we make sure that once we've declared that
596 * the drag has ended, we never send out another DRAG_STARTED for this drag action.
Christopher Tate2c095f32010-10-04 14:13:40 -0700597 *
598 * This method clones the 'event' parameter if it's being delivered to the same
599 * process, so it's safe for the caller to call recycle() on the event afterwards.
Christopher Tatea53146c2010-09-07 11:57:52 -0700600 */
Chris Tateb478f462010-10-15 16:02:26 -0700601 private void sendDragStartedLw(WindowState newWin, float touchX, float touchY,
602 ClipDescription desc) {
Chris Tate7b362e42010-11-04 16:02:52 -0700603 // Don't actually send the event if the drag is supposed to be pinned
604 // to the originating window but 'newWin' is not that window.
605 if (mLocalOnly) {
606 final IBinder winBinder = newWin.mClient.asBinder();
607 if (winBinder != mLocalWin) {
608 if (DEBUG_DRAG) {
609 Slog.d(TAG, "Not dispatching local DRAG_STARTED to " + newWin);
610 }
611 return;
612 }
613 }
614
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700615 if (mDragInProgress && newWin.isPotentialDragTarget()) {
Chris Tateb478f462010-10-15 16:02:26 -0700616 DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED,
617 touchX - newWin.mFrame.left, touchY - newWin.mFrame.top,
Chris Tated4533f142010-10-19 15:15:08 -0700618 desc, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700619 try {
620 newWin.mClient.dispatchDragEvent(event);
621 // track each window that we've notified that the drag is starting
622 mNotifiedWindows.add(newWin);
623 } catch (RemoteException e) {
624 Slog.w(TAG, "Unable to drag-start window " + newWin);
Chris Tateb478f462010-10-15 16:02:26 -0700625 } finally {
626 // if the callee was local, the dispatch has already recycled the event
627 if (Process.myPid() != newWin.mSession.mPid) {
628 event.recycle();
629 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700630 }
631 }
632 }
633
634 /* helper - construct and send a DRAG_STARTED event only if the window has not
635 * previously been notified, i.e. it became visible after the drag operation
636 * was begun. This is a rare case.
637 */
638 private void sendDragStartedIfNeededLw(WindowState newWin) {
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700639 if (mDragInProgress) {
640 // If we have sent the drag-started, we needn't do so again
641 for (WindowState ws : mNotifiedWindows) {
642 if (ws == newWin) {
643 return;
644 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700645 }
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700646 if (DEBUG_DRAG) {
Chris Tateef70a072010-10-22 19:10:34 -0700647 Slog.d(TAG, "need to send DRAG_STARTED to new window " + newWin);
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700648 }
Chris Tateb478f462010-10-15 16:02:26 -0700649 sendDragStartedLw(newWin, mCurrentX, mCurrentY, mDataDescription);
Christopher Tatea53146c2010-09-07 11:57:52 -0700650 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700651 }
652
Chris Tated4533f142010-10-19 15:15:08 -0700653 void broadcastDragEndedLw() {
Christopher Tatea53146c2010-09-07 11:57:52 -0700654 if (DEBUG_DRAG) {
655 Slog.d(TAG, "broadcasting DRAG_ENDED");
656 }
Chris Tated4533f142010-10-19 15:15:08 -0700657 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
658 0, 0, null, null, mDragResult);
659 for (WindowState ws: mNotifiedWindows) {
660 try {
661 ws.mClient.dispatchDragEvent(evt);
662 } catch (RemoteException e) {
663 Slog.w(TAG, "Unable to drag-end window " + ws);
Christopher Tatea53146c2010-09-07 11:57:52 -0700664 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700665 }
Chris Tated4533f142010-10-19 15:15:08 -0700666 mNotifiedWindows.clear();
667 mDragInProgress = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700668 evt.recycle();
669 }
670
Chris Tated4533f142010-10-19 15:15:08 -0700671 void endDragLw() {
672 mDragState.broadcastDragEndedLw();
673
674 // stop intercepting input
675 mDragState.unregister();
676 mInputMonitor.updateInputWindowsLw();
677
678 // free our resources and drop all the object references
679 mDragState.reset();
680 mDragState = null;
681 }
682
Christopher Tatea53146c2010-09-07 11:57:52 -0700683 void notifyMoveLw(float x, float y) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700684 final int myPid = Process.myPid();
685
686 // Move the surface to the given touch
687 mSurface.openTransaction();
688 mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
689 mSurface.closeTransaction();
690
691 // Tell the affected window
Christopher Tatea53146c2010-09-07 11:57:52 -0700692 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
Chris Tate7b362e42010-11-04 16:02:52 -0700693 if (mLocalOnly) {
694 final IBinder touchedBinder = touchedWin.mClient.asBinder();
695 if (touchedBinder != mLocalWin) {
696 // This drag is pinned only to the originating window, but the drag
697 // point is outside that window. Pretend it's over empty space.
698 touchedWin = null;
699 }
700 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700701 try {
702 // have we dragged over a new window?
703 if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
704 if (DEBUG_DRAG) {
705 Slog.d(TAG, "sending DRAG_EXITED to " + mTargetWindow);
706 }
707 // force DRAG_EXITED_EVENT if appropriate
708 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
Chris Tateb478f462010-10-15 16:02:26 -0700709 x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top,
Chris Tated4533f142010-10-19 15:15:08 -0700710 null, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700711 mTargetWindow.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700712 if (myPid != mTargetWindow.mSession.mPid) {
713 evt.recycle();
714 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700715 }
716 if (touchedWin != null) {
Chris Tate9d1ab882010-11-02 15:55:39 -0700717 if (false && DEBUG_DRAG) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700718 Slog.d(TAG, "sending DRAG_LOCATION to " + touchedWin);
719 }
720 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
Chris Tateb478f462010-10-15 16:02:26 -0700721 x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
Chris Tated4533f142010-10-19 15:15:08 -0700722 null, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700723 touchedWin.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700724 if (myPid != touchedWin.mSession.mPid) {
725 evt.recycle();
726 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700727 }
728 } catch (RemoteException e) {
729 Slog.w(TAG, "can't send drag notification to windows");
730 }
731 mTargetWindow = touchedWin;
732 }
733
Chris Tated4533f142010-10-19 15:15:08 -0700734 // Tell the drop target about the data. Returns 'true' if we can immediately
735 // dispatch the global drag-ended message, 'false' if we need to wait for a
736 // result from the recipient.
737 boolean notifyDropLw(float x, float y) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700738 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
Chris Tated4533f142010-10-19 15:15:08 -0700739 if (touchedWin == null) {
740 // "drop" outside a valid window -- no recipient to apply a
741 // timeout to, and we can send the drag-ended message immediately.
742 mDragResult = false;
743 return true;
744 }
745
746 if (DEBUG_DRAG) {
747 Slog.d(TAG, "sending DROP to " + touchedWin);
748 }
749 final int myPid = Process.myPid();
750 final IBinder token = touchedWin.mClient.asBinder();
751 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP,
752 x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
753 null, mData, false);
754 try {
755 touchedWin.mClient.dispatchDragEvent(evt);
756
757 // 5 second timeout for this window to respond to the drop
758 mH.removeMessages(H.DRAG_END_TIMEOUT, token);
759 Message msg = mH.obtainMessage(H.DRAG_END_TIMEOUT, token);
760 mH.sendMessageDelayed(msg, 5000);
761 } catch (RemoteException e) {
762 Slog.w(TAG, "can't send drop notification to win " + touchedWin);
763 return true;
764 } finally {
Christopher Tate2c095f32010-10-04 14:13:40 -0700765 if (myPid != touchedWin.mSession.mPid) {
766 evt.recycle();
767 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700768 }
Chris Tated4533f142010-10-19 15:15:08 -0700769 mToken = token;
770 return false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700771 }
772
773 // Find the visible, touch-deliverable window under the given point
774 private WindowState getTouchedWinAtPointLw(float xf, float yf) {
775 WindowState touchedWin = null;
776 final int x = (int) xf;
777 final int y = (int) yf;
778 final ArrayList<WindowState> windows = mWindows;
779 final int N = windows.size();
780 for (int i = N - 1; i >= 0; i--) {
781 WindowState child = windows.get(i);
782 final int flags = child.mAttrs.flags;
783 if (!child.isVisibleLw()) {
784 // not visible == don't tell about drags
785 continue;
786 }
787 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
788 // not touchable == don't tell about drags
789 continue;
790 }
791 // account for the window's decor etc
792 tmpRect.set(child.mFrame);
793 if (child.mTouchableInsets == ViewTreeObserver
794 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
795 // The point is inside of the window if it is
796 // inside the frame, AND the content part of that
797 // frame that was given by the application.
798 tmpRect.left += child.mGivenContentInsets.left;
799 tmpRect.top += child.mGivenContentInsets.top;
800 tmpRect.right -= child.mGivenContentInsets.right;
801 tmpRect.bottom -= child.mGivenContentInsets.bottom;
802 } else if (child.mTouchableInsets == ViewTreeObserver
803 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
804 // The point is inside of the window if it is
805 // inside the frame, AND the visible part of that
806 // frame that was given by the application.
807 tmpRect.left += child.mGivenVisibleInsets.left;
808 tmpRect.top += child.mGivenVisibleInsets.top;
809 tmpRect.right -= child.mGivenVisibleInsets.right;
810 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
811 }
812 final int touchFlags = flags &
813 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
814 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
815 if (tmpRect.contains(x, y) || touchFlags == 0) {
816 // Found it
817 touchedWin = child;
818 break;
819 }
820 }
821
822 return touchedWin;
823 }
824 }
825
826 DragState mDragState = null;
827 private final InputHandler mDragInputHandler = new BaseInputHandler() {
828 @Override
Jeff Brown3915bb82010-11-05 15:02:16 -0700829 public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
830 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700831 try {
Jeff Brown3915bb82010-11-05 15:02:16 -0700832 if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
833 && mDragState != null) {
834 boolean endDrag = false;
835 final float newX = event.getRawX();
836 final float newY = event.getRawY();
837
Christopher Tatea53146c2010-09-07 11:57:52 -0700838 switch (event.getAction()) {
839 case MotionEvent.ACTION_DOWN: {
840 if (DEBUG_DRAG) {
841 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
842 }
843 } break;
844
845 case MotionEvent.ACTION_MOVE: {
846 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700847 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700848 mDragState.notifyMoveLw(newX, newY);
849 }
850 } break;
851
852 case MotionEvent.ACTION_UP: {
853 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
854 + newX + "," + newY);
855 synchronized (mWindowMap) {
Chris Tated4533f142010-10-19 15:15:08 -0700856 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700857 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700858 } break;
859
860 case MotionEvent.ACTION_CANCEL: {
861 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
862 endDrag = true;
863 } break;
864 }
865
866 if (endDrag) {
867 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
868 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700869 synchronized (mWindowMap) {
Chris Tated4533f142010-10-19 15:15:08 -0700870 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700871 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700872 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700873
874 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700875 }
876 } catch (Exception e) {
877 Slog.e(TAG, "Exception caught by drag handleMotion", e);
878 } finally {
Jeff Brown3915bb82010-11-05 15:02:16 -0700879 finishedCallback.finished(handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700880 }
881 }
882 };
883
884 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885 * Whether the UI is currently running in touch mode (not showing
886 * navigational focus because the user is directly pressing the screen).
887 */
888 boolean mInTouchMode = false;
889
890 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700891 private ArrayList<WindowChangeListener> mWindowChangeListeners =
892 new ArrayList<WindowChangeListener>();
893 private boolean mWindowsChanged = false;
894
895 public interface WindowChangeListener {
896 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700897 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700898 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800899
Dianne Hackbornc485a602009-03-24 22:39:49 -0700900 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700901 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700902
903 // The frame use to limit the size of the app running in compatibility mode.
904 Rect mCompatibleScreenFrame = new Rect();
905 // The surface used to fill the outer rim of the app running in compatibility mode.
906 Surface mBackgroundFillerSurface = null;
907 boolean mBackgroundFillerShown = false;
908
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909 public static WindowManagerService main(Context context,
910 PowerManagerService pm, boolean haveInputMethods) {
911 WMThread thr = new WMThread(context, pm, haveInputMethods);
912 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 synchronized (thr) {
915 while (thr.mService == null) {
916 try {
917 thr.wait();
918 } catch (InterruptedException e) {
919 }
920 }
921 }
Romain Guy06882f82009-06-10 13:36:04 -0700922
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800923 return thr.mService;
924 }
Romain Guy06882f82009-06-10 13:36:04 -0700925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 static class WMThread extends Thread {
927 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 private final Context mContext;
930 private final PowerManagerService mPM;
931 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 public WMThread(Context context, PowerManagerService pm,
934 boolean haveInputMethods) {
935 super("WindowManager");
936 mContext = context;
937 mPM = pm;
938 mHaveInputMethods = haveInputMethods;
939 }
Romain Guy06882f82009-06-10 13:36:04 -0700940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800941 public void run() {
942 Looper.prepare();
943 WindowManagerService s = new WindowManagerService(mContext, mPM,
944 mHaveInputMethods);
945 android.os.Process.setThreadPriority(
946 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700947 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700948
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 synchronized (this) {
950 mService = s;
951 notifyAll();
952 }
Romain Guy06882f82009-06-10 13:36:04 -0700953
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700954 // For debug builds, log event loop stalls to dropbox for analysis.
955 if (StrictMode.conditionallyEnableDebugLogging()) {
956 Slog.i(TAG, "Enabled StrictMode logging for WMThread's Looper");
957 }
958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 Looper.loop();
960 }
961 }
962
963 static class PolicyThread extends Thread {
964 private final WindowManagerPolicy mPolicy;
965 private final WindowManagerService mService;
966 private final Context mContext;
967 private final PowerManagerService mPM;
968 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700969
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970 public PolicyThread(WindowManagerPolicy policy,
971 WindowManagerService service, Context context,
972 PowerManagerService pm) {
973 super("WindowManagerPolicy");
974 mPolicy = policy;
975 mService = service;
976 mContext = context;
977 mPM = pm;
978 }
Romain Guy06882f82009-06-10 13:36:04 -0700979
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800980 public void run() {
981 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800982 WindowManagerPolicyThread.set(this, Looper.myLooper());
983
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800985 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800986 android.os.Process.setThreadPriority(
987 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -0700988 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800989 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -0700990
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 synchronized (this) {
992 mRunning = true;
993 notifyAll();
994 }
Romain Guy06882f82009-06-10 13:36:04 -0700995
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700996 // For debug builds, log event loop stalls to dropbox for analysis.
997 if (StrictMode.conditionallyEnableDebugLogging()) {
998 Slog.i(TAG, "Enabled StrictMode for PolicyThread's Looper");
999 }
1000
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 Looper.loop();
1002 }
1003 }
1004
1005 private WindowManagerService(Context context, PowerManagerService pm,
1006 boolean haveInputMethods) {
1007 mContext = context;
1008 mHaveInputMethods = haveInputMethods;
1009 mLimitedAlphaCompositing = context.getResources().getBoolean(
1010 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -07001011
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001012 mPowerManager = pm;
1013 mPowerManager.setPolicy(mPolicy);
1014 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1015 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
1016 "SCREEN_FROZEN");
1017 mScreenFrozenLock.setReferenceCounted(false);
1018
1019 mActivityManager = ActivityManagerNative.getDefault();
1020 mBatteryStats = BatteryStatsService.getService();
1021
1022 // Get persisted window scale setting
1023 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
1024 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
1025 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
1026 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -07001027
Jim Miller284b62e2010-06-08 14:27:42 -07001028 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
1029 IntentFilter filter = new IntentFilter();
1030 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1031 mContext.registerReceiver(mBroadcastReceiver, filter);
1032
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001033 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
1034 "KEEP_SCREEN_ON_FLAG");
1035 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001036
Jeff Browne33348b2010-07-15 23:54:05 -07001037 mInputManager = new InputManager(context, this);
Romain Guy06882f82009-06-10 13:36:04 -07001038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001039 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
1040 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -07001041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001042 synchronized (thr) {
1043 while (!thr.mRunning) {
1044 try {
1045 thr.wait();
1046 } catch (InterruptedException e) {
1047 }
1048 }
1049 }
Romain Guy06882f82009-06-10 13:36:04 -07001050
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001051 mInputManager.start();
Romain Guy06882f82009-06-10 13:36:04 -07001052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053 // Add ourself to the Watchdog monitors.
1054 Watchdog.getInstance().addMonitor(this);
1055 }
1056
1057 @Override
1058 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1059 throws RemoteException {
1060 try {
1061 return super.onTransact(code, data, reply, flags);
1062 } catch (RuntimeException e) {
1063 // The window manager only throws security exceptions, so let's
1064 // log all others.
1065 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001066 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001067 }
1068 throw e;
1069 }
1070 }
1071
Jeff Browne33348b2010-07-15 23:54:05 -07001072 private void placeWindowAfter(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001073 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001074 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001075 TAG, "Adding window " + window + " at "
1076 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
1077 mWindows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001078 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079 }
1080
Jeff Browne33348b2010-07-15 23:54:05 -07001081 private void placeWindowBefore(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001082 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001083 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001084 TAG, "Adding window " + window + " at "
1085 + i + " of " + mWindows.size() + " (before " + pos + ")");
1086 mWindows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001087 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001088 }
1089
1090 //This method finds out the index of a window that has the same app token as
1091 //win. used for z ordering the windows in mWindows
1092 private int findIdxBasedOnAppTokens(WindowState win) {
1093 //use a local variable to cache mWindows
Jeff Browne33348b2010-07-15 23:54:05 -07001094 ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001095 int jmax = localmWindows.size();
1096 if(jmax == 0) {
1097 return -1;
1098 }
1099 for(int j = (jmax-1); j >= 0; j--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001100 WindowState wentry = localmWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001101 if(wentry.mAppToken == win.mAppToken) {
1102 return j;
1103 }
1104 }
1105 return -1;
1106 }
Romain Guy06882f82009-06-10 13:36:04 -07001107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001108 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
1109 final IWindow client = win.mClient;
1110 final WindowToken token = win.mToken;
Jeff Browne33348b2010-07-15 23:54:05 -07001111 final ArrayList<WindowState> localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -07001112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 final int N = localmWindows.size();
1114 final WindowState attached = win.mAttachedWindow;
1115 int i;
1116 if (attached == null) {
1117 int tokenWindowsPos = token.windows.size();
1118 if (token.appWindowToken != null) {
1119 int index = tokenWindowsPos-1;
1120 if (index >= 0) {
1121 // If this application has existing windows, we
1122 // simply place the new window on top of them... but
1123 // keep the starting window on top.
1124 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1125 // Base windows go behind everything else.
1126 placeWindowBefore(token.windows.get(0), win);
1127 tokenWindowsPos = 0;
1128 } else {
1129 AppWindowToken atoken = win.mAppToken;
1130 if (atoken != null &&
1131 token.windows.get(index) == atoken.startingWindow) {
1132 placeWindowBefore(token.windows.get(index), win);
1133 tokenWindowsPos--;
1134 } else {
1135 int newIdx = findIdxBasedOnAppTokens(win);
1136 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -07001137 //there is a window above this one associated with the same
1138 //apptoken note that the window could be a floating window
1139 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001140 //windows associated with this token.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001141 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001142 TAG, "Adding window " + win + " at "
1143 + (newIdx+1) + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001144 localmWindows.add(newIdx+1, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001145 mWindowsChanged = true;
Romain Guy06882f82009-06-10 13:36:04 -07001146 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001147 }
1148 }
1149 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001150 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001151 TAG, "Figuring out where to add app window "
1152 + client.asBinder() + " (token=" + token + ")");
1153 // Figure out where the window should go, based on the
1154 // order of applications.
1155 final int NA = mAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -07001156 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001157 for (i=NA-1; i>=0; i--) {
1158 AppWindowToken t = mAppTokens.get(i);
1159 if (t == token) {
1160 i--;
1161 break;
1162 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001163
Dianne Hackborna8f60182009-09-01 19:01:50 -07001164 // We haven't reached the token yet; if this token
1165 // is not going to the bottom and has windows, we can
1166 // use it as an anchor for when we do reach the token.
1167 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001168 pos = t.windows.get(0);
1169 }
1170 }
1171 // We now know the index into the apps. If we found
1172 // an app window above, that gives us the position; else
1173 // we need to look some more.
1174 if (pos != null) {
1175 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -07001176 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001177 if (atoken != null) {
1178 final int NC = atoken.windows.size();
1179 if (NC > 0) {
1180 WindowState bottom = atoken.windows.get(0);
1181 if (bottom.mSubLayer < 0) {
1182 pos = bottom;
1183 }
1184 }
1185 }
1186 placeWindowBefore(pos, win);
1187 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -07001188 // Continue looking down until we find the first
1189 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001190 while (i >= 0) {
1191 AppWindowToken t = mAppTokens.get(i);
1192 final int NW = t.windows.size();
1193 if (NW > 0) {
1194 pos = t.windows.get(NW-1);
1195 break;
1196 }
1197 i--;
1198 }
1199 if (pos != null) {
1200 // Move in front of any windows attached to this
1201 // one.
Jeff Browne33348b2010-07-15 23:54:05 -07001202 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 if (atoken != null) {
1204 final int NC = atoken.windows.size();
1205 if (NC > 0) {
1206 WindowState top = atoken.windows.get(NC-1);
1207 if (top.mSubLayer >= 0) {
1208 pos = top;
1209 }
1210 }
1211 }
1212 placeWindowAfter(pos, win);
1213 } else {
1214 // Just search for the start of this layer.
1215 final int myLayer = win.mBaseLayer;
1216 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07001217 WindowState w = localmWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001218 if (w.mBaseLayer > myLayer) {
1219 break;
1220 }
1221 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001222 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001223 TAG, "Adding window " + win + " at "
1224 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001225 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001226 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001227 }
1228 }
1229 }
1230 } else {
1231 // Figure out where window should go, based on layer.
1232 final int myLayer = win.mBaseLayer;
1233 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001234 if (localmWindows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001235 i++;
1236 break;
1237 }
1238 }
1239 if (i < 0) i = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001240 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001241 TAG, "Adding window " + win + " at "
1242 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001244 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 }
1246 if (addToToken) {
1247 token.windows.add(tokenWindowsPos, win);
1248 }
1249
1250 } else {
1251 // Figure out this window's ordering relative to the window
1252 // it is attached to.
1253 final int NA = token.windows.size();
1254 final int sublayer = win.mSubLayer;
1255 int largestSublayer = Integer.MIN_VALUE;
1256 WindowState windowWithLargestSublayer = null;
1257 for (i=0; i<NA; i++) {
1258 WindowState w = token.windows.get(i);
1259 final int wSublayer = w.mSubLayer;
1260 if (wSublayer >= largestSublayer) {
1261 largestSublayer = wSublayer;
1262 windowWithLargestSublayer = w;
1263 }
1264 if (sublayer < 0) {
1265 // For negative sublayers, we go below all windows
1266 // in the same sublayer.
1267 if (wSublayer >= sublayer) {
1268 if (addToToken) {
1269 token.windows.add(i, win);
1270 }
1271 placeWindowBefore(
1272 wSublayer >= 0 ? attached : w, win);
1273 break;
1274 }
1275 } else {
1276 // For positive sublayers, we go above all windows
1277 // in the same sublayer.
1278 if (wSublayer > sublayer) {
1279 if (addToToken) {
1280 token.windows.add(i, win);
1281 }
1282 placeWindowBefore(w, win);
1283 break;
1284 }
1285 }
1286 }
1287 if (i >= NA) {
1288 if (addToToken) {
1289 token.windows.add(win);
1290 }
1291 if (sublayer < 0) {
1292 placeWindowBefore(attached, win);
1293 } else {
1294 placeWindowAfter(largestSublayer >= 0
1295 ? windowWithLargestSublayer
1296 : attached,
1297 win);
1298 }
1299 }
1300 }
Romain Guy06882f82009-06-10 13:36:04 -07001301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 if (win.mAppToken != null && addToToken) {
1303 win.mAppToken.allAppWindows.add(win);
1304 }
1305 }
Romain Guy06882f82009-06-10 13:36:04 -07001306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 static boolean canBeImeTarget(WindowState w) {
1308 final int fl = w.mAttrs.flags
1309 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
1310 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
1311 return w.isVisibleOrAdding();
1312 }
1313 return false;
1314 }
Romain Guy06882f82009-06-10 13:36:04 -07001315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Jeff Browne33348b2010-07-15 23:54:05 -07001317 final ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 final int N = localmWindows.size();
1319 WindowState w = null;
1320 int i = N;
1321 while (i > 0) {
1322 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001323 w = localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001324
Joe Onorato8a9b2202010-02-26 18:56:32 -08001325 //Slog.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 // + Integer.toHexString(w.mAttrs.flags));
1327 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001328 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001330 // Yet more tricksyness! If this window is a "starting"
1331 // window, we do actually want to be on top of it, but
1332 // it is not -really- where input will go. So if the caller
1333 // is not actually looking to move the IME, look down below
1334 // for a real window to target...
1335 if (!willMove
1336 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1337 && i > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001338 WindowState wb = localmWindows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001339 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1340 i--;
1341 w = wb;
1342 }
1343 }
1344 break;
1345 }
1346 }
Romain Guy06882f82009-06-10 13:36:04 -07001347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 mUpcomingInputMethodTarget = w;
Romain Guy06882f82009-06-10 13:36:04 -07001349
Joe Onorato8a9b2202010-02-26 18:56:32 -08001350 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001351 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 if (willMove && w != null) {
1354 final WindowState curTarget = mInputMethodTarget;
1355 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001357 // Now some fun for dealing with window animations that
1358 // modify the Z order. We need to look at all windows below
1359 // the current target that are in this app, finding the highest
1360 // visible one in layering.
1361 AppWindowToken token = curTarget.mAppToken;
1362 WindowState highestTarget = null;
1363 int highestPos = 0;
1364 if (token.animating || token.animation != null) {
1365 int pos = 0;
1366 pos = localmWindows.indexOf(curTarget);
1367 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001368 WindowState win = localmWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369 if (win.mAppToken != token) {
1370 break;
1371 }
1372 if (!win.mRemoved) {
1373 if (highestTarget == null || win.mAnimLayer >
1374 highestTarget.mAnimLayer) {
1375 highestTarget = win;
1376 highestPos = pos;
1377 }
1378 }
1379 pos--;
1380 }
1381 }
Romain Guy06882f82009-06-10 13:36:04 -07001382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001383 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001384 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001385 + mNextAppTransition + " " + highestTarget
1386 + " animating=" + highestTarget.isAnimating()
1387 + " layer=" + highestTarget.mAnimLayer
1388 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001389
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001390 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391 // If we are currently setting up for an animation,
1392 // hold everything until we can find out what will happen.
1393 mInputMethodTargetWaitingAnim = true;
1394 mInputMethodTarget = highestTarget;
1395 return highestPos + 1;
1396 } else if (highestTarget.isAnimating() &&
1397 highestTarget.mAnimLayer > w.mAnimLayer) {
1398 // If the window we are currently targeting is involved
1399 // with an animation, and it is on top of the next target
1400 // we will be over, then hold off on moving until
1401 // that is done.
1402 mInputMethodTarget = highestTarget;
1403 return highestPos + 1;
1404 }
1405 }
1406 }
1407 }
Romain Guy06882f82009-06-10 13:36:04 -07001408
Joe Onorato8a9b2202010-02-26 18:56:32 -08001409 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001410 if (w != null) {
1411 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001412 if (DEBUG_INPUT_METHOD) {
1413 RuntimeException e = null;
1414 if (!HIDE_STACK_CRAWLS) {
1415 e = new RuntimeException();
1416 e.fillInStackTrace();
1417 }
1418 Slog.w(TAG, "Moving IM target from "
1419 + mInputMethodTarget + " to " + w, e);
1420 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001421 mInputMethodTarget = w;
1422 if (w.mAppToken != null) {
1423 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1424 } else {
1425 setInputMethodAnimLayerAdjustment(0);
1426 }
1427 }
1428 return i+1;
1429 }
1430 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001431 if (DEBUG_INPUT_METHOD) {
1432 RuntimeException e = null;
1433 if (!HIDE_STACK_CRAWLS) {
1434 e = new RuntimeException();
1435 e.fillInStackTrace();
1436 }
1437 Slog.w(TAG, "Moving IM target from "
1438 + mInputMethodTarget + " to null", e);
1439 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001440 mInputMethodTarget = null;
1441 setInputMethodAnimLayerAdjustment(0);
1442 }
1443 return -1;
1444 }
Romain Guy06882f82009-06-10 13:36:04 -07001445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 void addInputMethodWindowToListLocked(WindowState win) {
1447 int pos = findDesiredInputMethodWindowIndexLocked(true);
1448 if (pos >= 0) {
1449 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001450 if (DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001451 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452 mWindows.add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001453 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001454 moveInputMethodDialogsLocked(pos+1);
1455 return;
1456 }
1457 win.mTargetAppToken = null;
1458 addWindowToListInOrderLocked(win, true);
1459 moveInputMethodDialogsLocked(pos);
1460 }
Romain Guy06882f82009-06-10 13:36:04 -07001461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001462 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001463 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001464 mInputMethodAnimLayerAdjustment = adj;
1465 WindowState imw = mInputMethodWindow;
1466 if (imw != null) {
1467 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001468 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 + " anim layer: " + imw.mAnimLayer);
1470 int wi = imw.mChildWindows.size();
1471 while (wi > 0) {
1472 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001473 WindowState cw = imw.mChildWindows.get(wi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001474 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001475 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001476 + " anim layer: " + cw.mAnimLayer);
1477 }
1478 }
1479 int di = mInputMethodDialogs.size();
1480 while (di > 0) {
1481 di --;
1482 imw = mInputMethodDialogs.get(di);
1483 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001484 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001485 + " anim layer: " + imw.mAnimLayer);
1486 }
1487 }
Romain Guy06882f82009-06-10 13:36:04 -07001488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001489 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1490 int wpos = mWindows.indexOf(win);
1491 if (wpos >= 0) {
1492 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001493 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001495 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496 int NC = win.mChildWindows.size();
1497 while (NC > 0) {
1498 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001499 WindowState cw = win.mChildWindows.get(NC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500 int cpos = mWindows.indexOf(cw);
1501 if (cpos >= 0) {
1502 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001503 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001504 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 mWindows.remove(cpos);
1506 }
1507 }
1508 }
1509 return interestingPos;
1510 }
Romain Guy06882f82009-06-10 13:36:04 -07001511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001512 private void reAddWindowToListInOrderLocked(WindowState win) {
1513 addWindowToListInOrderLocked(win, false);
1514 // This is a hack to get all of the child windows added as well
1515 // at the right position. Child windows should be rare and
1516 // this case should be rare, so it shouldn't be that big a deal.
1517 int wpos = mWindows.indexOf(win);
1518 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001519 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001520 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001521 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001522 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 reAddWindowLocked(wpos, win);
1524 }
1525 }
Romain Guy06882f82009-06-10 13:36:04 -07001526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001527 void logWindowList(String prefix) {
1528 int N = mWindows.size();
1529 while (N > 0) {
1530 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001531 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001532 }
1533 }
Romain Guy06882f82009-06-10 13:36:04 -07001534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001535 void moveInputMethodDialogsLocked(int pos) {
1536 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001538 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001539 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 for (int i=0; i<N; i++) {
1541 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1542 }
1543 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001544 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545 logWindowList(" ");
1546 }
Romain Guy06882f82009-06-10 13:36:04 -07001547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 if (pos >= 0) {
1549 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1550 if (pos < mWindows.size()) {
Jeff Browne33348b2010-07-15 23:54:05 -07001551 WindowState wp = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 if (wp == mInputMethodWindow) {
1553 pos++;
1554 }
1555 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001556 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 for (int i=0; i<N; i++) {
1558 WindowState win = dialogs.get(i);
1559 win.mTargetAppToken = targetAppToken;
1560 pos = reAddWindowLocked(pos, win);
1561 }
1562 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001563 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001564 logWindowList(" ");
1565 }
1566 return;
1567 }
1568 for (int i=0; i<N; i++) {
1569 WindowState win = dialogs.get(i);
1570 win.mTargetAppToken = null;
1571 reAddWindowToListInOrderLocked(win);
1572 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001573 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001574 logWindowList(" ");
1575 }
1576 }
1577 }
Romain Guy06882f82009-06-10 13:36:04 -07001578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001579 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1580 final WindowState imWin = mInputMethodWindow;
1581 final int DN = mInputMethodDialogs.size();
1582 if (imWin == null && DN == 0) {
1583 return false;
1584 }
Romain Guy06882f82009-06-10 13:36:04 -07001585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001586 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1587 if (imPos >= 0) {
1588 // In this case, the input method windows are to be placed
1589 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001591 // First check to see if the input method windows are already
1592 // located here, and contiguous.
1593 final int N = mWindows.size();
1594 WindowState firstImWin = imPos < N
Jeff Browne33348b2010-07-15 23:54:05 -07001595 ? mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001597 // Figure out the actual input method window that should be
1598 // at the bottom of their stack.
1599 WindowState baseImWin = imWin != null
1600 ? imWin : mInputMethodDialogs.get(0);
1601 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001602 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 if (cw.mSubLayer < 0) baseImWin = cw;
1604 }
Romain Guy06882f82009-06-10 13:36:04 -07001605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 if (firstImWin == baseImWin) {
1607 // The windows haven't moved... but are they still contiguous?
1608 // First find the top IM window.
1609 int pos = imPos+1;
1610 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001611 if (!(mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001612 break;
1613 }
1614 pos++;
1615 }
1616 pos++;
1617 // Now there should be no more input method windows above.
1618 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001619 if ((mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001620 break;
1621 }
1622 pos++;
1623 }
1624 if (pos >= N) {
1625 // All is good!
1626 return false;
1627 }
1628 }
Romain Guy06882f82009-06-10 13:36:04 -07001629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001630 if (imWin != null) {
1631 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001632 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001633 logWindowList(" ");
1634 }
1635 imPos = tmpRemoveWindowLocked(imPos, imWin);
1636 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001637 Slog.v(TAG, "List after moving with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001638 logWindowList(" ");
1639 }
1640 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1641 reAddWindowLocked(imPos, imWin);
1642 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001643 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001644 logWindowList(" ");
1645 }
1646 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1647 } else {
1648 moveInputMethodDialogsLocked(imPos);
1649 }
Romain Guy06882f82009-06-10 13:36:04 -07001650
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001651 } else {
1652 // In this case, the input method windows go in a fixed layer,
1653 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001655 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001656 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001657 tmpRemoveWindowLocked(0, imWin);
1658 imWin.mTargetAppToken = null;
1659 reAddWindowToListInOrderLocked(imWin);
1660 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001661 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001662 logWindowList(" ");
1663 }
1664 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1665 } else {
1666 moveInputMethodDialogsLocked(-1);;
1667 }
Romain Guy06882f82009-06-10 13:36:04 -07001668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001669 }
Romain Guy06882f82009-06-10 13:36:04 -07001670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001671 if (needAssignLayers) {
1672 assignLayersLocked();
1673 }
Romain Guy06882f82009-06-10 13:36:04 -07001674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 return true;
1676 }
Romain Guy06882f82009-06-10 13:36:04 -07001677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 void adjustInputMethodDialogsLocked() {
1679 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1680 }
Romain Guy06882f82009-06-10 13:36:04 -07001681
Dianne Hackborn25994b42009-09-04 14:21:19 -07001682 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001683 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001684 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1685 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1686 ? wallpaperTarget.mAppToken.animation : null)
1687 + " upper=" + mUpperWallpaperTarget
1688 + " lower=" + mLowerWallpaperTarget);
1689 return (wallpaperTarget != null
1690 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1691 && wallpaperTarget.mAppToken.animation != null)))
1692 || mUpperWallpaperTarget != null
1693 || mLowerWallpaperTarget != null;
1694 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001695
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001696 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1697 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001698
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001699 int adjustWallpaperWindowsLocked() {
1700 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001701
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001702 final int dw = mDisplay.getWidth();
1703 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001704
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001705 // First find top-most window that has asked to be on top of the
1706 // wallpaper; all wallpapers go behind it.
Jeff Browne33348b2010-07-15 23:54:05 -07001707 final ArrayList<WindowState> localmWindows = mWindows;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001708 int N = localmWindows.size();
1709 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001710 WindowState foundW = null;
1711 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001712 WindowState topCurW = null;
1713 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001714 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001715 int i = N;
1716 while (i > 0) {
1717 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001718 w = localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001719 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1720 if (topCurW == null) {
1721 topCurW = w;
1722 topCurI = i;
1723 }
1724 continue;
1725 }
1726 topCurW = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001727 if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001728 // If this window's app token is hidden and not animating,
1729 // it is of no interest to us.
1730 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001731 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001732 "Skipping not hidden or animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001733 continue;
1734 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001735 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001736 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001737 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1738 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001739 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001740 && (mWallpaperTarget == w
1741 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001742 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001743 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001744 foundW = w;
1745 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001746 if (w == mWallpaperTarget && ((w.mAppToken != null
1747 && w.mAppToken.animation != null)
1748 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001749 // The current wallpaper target is animating, so we'll
1750 // look behind it for another possible target and figure
1751 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001752 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001753 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001754 continue;
1755 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001756 break;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001757 } else if (w == mWindowDetachedWallpaper) {
1758 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001759 }
1760 }
1761
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001762 if (foundW == null && windowDetachedI >= 0) {
1763 if (DEBUG_WALLPAPER) Slog.v(TAG,
1764 "Found animating detached wallpaper activity: #" + i + "=" + w);
1765 foundW = w;
1766 foundI = windowDetachedI;
1767 }
1768
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001769 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001770 // If we are currently waiting for an app transition, and either
1771 // the current target or the next target are involved with it,
1772 // then hold off on doing anything with the wallpaper.
1773 // Note that we are checking here for just whether the target
1774 // is part of an app token... which is potentially overly aggressive
1775 // (the app token may not be involved in the transition), but good
1776 // enough (we'll just wait until whatever transition is pending
1777 // executes).
1778 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001779 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001780 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001781 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001782 }
1783 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001784 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001785 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001786 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001787 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001788 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001789
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001790 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001791 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001792 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001793 + " oldTarget: " + mWallpaperTarget);
1794 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001795
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001796 mLowerWallpaperTarget = null;
1797 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001798
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001799 WindowState oldW = mWallpaperTarget;
1800 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001801
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001802 // Now what is happening... if the current and new targets are
1803 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001804 if (foundW != null && oldW != null) {
1805 boolean oldAnim = oldW.mAnimation != null
1806 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1807 boolean foundAnim = foundW.mAnimation != null
1808 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001809 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001810 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001811 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001812 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001813 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001814 int oldI = localmWindows.indexOf(oldW);
1815 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001816 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001817 }
1818 if (oldI >= 0) {
1819 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001820 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001821 + "=" + oldW + "; new#" + foundI
1822 + "=" + foundW);
1823 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001824
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001825 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001826 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001827 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001828 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001829 }
1830 mWallpaperTarget = oldW;
1831 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001832
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001833 // Now set the upper and lower wallpaper targets
1834 // correctly, and make sure that we are positioning
1835 // the wallpaper below the lower.
1836 if (foundI > oldI) {
1837 // The new target is on top of the old one.
1838 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001839 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001840 }
1841 mUpperWallpaperTarget = foundW;
1842 mLowerWallpaperTarget = oldW;
1843 foundW = oldW;
1844 foundI = oldI;
1845 } else {
1846 // The new target is below the old one.
1847 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001848 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001849 }
1850 mUpperWallpaperTarget = oldW;
1851 mLowerWallpaperTarget = foundW;
1852 }
1853 }
1854 }
1855 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001856
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001857 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001858 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001859 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1860 || (mLowerWallpaperTarget.mAppToken != null
1861 && mLowerWallpaperTarget.mAppToken.animation != null);
1862 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1863 || (mUpperWallpaperTarget.mAppToken != null
1864 && mUpperWallpaperTarget.mAppToken.animation != null);
1865 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001866 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001867 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001868 }
1869 mLowerWallpaperTarget = null;
1870 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001871 }
1872 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001873
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001874 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001875 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001876 // The window is visible to the compositor... but is it visible
1877 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001878 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001879 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001880
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001881 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001882 // its layer adjustment. Only do this if we are not transfering
1883 // between two wallpaper targets.
1884 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001885 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001886 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001887
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001888 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1889 * TYPE_LAYER_MULTIPLIER
1890 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001891
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001892 // Now w is the window we are supposed to be behind... but we
1893 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001894 // AND any starting window associated with it, AND below the
1895 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001896 while (foundI > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001897 WindowState wb = localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001898 if (wb.mBaseLayer < maxLayer &&
1899 wb.mAttachedWindow != foundW &&
Pal Szasz73dc2592010-09-03 11:46:26 +02001900 wb.mAttachedWindow != foundW.mAttachedWindow &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001901 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001902 wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001903 // This window is not related to the previous one in any
1904 // interesting way, so stop here.
1905 break;
1906 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001907 foundW = wb;
1908 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001909 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001910 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001911 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001912 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001913
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001914 if (foundW == null && topCurW != null) {
1915 // There is no wallpaper target, so it goes at the bottom.
1916 // We will assume it is the same place as last time, if known.
1917 foundW = topCurW;
1918 foundI = topCurI+1;
1919 } else {
1920 // Okay i is the position immediately above the wallpaper. Look at
1921 // what is below it for later.
Jeff Browne33348b2010-07-15 23:54:05 -07001922 foundW = foundI > 0 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001923 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001924
Dianne Hackborn284ac932009-08-28 10:34:25 -07001925 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001926 if (mWallpaperTarget.mWallpaperX >= 0) {
1927 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001928 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001929 }
1930 if (mWallpaperTarget.mWallpaperY >= 0) {
1931 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001932 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001933 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001934 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001935
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001936 // Start stepping backwards from here, ensuring that our wallpaper windows
1937 // are correctly placed.
1938 int curTokenIndex = mWallpaperTokens.size();
1939 while (curTokenIndex > 0) {
1940 curTokenIndex--;
1941 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001942 if (token.hidden == visible) {
1943 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1944 token.hidden = !visible;
1945 // Need to do a layout to ensure the wallpaper now has the
1946 // correct size.
1947 mLayoutNeeded = true;
1948 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001949
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001950 int curWallpaperIndex = token.windows.size();
1951 while (curWallpaperIndex > 0) {
1952 curWallpaperIndex--;
1953 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001954
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001955 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001956 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001957 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001958
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001959 // First, make sure the client has the current visibility
1960 // state.
1961 if (wallpaper.mWallpaperVisible != visible) {
1962 wallpaper.mWallpaperVisible = visible;
1963 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001964 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001965 "Setting visibility of wallpaper " + wallpaper
1966 + ": " + visible);
1967 wallpaper.mClient.dispatchAppVisibility(visible);
1968 } catch (RemoteException e) {
1969 }
1970 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001971
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001972 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001973 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001974 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001975
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001976 // First, if this window is at the current index, then all
1977 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001978 if (wallpaper == foundW) {
1979 foundI--;
1980 foundW = foundI > 0
Jeff Browne33348b2010-07-15 23:54:05 -07001981 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001982 continue;
1983 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001984
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001985 // The window didn't match... the current wallpaper window,
1986 // wherever it is, is in the wrong place, so make sure it is
1987 // not in the list.
1988 int oldIndex = localmWindows.indexOf(wallpaper);
1989 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001990 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001991 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001992 localmWindows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001993 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001994 if (oldIndex < foundI) {
1995 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001996 }
1997 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001998
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001999 // Now stick it in.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002000 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07002001 "Moving wallpaper " + wallpaper
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002002 + " from " + oldIndex + " to " + foundI);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002003
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002004 localmWindows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002005 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002006 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002007 }
2008 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002009
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002010 return changed;
2011 }
2012
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002013 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002014 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002015 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002016 mWallpaperAnimLayerAdjustment = adj;
2017 int curTokenIndex = mWallpaperTokens.size();
2018 while (curTokenIndex > 0) {
2019 curTokenIndex--;
2020 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2021 int curWallpaperIndex = token.windows.size();
2022 while (curWallpaperIndex > 0) {
2023 curWallpaperIndex--;
2024 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2025 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002026 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002027 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002028 }
2029 }
2030 }
2031
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002032 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
2033 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002034 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002035 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002036 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002037 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002038 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
2039 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
2040 changed = wallpaperWin.mXOffset != offset;
2041 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002042 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002043 + wallpaperWin + " x: " + offset);
2044 wallpaperWin.mXOffset = offset;
2045 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002046 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002047 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002048 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002049 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002050 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002051
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002052 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002053 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002054 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
2055 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
2056 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002057 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002058 + wallpaperWin + " y: " + offset);
2059 changed = true;
2060 wallpaperWin.mYOffset = offset;
2061 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002062 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002063 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002064 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002065 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002066 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002067
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002068 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002069 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002070 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002071 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
2072 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002073 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002074 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002075 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002076 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002077 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
2078 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002079 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002080 if (mWaitingOnWallpaper != null) {
2081 long start = SystemClock.uptimeMillis();
2082 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
2083 < start) {
2084 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002085 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07002086 "Waiting for offset complete...");
2087 mWindowMap.wait(WALLPAPER_TIMEOUT);
2088 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002089 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002090 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07002091 if ((start+WALLPAPER_TIMEOUT)
2092 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002093 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07002094 + wallpaperWin);
2095 mLastWallpaperTimeoutTime = start;
2096 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002097 }
Dianne Hackborn75804932009-10-20 20:15:20 -07002098 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002099 }
2100 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002101 } catch (RemoteException e) {
2102 }
2103 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002104
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002105 return changed;
2106 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002107
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002108 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002109 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002110 if (mWaitingOnWallpaper != null &&
2111 mWaitingOnWallpaper.mClient.asBinder() == window) {
2112 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07002113 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002114 }
2115 }
2116 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002117
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002118 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002119 final int dw = mDisplay.getWidth();
2120 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002121
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002122 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002123
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002124 WindowState target = mWallpaperTarget;
2125 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002126 if (target.mWallpaperX >= 0) {
2127 mLastWallpaperX = target.mWallpaperX;
2128 } else if (changingTarget.mWallpaperX >= 0) {
2129 mLastWallpaperX = changingTarget.mWallpaperX;
2130 }
2131 if (target.mWallpaperY >= 0) {
2132 mLastWallpaperY = target.mWallpaperY;
2133 } else if (changingTarget.mWallpaperY >= 0) {
2134 mLastWallpaperY = changingTarget.mWallpaperY;
2135 }
2136 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002137
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002138 int curTokenIndex = mWallpaperTokens.size();
2139 while (curTokenIndex > 0) {
2140 curTokenIndex--;
2141 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2142 int curWallpaperIndex = token.windows.size();
2143 while (curWallpaperIndex > 0) {
2144 curWallpaperIndex--;
2145 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2146 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
2147 wallpaper.computeShownFrameLocked();
2148 changed = true;
2149 // We only want to be synchronous with one wallpaper.
2150 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002151 }
2152 }
2153 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002154
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002155 return changed;
2156 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002157
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002158 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002159 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002160 final int dw = mDisplay.getWidth();
2161 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002162
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002163 int curTokenIndex = mWallpaperTokens.size();
2164 while (curTokenIndex > 0) {
2165 curTokenIndex--;
2166 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002167 if (token.hidden == visible) {
2168 token.hidden = !visible;
2169 // Need to do a layout to ensure the wallpaper now has the
2170 // correct size.
2171 mLayoutNeeded = true;
2172 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002173
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002174 int curWallpaperIndex = token.windows.size();
2175 while (curWallpaperIndex > 0) {
2176 curWallpaperIndex--;
2177 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2178 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002179 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002180 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002181
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002182 if (wallpaper.mWallpaperVisible != visible) {
2183 wallpaper.mWallpaperVisible = visible;
2184 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002185 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07002186 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002187 + ": " + visible);
2188 wallpaper.mClient.dispatchAppVisibility(visible);
2189 } catch (RemoteException e) {
2190 }
2191 }
2192 }
2193 }
2194 }
Dianne Hackborn90d2db32010-02-11 22:19:06 -08002195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002196 public int addWindow(Session session, IWindow client,
2197 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002198 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002199 int res = mPolicy.checkAddPermission(attrs);
2200 if (res != WindowManagerImpl.ADD_OKAY) {
2201 return res;
2202 }
Romain Guy06882f82009-06-10 13:36:04 -07002203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002204 boolean reportNewConfig = false;
2205 WindowState attachedWindow = null;
2206 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002207 long origId;
Romain Guy06882f82009-06-10 13:36:04 -07002208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002209 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002210 if (mDisplay == null) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002211 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002212 }
Romain Guy06882f82009-06-10 13:36:04 -07002213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002214 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002215 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002216 return WindowManagerImpl.ADD_DUPLICATE_ADD;
2217 }
2218
2219 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002220 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002221 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002222 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002223 + attrs.token + ". Aborting.");
2224 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2225 }
2226 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2227 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002228 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002229 + attrs.token + ". Aborting.");
2230 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2231 }
2232 }
2233
2234 boolean addToken = false;
2235 WindowToken token = mTokenMap.get(attrs.token);
2236 if (token == null) {
2237 if (attrs.type >= FIRST_APPLICATION_WINDOW
2238 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002239 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002240 + attrs.token + ". Aborting.");
2241 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2242 }
2243 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002244 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002245 + attrs.token + ". Aborting.");
2246 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2247 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002248 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002249 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002250 + attrs.token + ". Aborting.");
2251 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002253 token = new WindowToken(attrs.token, -1, false);
2254 addToken = true;
2255 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
2256 && attrs.type <= LAST_APPLICATION_WINDOW) {
2257 AppWindowToken atoken = token.appWindowToken;
2258 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002259 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002260 + token + ". Aborting.");
2261 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
2262 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002263 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002264 + token + ". Aborting.");
2265 return WindowManagerImpl.ADD_APP_EXITING;
2266 }
2267 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
2268 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002269 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002270 TAG, "**** NO NEED TO START: " + attrs.getTitle());
2271 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
2272 }
2273 } else if (attrs.type == TYPE_INPUT_METHOD) {
2274 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002275 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002276 + attrs.token + ". Aborting.");
2277 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2278 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002279 } else if (attrs.type == TYPE_WALLPAPER) {
2280 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002281 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002282 + attrs.token + ". Aborting.");
2283 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2284 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 }
2286
2287 win = new WindowState(session, client, token,
2288 attachedWindow, attrs, viewVisibility);
2289 if (win.mDeathRecipient == null) {
2290 // Client has apparently died, so there is no reason to
2291 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002292 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002293 + " that is dead, aborting.");
2294 return WindowManagerImpl.ADD_APP_EXITING;
2295 }
2296
2297 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07002298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002299 res = mPolicy.prepareAddWindowLw(win, attrs);
2300 if (res != WindowManagerImpl.ADD_OKAY) {
2301 return res;
2302 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002303
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002304 if (outInputChannel != null) {
2305 String name = win.makeInputChannelName();
2306 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2307 win.mInputChannel = inputChannels[0];
2308 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2309
2310 mInputManager.registerInputChannel(win.mInputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002311 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312
2313 // From now on, no exceptions or errors allowed!
2314
2315 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002316
Dianne Hackborn5132b372010-07-29 12:51:35 -07002317 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002319 if (addToken) {
2320 mTokenMap.put(attrs.token, token);
2321 mTokenList.add(token);
2322 }
2323 win.attach();
2324 mWindowMap.put(client.asBinder(), win);
2325
2326 if (attrs.type == TYPE_APPLICATION_STARTING &&
2327 token.appWindowToken != null) {
2328 token.appWindowToken.startingWindow = win;
2329 }
2330
2331 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002333 if (attrs.type == TYPE_INPUT_METHOD) {
2334 mInputMethodWindow = win;
2335 addInputMethodWindowToListLocked(win);
2336 imMayMove = false;
2337 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2338 mInputMethodDialogs.add(win);
2339 addWindowToListInOrderLocked(win, true);
2340 adjustInputMethodDialogsLocked();
2341 imMayMove = false;
2342 } else {
2343 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002344 if (attrs.type == TYPE_WALLPAPER) {
2345 mLastWallpaperTimeoutTime = 0;
2346 adjustWallpaperWindowsLocked();
2347 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002348 adjustWallpaperWindowsLocked();
2349 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002350 }
Romain Guy06882f82009-06-10 13:36:04 -07002351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002354 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002356 if (mInTouchMode) {
2357 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2358 }
2359 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2360 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2361 }
Romain Guy06882f82009-06-10 13:36:04 -07002362
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002363 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002364 if (win.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07002365 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS);
2366 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 imMayMove = false;
2368 }
2369 }
Romain Guy06882f82009-06-10 13:36:04 -07002370
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002371 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002372 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 }
Romain Guy06882f82009-06-10 13:36:04 -07002374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002375 assignLayersLocked();
2376 // Don't do layout here, the window must call
2377 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002379 //dump();
2380
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002381 if (focusChanged) {
Jeff Brown349703e2010-06-22 01:27:15 -07002382 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002383 }
Jeff Brown349703e2010-06-22 01:27:15 -07002384
Joe Onorato8a9b2202010-02-26 18:56:32 -08002385 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002386 TAG, "New client " + client.asBinder()
2387 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002388
2389 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked()) {
2390 reportNewConfig = true;
2391 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002392 }
2393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002394 if (reportNewConfig) {
2395 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002396 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002398 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400 return res;
2401 }
Romain Guy06882f82009-06-10 13:36:04 -07002402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002403 public void removeWindow(Session session, IWindow client) {
2404 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002405 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002406 if (win == null) {
2407 return;
2408 }
2409 removeWindowLocked(session, win);
2410 }
2411 }
Romain Guy06882f82009-06-10 13:36:04 -07002412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002413 public void removeWindowLocked(Session session, WindowState win) {
2414
Joe Onorato8a9b2202010-02-26 18:56:32 -08002415 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002416 TAG, "Remove " + win + " client="
2417 + Integer.toHexString(System.identityHashCode(
2418 win.mClient.asBinder()))
2419 + ", surface=" + win.mSurface);
2420
2421 final long origId = Binder.clearCallingIdentity();
Jeff Brownc5ed5912010-07-14 18:48:53 -07002422
2423 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002424
Joe Onorato8a9b2202010-02-26 18:56:32 -08002425 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002426 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2427 + " mExiting=" + win.mExiting
2428 + " isAnimating=" + win.isAnimating()
2429 + " app-animation="
2430 + (win.mAppToken != null ? win.mAppToken.animation : null)
2431 + " inPendingTransaction="
2432 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2433 + " mDisplayFrozen=" + mDisplayFrozen);
2434 // Visibility of the removed window. Will be used later to update orientation later on.
2435 boolean wasVisible = false;
2436 // First, see if we need to run an animation. If we do, we have
2437 // to hold off on removing the window until the animation is done.
2438 // If the display is frozen, just remove immediately, since the
2439 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002440 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002441 // If we are not currently running the exit animation, we
2442 // need to see about starting one.
2443 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002444
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002445 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2446 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2447 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2448 }
2449 // Try starting an animation.
2450 if (applyAnimationLocked(win, transit, false)) {
2451 win.mExiting = true;
2452 }
2453 }
2454 if (win.mExiting || win.isAnimating()) {
2455 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002456 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 win.mExiting = true;
2458 win.mRemoveOnExit = true;
2459 mLayoutNeeded = true;
2460 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
2461 performLayoutAndPlaceSurfacesLocked();
2462 if (win.mAppToken != null) {
2463 win.mAppToken.updateReportedVisibilityLocked();
2464 }
2465 //dump();
2466 Binder.restoreCallingIdentity(origId);
2467 return;
2468 }
2469 }
2470
2471 removeWindowInnerLocked(session, win);
2472 // Removing a visible window will effect the computed orientation
2473 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002474 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002475 != mForcedAppOrientation
2476 && updateOrientationFromAppTokensLocked()) {
2477 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002478 }
2479 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2480 Binder.restoreCallingIdentity(origId);
2481 }
Romain Guy06882f82009-06-10 13:36:04 -07002482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002483 private void removeWindowInnerLocked(Session session, WindowState win) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002484 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002486 if (mInputMethodTarget == win) {
2487 moveInputMethodWindowsIfNeededLocked(false);
2488 }
Romain Guy06882f82009-06-10 13:36:04 -07002489
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002490 if (false) {
2491 RuntimeException e = new RuntimeException("here");
2492 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002493 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002494 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002496 mPolicy.removeWindowLw(win);
2497 win.removeLocked();
2498
2499 mWindowMap.remove(win.mClient.asBinder());
2500 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002501 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002502 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002503
2504 if (mInputMethodWindow == win) {
2505 mInputMethodWindow = null;
2506 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2507 mInputMethodDialogs.remove(win);
2508 }
Romain Guy06882f82009-06-10 13:36:04 -07002509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002510 final WindowToken token = win.mToken;
2511 final AppWindowToken atoken = win.mAppToken;
2512 token.windows.remove(win);
2513 if (atoken != null) {
2514 atoken.allAppWindows.remove(win);
2515 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002516 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002517 TAG, "**** Removing window " + win + ": count="
2518 + token.windows.size());
2519 if (token.windows.size() == 0) {
2520 if (!token.explicit) {
2521 mTokenMap.remove(token.token);
2522 mTokenList.remove(token);
2523 } else if (atoken != null) {
2524 atoken.firstWindowDrawn = false;
2525 }
2526 }
2527
2528 if (atoken != null) {
2529 if (atoken.startingWindow == win) {
2530 atoken.startingWindow = null;
2531 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2532 // If this is the last window and we had requested a starting
2533 // transition window, well there is no point now.
2534 atoken.startingData = null;
2535 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2536 // If this is the last window except for a starting transition
2537 // window, we need to get rid of the starting transition.
2538 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002539 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002540 + ": no more real windows");
2541 }
2542 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2543 mH.sendMessage(m);
2544 }
2545 }
Romain Guy06882f82009-06-10 13:36:04 -07002546
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002547 if (win.mAttrs.type == TYPE_WALLPAPER) {
2548 mLastWallpaperTimeoutTime = 0;
2549 adjustWallpaperWindowsLocked();
2550 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002551 adjustWallpaperWindowsLocked();
2552 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002554 if (!mInLayout) {
2555 assignLayersLocked();
2556 mLayoutNeeded = true;
2557 performLayoutAndPlaceSurfacesLocked();
2558 if (win.mAppToken != null) {
2559 win.mAppToken.updateReportedVisibilityLocked();
2560 }
2561 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07002562
2563 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002564 }
2565
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002566 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2567 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2568 + ": " + msg + " / " + w.mAttrs.getTitle();
2569 if (where != null) {
2570 Slog.i(TAG, str, where);
2571 } else {
2572 Slog.i(TAG, str);
2573 }
2574 }
2575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002576 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
2577 long origId = Binder.clearCallingIdentity();
2578 try {
2579 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002580 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002581 if ((w != null) && (w.mSurface != null)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002582 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002583 Surface.openTransaction();
2584 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002585 if (SHOW_TRANSACTIONS) logSurface(w,
2586 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002587 w.mSurface.setTransparentRegionHint(region);
2588 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002589 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002590 Surface.closeTransaction();
2591 }
2592 }
2593 }
2594 } finally {
2595 Binder.restoreCallingIdentity(origId);
2596 }
2597 }
2598
2599 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002600 int touchableInsets, Rect contentInsets,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002601 Rect visibleInsets) {
2602 long origId = Binder.clearCallingIdentity();
2603 try {
2604 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002605 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002606 if (w != null) {
2607 w.mGivenInsetsPending = false;
2608 w.mGivenContentInsets.set(contentInsets);
2609 w.mGivenVisibleInsets.set(visibleInsets);
2610 w.mTouchableInsets = touchableInsets;
2611 mLayoutNeeded = true;
2612 performLayoutAndPlaceSurfacesLocked();
2613 }
2614 }
2615 } finally {
2616 Binder.restoreCallingIdentity(origId);
2617 }
2618 }
Romain Guy06882f82009-06-10 13:36:04 -07002619
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002620 public void getWindowDisplayFrame(Session session, IWindow client,
2621 Rect outDisplayFrame) {
2622 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002623 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002624 if (win == null) {
2625 outDisplayFrame.setEmpty();
2626 return;
2627 }
2628 outDisplayFrame.set(win.mDisplayFrame);
2629 }
2630 }
2631
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002632 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2633 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002634 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2635 window.mWallpaperX = x;
2636 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002637 window.mWallpaperXStep = xStep;
2638 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002639 if (updateWallpaperOffsetLocked(window, true)) {
2640 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002641 }
2642 }
2643 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002644
Dianne Hackborn75804932009-10-20 20:15:20 -07002645 void wallpaperCommandComplete(IBinder window, Bundle result) {
2646 synchronized (mWindowMap) {
2647 if (mWaitingOnWallpaper != null &&
2648 mWaitingOnWallpaper.mClient.asBinder() == window) {
2649 mWaitingOnWallpaper = null;
2650 mWindowMap.notifyAll();
2651 }
2652 }
2653 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002654
Dianne Hackborn75804932009-10-20 20:15:20 -07002655 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2656 String action, int x, int y, int z, Bundle extras, boolean sync) {
2657 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2658 || window == mUpperWallpaperTarget) {
2659 boolean doWait = sync;
2660 int curTokenIndex = mWallpaperTokens.size();
2661 while (curTokenIndex > 0) {
2662 curTokenIndex--;
2663 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2664 int curWallpaperIndex = token.windows.size();
2665 while (curWallpaperIndex > 0) {
2666 curWallpaperIndex--;
2667 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2668 try {
2669 wallpaper.mClient.dispatchWallpaperCommand(action,
2670 x, y, z, extras, sync);
2671 // We only want to be synchronous with one wallpaper.
2672 sync = false;
2673 } catch (RemoteException e) {
2674 }
2675 }
2676 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002677
Dianne Hackborn75804932009-10-20 20:15:20 -07002678 if (doWait) {
2679 // XXX Need to wait for result.
2680 }
2681 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002682
Dianne Hackborn75804932009-10-20 20:15:20 -07002683 return null;
2684 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002686 public int relayoutWindow(Session session, IWindow client,
2687 WindowManager.LayoutParams attrs, int requestedWidth,
2688 int requestedHeight, int viewVisibility, boolean insetsPending,
2689 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002690 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002691 boolean displayed = false;
2692 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002693 boolean configChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002694 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002695
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002696 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002697 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002698 if (win == null) {
2699 return 0;
2700 }
2701 win.mRequestedWidth = requestedWidth;
2702 win.mRequestedHeight = requestedHeight;
2703
2704 if (attrs != null) {
2705 mPolicy.adjustWindowParamsLw(attrs);
2706 }
Romain Guy06882f82009-06-10 13:36:04 -07002707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002708 int attrChanges = 0;
2709 int flagChanges = 0;
2710 if (attrs != null) {
2711 flagChanges = win.mAttrs.flags ^= attrs.flags;
2712 attrChanges = win.mAttrs.copyFrom(attrs);
2713 }
2714
Joe Onorato8a9b2202010-02-26 18:56:32 -08002715 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002716
2717 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2718 win.mAlpha = attrs.alpha;
2719 }
2720
2721 final boolean scaledWindow =
2722 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2723
2724 if (scaledWindow) {
2725 // requested{Width|Height} Surface's physical size
2726 // attrs.{width|height} Size on screen
2727 win.mHScale = (attrs.width != requestedWidth) ?
2728 (attrs.width / (float)requestedWidth) : 1.0f;
2729 win.mVScale = (attrs.height != requestedHeight) ?
2730 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002731 } else {
2732 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002733 }
2734
2735 boolean imMayMove = (flagChanges&(
2736 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2737 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002739 boolean focusMayChange = win.mViewVisibility != viewVisibility
2740 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2741 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002742
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002743 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2744 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002746 win.mRelayoutCalled = true;
2747 final int oldVisibility = win.mViewVisibility;
2748 win.mViewVisibility = viewVisibility;
2749 if (viewVisibility == View.VISIBLE &&
2750 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2751 displayed = !win.isVisibleLw();
2752 if (win.mExiting) {
2753 win.mExiting = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07002754 if (win.mAnimation != null) {
2755 win.mAnimation.cancel();
2756 win.mAnimation = null;
2757 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002758 }
2759 if (win.mDestroying) {
2760 win.mDestroying = false;
2761 mDestroySurface.remove(win);
2762 }
2763 if (oldVisibility == View.GONE) {
2764 win.mEnterAnimationPending = true;
2765 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002766 if (displayed) {
2767 if (win.mSurface != null && !win.mDrawPending
2768 && !win.mCommitDrawPending && !mDisplayFrozen
2769 && mPolicy.isScreenOn()) {
2770 applyEnterAnimationLocked(win);
2771 }
2772 if ((win.mAttrs.flags
2773 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2774 if (DEBUG_VISIBILITY) Slog.v(TAG,
2775 "Relayout window turning screen on: " + win);
2776 win.mTurnOnScreen = true;
2777 }
2778 int diff = 0;
2779 if (win.mConfiguration != mCurConfiguration
2780 && (win.mConfiguration == null
2781 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2782 win.mConfiguration = mCurConfiguration;
2783 if (DEBUG_CONFIGURATION) {
2784 Slog.i(TAG, "Window " + win + " visible with new config: "
2785 + win.mConfiguration + " / 0x"
2786 + Integer.toHexString(diff));
2787 }
2788 outConfig.setTo(mCurConfiguration);
2789 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002790 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002791 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2792 // To change the format, we need to re-build the surface.
2793 win.destroySurfaceLocked();
2794 displayed = true;
2795 }
2796 try {
2797 Surface surface = win.createSurfaceLocked();
2798 if (surface != null) {
2799 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002800 win.mReportDestroySurface = false;
2801 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002802 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002803 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002804 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002805 // For some reason there isn't a surface. Clear the
2806 // caller's object so they see the same state.
2807 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002808 }
2809 } catch (Exception e) {
Jeff Browne33348b2010-07-15 23:54:05 -07002810 mInputMonitor.updateInputWindowsLw();
2811
Joe Onorato8a9b2202010-02-26 18:56:32 -08002812 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002813 + client + " (" + win.mAttrs.getTitle() + ")",
2814 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002815 Binder.restoreCallingIdentity(origId);
2816 return 0;
2817 }
2818 if (displayed) {
2819 focusMayChange = true;
2820 }
2821 if (win.mAttrs.type == TYPE_INPUT_METHOD
2822 && mInputMethodWindow == null) {
2823 mInputMethodWindow = win;
2824 imMayMove = true;
2825 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002826 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2827 && win.mAppToken != null
2828 && win.mAppToken.startingWindow != null) {
2829 // Special handling of starting window over the base
2830 // window of the app: propagate lock screen flags to it,
2831 // to provide the correct semantics while starting.
2832 final int mask =
2833 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002834 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2835 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002836 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2837 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2838 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002839 } else {
2840 win.mEnterAnimationPending = false;
2841 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002842 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002843 + ": mExiting=" + win.mExiting
2844 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002845 // If we are not currently running the exit animation, we
2846 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002847 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002848 // Try starting an animation; if there isn't one, we
2849 // can destroy the surface right away.
2850 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2851 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2852 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2853 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002854 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002855 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002856 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002857 win.mExiting = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002858 } else if (win.isAnimating()) {
2859 // Currently in a hide animation... turn this into
2860 // an exit.
2861 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002862 } else if (win == mWallpaperTarget) {
2863 // If the wallpaper is currently behind this
2864 // window, we need to change both of them inside
2865 // of a transaction to avoid artifacts.
2866 win.mExiting = true;
2867 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002868 } else {
2869 if (mInputMethodWindow == win) {
2870 mInputMethodWindow = null;
2871 }
2872 win.destroySurfaceLocked();
2873 }
2874 }
2875 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002876
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002877 if (win.mSurface == null || (win.getAttrs().flags
2878 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2879 || win.mSurfacePendingDestroy) {
2880 // We are being called from a local process, which
2881 // means outSurface holds its current surface. Ensure the
2882 // surface object is cleared, but we don't want it actually
2883 // destroyed at this point.
2884 win.mSurfacePendingDestroy = false;
2885 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002886 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002887 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002888 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002889 "Keeping surface, will report destroy: " + win);
2890 win.mReportDestroySurface = true;
2891 outSurface.copyFrom(win.mSurface);
2892 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002893 }
2894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002895 if (focusMayChange) {
2896 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2897 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002898 imMayMove = false;
2899 }
2900 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2901 }
Romain Guy06882f82009-06-10 13:36:04 -07002902
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002903 // updateFocusedWindowLocked() already assigned layers so we only need to
2904 // reassign them at this point if the IM window state gets shuffled
2905 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002906
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002907 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002908 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2909 // Little hack here -- we -should- be able to rely on the
2910 // function to return true if the IME has moved and needs
2911 // its layer recomputed. However, if the IME was hidden
2912 // and isn't actually moved in the list, its layer may be
2913 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002914 assignLayers = true;
2915 }
2916 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002917 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002918 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002919 assignLayers = true;
2920 }
2921 }
Romain Guy06882f82009-06-10 13:36:04 -07002922
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002923 mLayoutNeeded = true;
2924 win.mGivenInsetsPending = insetsPending;
2925 if (assignLayers) {
2926 assignLayersLocked();
2927 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002928 configChanged = updateOrientationFromAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002929 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002930 if (displayed && win.mIsWallpaper) {
2931 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002932 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002933 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002934 if (win.mAppToken != null) {
2935 win.mAppToken.updateReportedVisibilityLocked();
2936 }
2937 outFrame.set(win.mFrame);
2938 outContentInsets.set(win.mContentInsets);
2939 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002940 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002941 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002942 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002943 + ", requestedHeight=" + requestedHeight
2944 + ", viewVisibility=" + viewVisibility
2945 + "\nRelayout returning frame=" + outFrame
2946 + ", surface=" + outSurface);
2947
Joe Onorato8a9b2202010-02-26 18:56:32 -08002948 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002949 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2950
2951 inTouchMode = mInTouchMode;
Jeff Browne33348b2010-07-15 23:54:05 -07002952
2953 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002954 }
2955
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002956 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002957 sendNewConfiguration();
2958 }
Romain Guy06882f82009-06-10 13:36:04 -07002959
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002960 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002962 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2963 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2964 }
2965
2966 public void finishDrawingWindow(Session session, IWindow client) {
2967 final long origId = Binder.clearCallingIdentity();
2968 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002969 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002970 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002971 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2972 adjustWallpaperWindowsLocked();
2973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002974 mLayoutNeeded = true;
2975 performLayoutAndPlaceSurfacesLocked();
2976 }
2977 }
2978 Binder.restoreCallingIdentity(origId);
2979 }
2980
2981 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002982 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002983 + (lp != null ? lp.packageName : null)
2984 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
2985 if (lp != null && lp.windowAnimations != 0) {
2986 // If this is a system resource, don't try to load it from the
2987 // application resources. It is nice to avoid loading application
2988 // resources if we can.
2989 String packageName = lp.packageName != null ? lp.packageName : "android";
2990 int resId = lp.windowAnimations;
2991 if ((resId&0xFF000000) == 0x01000000) {
2992 packageName = "android";
2993 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002994 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002995 + packageName);
2996 return AttributeCache.instance().get(packageName, resId,
2997 com.android.internal.R.styleable.WindowAnimation);
2998 }
2999 return null;
3000 }
Romain Guy06882f82009-06-10 13:36:04 -07003001
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003002 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003003 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003004 + packageName + " resId=0x" + Integer.toHexString(resId));
3005 if (packageName != null) {
3006 if ((resId&0xFF000000) == 0x01000000) {
3007 packageName = "android";
3008 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003009 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003010 + packageName);
3011 return AttributeCache.instance().get(packageName, resId,
3012 com.android.internal.R.styleable.WindowAnimation);
3013 }
3014 return null;
3015 }
3016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003017 private void applyEnterAnimationLocked(WindowState win) {
3018 int transit = WindowManagerPolicy.TRANSIT_SHOW;
3019 if (win.mEnterAnimationPending) {
3020 win.mEnterAnimationPending = false;
3021 transit = WindowManagerPolicy.TRANSIT_ENTER;
3022 }
3023
3024 applyAnimationLocked(win, transit, true);
3025 }
3026
3027 private boolean applyAnimationLocked(WindowState win,
3028 int transit, boolean isEntrance) {
3029 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
3030 // If we are trying to apply an animation, but already running
3031 // an animation of the same type, then just leave that one alone.
3032 return true;
3033 }
Romain Guy06882f82009-06-10 13:36:04 -07003034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003035 // Only apply an animation if the display isn't frozen. If it is
3036 // frozen, there is no reason to animate and it can cause strange
3037 // artifacts when we unfreeze the display if some different animation
3038 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003039 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003040 int anim = mPolicy.selectAnimationLw(win, transit);
3041 int attr = -1;
3042 Animation a = null;
3043 if (anim != 0) {
3044 a = AnimationUtils.loadAnimation(mContext, anim);
3045 } else {
3046 switch (transit) {
3047 case WindowManagerPolicy.TRANSIT_ENTER:
3048 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
3049 break;
3050 case WindowManagerPolicy.TRANSIT_EXIT:
3051 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
3052 break;
3053 case WindowManagerPolicy.TRANSIT_SHOW:
3054 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
3055 break;
3056 case WindowManagerPolicy.TRANSIT_HIDE:
3057 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
3058 break;
3059 }
3060 if (attr >= 0) {
3061 a = loadAnimation(win.mAttrs, attr);
3062 }
3063 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003064 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003065 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
3066 + " mAnimation=" + win.mAnimation
3067 + " isEntrance=" + isEntrance);
3068 if (a != null) {
3069 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003070 RuntimeException e = null;
3071 if (!HIDE_STACK_CRAWLS) {
3072 e = new RuntimeException();
3073 e.fillInStackTrace();
3074 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003075 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003076 }
3077 win.setAnimation(a);
3078 win.mAnimationIsEntrance = isEntrance;
3079 }
3080 } else {
3081 win.clearAnimation();
3082 }
3083
3084 return win.mAnimation != null;
3085 }
3086
3087 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
3088 int anim = 0;
3089 Context context = mContext;
3090 if (animAttr >= 0) {
3091 AttributeCache.Entry ent = getCachedAnimations(lp);
3092 if (ent != null) {
3093 context = ent.context;
3094 anim = ent.array.getResourceId(animAttr, 0);
3095 }
3096 }
3097 if (anim != 0) {
3098 return AnimationUtils.loadAnimation(context, anim);
3099 }
3100 return null;
3101 }
Romain Guy06882f82009-06-10 13:36:04 -07003102
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003103 private Animation loadAnimation(String packageName, int resId) {
3104 int anim = 0;
3105 Context context = mContext;
3106 if (resId >= 0) {
3107 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
3108 if (ent != null) {
3109 context = ent.context;
3110 anim = resId;
3111 }
3112 }
3113 if (anim != 0) {
3114 return AnimationUtils.loadAnimation(context, anim);
3115 }
3116 return null;
3117 }
3118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003119 private boolean applyAnimationLocked(AppWindowToken wtoken,
3120 WindowManager.LayoutParams lp, int transit, boolean enter) {
3121 // Only apply an animation if the display isn't frozen. If it is
3122 // frozen, there is no reason to animate and it can cause strange
3123 // artifacts when we unfreeze the display if some different animation
3124 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003125 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003126 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07003127 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003128 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003129 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003130 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003131 } else if (mNextAppTransitionPackage != null) {
3132 a = loadAnimation(mNextAppTransitionPackage, enter ?
3133 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003134 } else {
3135 int animAttr = 0;
3136 switch (transit) {
3137 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3138 animAttr = enter
3139 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
3140 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
3141 break;
3142 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3143 animAttr = enter
3144 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
3145 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
3146 break;
3147 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
3148 animAttr = enter
3149 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
3150 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
3151 break;
3152 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
3153 animAttr = enter
3154 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
3155 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
3156 break;
3157 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
3158 animAttr = enter
3159 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
3160 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
3161 break;
3162 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
3163 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07003164 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003165 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
3166 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003167 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003168 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003169 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
3170 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003171 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003172 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003173 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003174 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
3175 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
3176 break;
3177 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
3178 animAttr = enter
3179 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
3180 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
3181 break;
3182 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
3183 animAttr = enter
3184 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
3185 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003186 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003187 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003188 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003189 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003190 + " anim=" + a
3191 + " animAttr=0x" + Integer.toHexString(animAttr)
3192 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003194 if (a != null) {
3195 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003196 RuntimeException e = null;
3197 if (!HIDE_STACK_CRAWLS) {
3198 e = new RuntimeException();
3199 e.fillInStackTrace();
3200 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003201 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003202 }
3203 wtoken.setAnimation(a);
3204 }
3205 } else {
3206 wtoken.clearAnimation();
3207 }
3208
3209 return wtoken.animation != null;
3210 }
3211
3212 // -------------------------------------------------------------
3213 // Application Window Tokens
3214 // -------------------------------------------------------------
3215
3216 public void validateAppTokens(List tokens) {
3217 int v = tokens.size()-1;
3218 int m = mAppTokens.size()-1;
3219 while (v >= 0 && m >= 0) {
3220 AppWindowToken wtoken = mAppTokens.get(m);
3221 if (wtoken.removed) {
3222 m--;
3223 continue;
3224 }
3225 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003226 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003227 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
3228 }
3229 v--;
3230 m--;
3231 }
3232 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003233 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003234 v--;
3235 }
3236 while (m >= 0) {
3237 AppWindowToken wtoken = mAppTokens.get(m);
3238 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003239 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003240 }
3241 m--;
3242 }
3243 }
3244
3245 boolean checkCallingPermission(String permission, String func) {
3246 // Quick check: if the calling permission is me, it's all okay.
3247 if (Binder.getCallingPid() == Process.myPid()) {
3248 return true;
3249 }
Romain Guy06882f82009-06-10 13:36:04 -07003250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003251 if (mContext.checkCallingPermission(permission)
3252 == PackageManager.PERMISSION_GRANTED) {
3253 return true;
3254 }
3255 String msg = "Permission Denial: " + func + " from pid="
3256 + Binder.getCallingPid()
3257 + ", uid=" + Binder.getCallingUid()
3258 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003259 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003260 return false;
3261 }
Romain Guy06882f82009-06-10 13:36:04 -07003262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003263 AppWindowToken findAppWindowToken(IBinder token) {
3264 WindowToken wtoken = mTokenMap.get(token);
3265 if (wtoken == null) {
3266 return null;
3267 }
3268 return wtoken.appWindowToken;
3269 }
Romain Guy06882f82009-06-10 13:36:04 -07003270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003271 public void addWindowToken(IBinder token, int type) {
3272 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3273 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003274 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003275 }
Romain Guy06882f82009-06-10 13:36:04 -07003276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003277 synchronized(mWindowMap) {
3278 WindowToken wtoken = mTokenMap.get(token);
3279 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003280 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003281 return;
3282 }
3283 wtoken = new WindowToken(token, type, true);
3284 mTokenMap.put(token, wtoken);
3285 mTokenList.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003286 if (type == TYPE_WALLPAPER) {
3287 mWallpaperTokens.add(wtoken);
3288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003289 }
3290 }
Romain Guy06882f82009-06-10 13:36:04 -07003291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003292 public void removeWindowToken(IBinder token) {
3293 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3294 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003295 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003296 }
3297
3298 final long origId = Binder.clearCallingIdentity();
3299 synchronized(mWindowMap) {
3300 WindowToken wtoken = mTokenMap.remove(token);
3301 mTokenList.remove(wtoken);
3302 if (wtoken != null) {
3303 boolean delayed = false;
3304 if (!wtoken.hidden) {
3305 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003307 final int N = wtoken.windows.size();
3308 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003310 for (int i=0; i<N; i++) {
3311 WindowState win = wtoken.windows.get(i);
3312
3313 if (win.isAnimating()) {
3314 delayed = true;
3315 }
Romain Guy06882f82009-06-10 13:36:04 -07003316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003317 if (win.isVisibleNow()) {
3318 applyAnimationLocked(win,
3319 WindowManagerPolicy.TRANSIT_EXIT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003320 changed = true;
3321 }
3322 }
3323
3324 if (changed) {
3325 mLayoutNeeded = true;
3326 performLayoutAndPlaceSurfacesLocked();
3327 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3328 }
Romain Guy06882f82009-06-10 13:36:04 -07003329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003330 if (delayed) {
3331 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003332 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3333 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003334 }
3335 }
Romain Guy06882f82009-06-10 13:36:04 -07003336
Jeff Brownc5ed5912010-07-14 18:48:53 -07003337 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003338 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003339 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003340 }
3341 }
3342 Binder.restoreCallingIdentity(origId);
3343 }
3344
3345 public void addAppToken(int addPos, IApplicationToken token,
3346 int groupId, int requestedOrientation, boolean fullscreen) {
3347 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3348 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003349 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003350 }
Jeff Brown349703e2010-06-22 01:27:15 -07003351
3352 // Get the dispatching timeout here while we are not holding any locks so that it
3353 // can be cached by the AppWindowToken. The timeout value is used later by the
3354 // input dispatcher in code that does hold locks. If we did not cache the value
3355 // here we would run the chance of introducing a deadlock between the window manager
3356 // (which holds locks while updating the input dispatcher state) and the activity manager
3357 // (which holds locks while querying the application token).
3358 long inputDispatchingTimeoutNanos;
3359 try {
3360 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3361 } catch (RemoteException ex) {
3362 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3363 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3364 }
Romain Guy06882f82009-06-10 13:36:04 -07003365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003366 synchronized(mWindowMap) {
3367 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3368 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003369 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003370 return;
3371 }
3372 wtoken = new AppWindowToken(token);
Jeff Brown349703e2010-06-22 01:27:15 -07003373 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003374 wtoken.groupId = groupId;
3375 wtoken.appFullscreen = fullscreen;
3376 wtoken.requestedOrientation = requestedOrientation;
3377 mAppTokens.add(addPos, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003378 if (localLOGV) Slog.v(TAG, "Adding new app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003379 mTokenMap.put(token.asBinder(), wtoken);
3380 mTokenList.add(wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003382 // Application tokens start out hidden.
3383 wtoken.hidden = true;
3384 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003386 //dump();
3387 }
3388 }
Romain Guy06882f82009-06-10 13:36:04 -07003389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003390 public void setAppGroupId(IBinder token, int groupId) {
3391 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3392 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003393 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003394 }
3395
3396 synchronized(mWindowMap) {
3397 AppWindowToken wtoken = findAppWindowToken(token);
3398 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003399 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003400 return;
3401 }
3402 wtoken.groupId = groupId;
3403 }
3404 }
Romain Guy06882f82009-06-10 13:36:04 -07003405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003406 public int getOrientationFromWindowsLocked() {
3407 int pos = mWindows.size() - 1;
3408 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07003409 WindowState wtoken = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003410 pos--;
3411 if (wtoken.mAppToken != null) {
3412 // We hit an application window. so the orientation will be determined by the
3413 // app window. No point in continuing further.
3414 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3415 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003416 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003417 continue;
3418 }
3419 int req = wtoken.mAttrs.screenOrientation;
3420 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3421 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3422 continue;
3423 } else {
3424 return req;
3425 }
3426 }
3427 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3428 }
Romain Guy06882f82009-06-10 13:36:04 -07003429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003430 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003431 int pos = mAppTokens.size() - 1;
3432 int curGroup = 0;
3433 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3434 boolean findingBehind = false;
3435 boolean haveGroup = false;
3436 boolean lastFullscreen = false;
3437 while (pos >= 0) {
3438 AppWindowToken wtoken = mAppTokens.get(pos);
3439 pos--;
3440 // if we're about to tear down this window and not seek for
3441 // the behind activity, don't use it for orientation
3442 if (!findingBehind
3443 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3444 continue;
3445 }
3446
3447 if (!haveGroup) {
3448 // We ignore any hidden applications on the top.
3449 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003450 continue;
3451 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003452 haveGroup = true;
3453 curGroup = wtoken.groupId;
3454 lastOrientation = wtoken.requestedOrientation;
3455 } else if (curGroup != wtoken.groupId) {
3456 // If we have hit a new application group, and the bottom
3457 // of the previous group didn't explicitly say to use
3458 // the orientation behind it, and the last app was
3459 // full screen, then we'll stick with the
3460 // user's orientation.
3461 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3462 && lastFullscreen) {
3463 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003465 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003466 int or = wtoken.requestedOrientation;
3467 // If this application is fullscreen, and didn't explicitly say
3468 // to use the orientation behind it, then just take whatever
3469 // orientation it has and ignores whatever is under it.
3470 lastFullscreen = wtoken.appFullscreen;
3471 if (lastFullscreen
3472 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3473 return or;
3474 }
3475 // If this application has requested an explicit orientation,
3476 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003477 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3478 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003479 return or;
3480 }
3481 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3482 }
3483 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003484 }
Romain Guy06882f82009-06-10 13:36:04 -07003485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003486 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003487 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003488 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3489 "updateOrientationFromAppTokens()")) {
3490 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3491 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003492
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003493 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003494 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003495
3496 synchronized(mWindowMap) {
3497 if (updateOrientationFromAppTokensLocked()) {
3498 if (freezeThisOneIfNeeded != null) {
3499 AppWindowToken wtoken = findAppWindowToken(
3500 freezeThisOneIfNeeded);
3501 if (wtoken != null) {
3502 startAppFreezingScreenLocked(wtoken,
3503 ActivityInfo.CONFIG_ORIENTATION);
3504 }
3505 }
3506 config = computeNewConfigurationLocked();
3507
3508 } else if (currentConfig != null) {
3509 // No obvious action we need to take, but if our current
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003510 // state mismatches the activity manager's, update it,
3511 // disregarding font scale, which should remain set to
3512 // the value of the previous configuration.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003513 mTempConfiguration.setToDefaults();
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003514 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003515 if (computeNewConfigurationLocked(mTempConfiguration)) {
3516 if (currentConfig.diff(mTempConfiguration) != 0) {
3517 mWaitingForConfig = true;
3518 mLayoutNeeded = true;
3519 startFreezingDisplayLocked();
3520 config = new Configuration(mTempConfiguration);
3521 }
3522 }
3523 }
3524 }
3525
Dianne Hackborncfaef692009-06-15 14:24:44 -07003526 Binder.restoreCallingIdentity(ident);
3527 return config;
3528 }
3529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003530 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003531 * Determine the new desired orientation of the display, returning
3532 * a non-null new Configuration if it has changed from the current
3533 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3534 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3535 * SCREEN. This will typically be done for you if you call
3536 * sendNewConfiguration().
3537 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 * The orientation is computed from non-application windows first. If none of
3539 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003540 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3542 * android.os.IBinder)
3543 */
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003544 boolean updateOrientationFromAppTokensLocked() {
Christopher Tateb696aee2010-04-02 19:08:30 -07003545 if (mDisplayFrozen) {
3546 // If the display is frozen, some activities may be in the middle
3547 // of restarting, and thus have removed their old window. If the
3548 // window has the flag to hide the lock screen, then the lock screen
3549 // can re-appear and inflict its own orientation on us. Keep the
3550 // orientation stable until this all settles down.
3551 return false;
3552 }
3553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003554 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003555 long ident = Binder.clearCallingIdentity();
3556 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003557 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003559 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003560 mForcedAppOrientation = req;
3561 //send a message to Policy indicating orientation change to take
3562 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003563 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003564 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
3565 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE)) {
3566 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003567 }
3568 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003569
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003570 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003571 } finally {
3572 Binder.restoreCallingIdentity(ident);
3573 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003574 }
Romain Guy06882f82009-06-10 13:36:04 -07003575
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003576 int computeForcedAppOrientationLocked() {
3577 int req = getOrientationFromWindowsLocked();
3578 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3579 req = getOrientationFromAppTokensLocked();
3580 }
3581 return req;
3582 }
Romain Guy06882f82009-06-10 13:36:04 -07003583
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003584 public void setNewConfiguration(Configuration config) {
3585 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3586 "setNewConfiguration()")) {
3587 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3588 }
3589
3590 synchronized(mWindowMap) {
3591 mCurConfiguration = new Configuration(config);
3592 mWaitingForConfig = false;
3593 performLayoutAndPlaceSurfacesLocked();
3594 }
3595 }
3596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003597 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3598 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3599 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003600 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003601 }
Romain Guy06882f82009-06-10 13:36:04 -07003602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003603 synchronized(mWindowMap) {
3604 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3605 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003606 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003607 return;
3608 }
Romain Guy06882f82009-06-10 13:36:04 -07003609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003610 wtoken.requestedOrientation = requestedOrientation;
3611 }
3612 }
Romain Guy06882f82009-06-10 13:36:04 -07003613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003614 public int getAppOrientation(IApplicationToken token) {
3615 synchronized(mWindowMap) {
3616 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3617 if (wtoken == null) {
3618 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3619 }
Romain Guy06882f82009-06-10 13:36:04 -07003620
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003621 return wtoken.requestedOrientation;
3622 }
3623 }
Romain Guy06882f82009-06-10 13:36:04 -07003624
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003625 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3626 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3627 "setFocusedApp()")) {
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 }
3630
3631 synchronized(mWindowMap) {
3632 boolean changed = false;
3633 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003634 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003635 changed = mFocusedApp != null;
3636 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003637 if (changed) {
3638 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003639 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003640 } else {
3641 AppWindowToken newFocus = findAppWindowToken(token);
3642 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003643 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003644 return;
3645 }
3646 changed = mFocusedApp != newFocus;
3647 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003648 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003649 if (changed) {
3650 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003651 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003652 }
3653
3654 if (moveFocusNow && changed) {
3655 final long origId = Binder.clearCallingIdentity();
3656 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3657 Binder.restoreCallingIdentity(origId);
3658 }
3659 }
3660 }
3661
3662 public void prepareAppTransition(int transit) {
3663 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3664 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003665 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 }
Romain Guy06882f82009-06-10 13:36:04 -07003667
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003668 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003669 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 TAG, "Prepare app transition: transit=" + transit
3671 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003672 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003673 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3674 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003675 mNextAppTransition = transit;
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07003676 } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3677 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3678 // Opening a new task always supersedes a close for the anim.
3679 mNextAppTransition = transit;
3680 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3681 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3682 // Opening a new activity always supersedes a close for the anim.
3683 mNextAppTransition = transit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003684 }
3685 mAppTransitionReady = false;
3686 mAppTransitionTimeout = false;
3687 mStartingIconInTransition = false;
3688 mSkipAppTransitionAnimation = false;
3689 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3690 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3691 5000);
3692 }
3693 }
3694 }
3695
3696 public int getPendingAppTransition() {
3697 return mNextAppTransition;
3698 }
Romain Guy06882f82009-06-10 13:36:04 -07003699
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003700 public void overridePendingAppTransition(String packageName,
3701 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003702 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003703 mNextAppTransitionPackage = packageName;
3704 mNextAppTransitionEnter = enterAnim;
3705 mNextAppTransitionExit = exitAnim;
3706 }
3707 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003709 public void executeAppTransition() {
3710 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3711 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003712 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003713 }
Romain Guy06882f82009-06-10 13:36:04 -07003714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003715 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003716 if (DEBUG_APP_TRANSITIONS) {
3717 RuntimeException e = new RuntimeException("here");
3718 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003719 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003720 + mNextAppTransition, e);
3721 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003722 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003723 mAppTransitionReady = true;
3724 final long origId = Binder.clearCallingIdentity();
3725 performLayoutAndPlaceSurfacesLocked();
3726 Binder.restoreCallingIdentity(origId);
3727 }
3728 }
3729 }
3730
3731 public void setAppStartingWindow(IBinder token, String pkg,
3732 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003733 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003734 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3735 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003736 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003737 }
3738
3739 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003740 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003741 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3742 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003744 AppWindowToken wtoken = findAppWindowToken(token);
3745 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003746 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003747 return;
3748 }
3749
3750 // If the display is frozen, we won't do anything until the
3751 // actual window is displayed so there is no reason to put in
3752 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003753 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003754 return;
3755 }
Romain Guy06882f82009-06-10 13:36:04 -07003756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003757 if (wtoken.startingData != null) {
3758 return;
3759 }
Romain Guy06882f82009-06-10 13:36:04 -07003760
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003761 if (transferFrom != null) {
3762 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3763 if (ttoken != null) {
3764 WindowState startingWindow = ttoken.startingWindow;
3765 if (startingWindow != null) {
3766 if (mStartingIconInTransition) {
3767 // In this case, the starting icon has already
3768 // been displayed, so start letting windows get
3769 // shown immediately without any more transitions.
3770 mSkipAppTransitionAnimation = true;
3771 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003772 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003773 "Moving existing starting from " + ttoken
3774 + " to " + wtoken);
3775 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003777 // Transfer the starting window over to the new
3778 // token.
3779 wtoken.startingData = ttoken.startingData;
3780 wtoken.startingView = ttoken.startingView;
3781 wtoken.startingWindow = startingWindow;
3782 ttoken.startingData = null;
3783 ttoken.startingView = null;
3784 ttoken.startingWindow = null;
3785 ttoken.startingMoved = true;
3786 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003787 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003788 startingWindow.mAppToken = wtoken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003789 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003790 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003791 mWindows.remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003792 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003793 ttoken.windows.remove(startingWindow);
3794 ttoken.allAppWindows.remove(startingWindow);
3795 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003797 // Propagate other interesting state between the
3798 // tokens. If the old token is displayed, we should
3799 // immediately force the new one to be displayed. If
3800 // it is animating, we need to move that animation to
3801 // the new one.
3802 if (ttoken.allDrawn) {
3803 wtoken.allDrawn = true;
3804 }
3805 if (ttoken.firstWindowDrawn) {
3806 wtoken.firstWindowDrawn = true;
3807 }
3808 if (!ttoken.hidden) {
3809 wtoken.hidden = false;
3810 wtoken.hiddenRequested = false;
3811 wtoken.willBeHidden = false;
3812 }
3813 if (wtoken.clientHidden != ttoken.clientHidden) {
3814 wtoken.clientHidden = ttoken.clientHidden;
3815 wtoken.sendAppVisibilityToClients();
3816 }
3817 if (ttoken.animation != null) {
3818 wtoken.animation = ttoken.animation;
3819 wtoken.animating = ttoken.animating;
3820 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3821 ttoken.animation = null;
3822 ttoken.animLayerAdjustment = 0;
3823 wtoken.updateLayers();
3824 ttoken.updateLayers();
3825 }
Romain Guy06882f82009-06-10 13:36:04 -07003826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003827 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003828 mLayoutNeeded = true;
3829 performLayoutAndPlaceSurfacesLocked();
3830 Binder.restoreCallingIdentity(origId);
3831 return;
3832 } else if (ttoken.startingData != null) {
3833 // The previous app was getting ready to show a
3834 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003835 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003836 "Moving pending starting from " + ttoken
3837 + " to " + wtoken);
3838 wtoken.startingData = ttoken.startingData;
3839 ttoken.startingData = null;
3840 ttoken.startingMoved = true;
3841 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3842 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3843 // want to process the message ASAP, before any other queued
3844 // messages.
3845 mH.sendMessageAtFrontOfQueue(m);
3846 return;
3847 }
3848 }
3849 }
3850
3851 // There is no existing starting window, and the caller doesn't
3852 // want us to create one, so that's it!
3853 if (!createIfNeeded) {
3854 return;
3855 }
Romain Guy06882f82009-06-10 13:36:04 -07003856
Dianne Hackborn284ac932009-08-28 10:34:25 -07003857 // If this is a translucent or wallpaper window, then don't
3858 // show a starting window -- the current effect (a full-screen
3859 // opaque starting window that fades away to the real contents
3860 // when it is ready) does not work for this.
3861 if (theme != 0) {
3862 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3863 com.android.internal.R.styleable.Window);
3864 if (ent.array.getBoolean(
3865 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3866 return;
3867 }
3868 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003869 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3870 return;
3871 }
3872 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003873 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3874 return;
3875 }
3876 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003878 mStartingIconInTransition = true;
3879 wtoken.startingData = new StartingData(
3880 pkg, theme, nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003881 labelRes, icon, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003882 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3883 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3884 // want to process the message ASAP, before any other queued
3885 // messages.
3886 mH.sendMessageAtFrontOfQueue(m);
3887 }
3888 }
3889
3890 public void setAppWillBeHidden(IBinder token) {
3891 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3892 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003893 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003894 }
3895
3896 AppWindowToken wtoken;
3897
3898 synchronized(mWindowMap) {
3899 wtoken = findAppWindowToken(token);
3900 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003901 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 -08003902 return;
3903 }
3904 wtoken.willBeHidden = true;
3905 }
3906 }
Romain Guy06882f82009-06-10 13:36:04 -07003907
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003908 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3909 boolean visible, int transit, boolean performLayout) {
3910 boolean delayed = false;
3911
3912 if (wtoken.clientHidden == visible) {
3913 wtoken.clientHidden = !visible;
3914 wtoken.sendAppVisibilityToClients();
3915 }
Romain Guy06882f82009-06-10 13:36:04 -07003916
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003917 wtoken.willBeHidden = false;
3918 if (wtoken.hidden == visible) {
3919 final int N = wtoken.allAppWindows.size();
3920 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003921 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003922 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3923 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003925 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003926
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003927 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003928 if (wtoken.animation == sDummyAnimation) {
3929 wtoken.animation = null;
3930 }
3931 applyAnimationLocked(wtoken, lp, transit, visible);
3932 changed = true;
3933 if (wtoken.animation != null) {
3934 delayed = runningAppAnimation = true;
3935 }
3936 }
Romain Guy06882f82009-06-10 13:36:04 -07003937
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003938 for (int i=0; i<N; i++) {
3939 WindowState win = wtoken.allAppWindows.get(i);
3940 if (win == wtoken.startingWindow) {
3941 continue;
3942 }
3943
3944 if (win.isAnimating()) {
3945 delayed = true;
3946 }
Romain Guy06882f82009-06-10 13:36:04 -07003947
Joe Onorato8a9b2202010-02-26 18:56:32 -08003948 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003949 //win.dump(" ");
3950 if (visible) {
3951 if (!win.isVisibleNow()) {
3952 if (!runningAppAnimation) {
3953 applyAnimationLocked(win,
3954 WindowManagerPolicy.TRANSIT_ENTER, true);
3955 }
3956 changed = true;
3957 }
3958 } else if (win.isVisibleNow()) {
3959 if (!runningAppAnimation) {
3960 applyAnimationLocked(win,
3961 WindowManagerPolicy.TRANSIT_EXIT, false);
3962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003963 changed = true;
3964 }
3965 }
3966
3967 wtoken.hidden = wtoken.hiddenRequested = !visible;
3968 if (!visible) {
3969 unsetAppFreezingScreenLocked(wtoken, true, true);
3970 } else {
3971 // If we are being set visible, and the starting window is
3972 // not yet displayed, then make sure it doesn't get displayed.
3973 WindowState swin = wtoken.startingWindow;
3974 if (swin != null && (swin.mDrawPending
3975 || swin.mCommitDrawPending)) {
3976 swin.mPolicyVisibility = false;
3977 swin.mPolicyVisibilityAfterAnim = false;
3978 }
3979 }
Romain Guy06882f82009-06-10 13:36:04 -07003980
Joe Onorato8a9b2202010-02-26 18:56:32 -08003981 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003982 + ": hidden=" + wtoken.hidden + " hiddenRequested="
3983 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07003984
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003985 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003986 mLayoutNeeded = true;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003987 if (performLayout) {
3988 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
3989 performLayoutAndPlaceSurfacesLocked();
Jeff Browne33348b2010-07-15 23:54:05 -07003990 } else {
3991 mInputMonitor.updateInputWindowsLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003992 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003993 }
3994 }
3995
3996 if (wtoken.animation != null) {
3997 delayed = true;
3998 }
Romain Guy06882f82009-06-10 13:36:04 -07003999
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004000 return delayed;
4001 }
4002
4003 public void setAppVisibility(IBinder token, boolean visible) {
4004 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4005 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004006 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004007 }
4008
4009 AppWindowToken wtoken;
4010
4011 synchronized(mWindowMap) {
4012 wtoken = findAppWindowToken(token);
4013 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004014 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004015 return;
4016 }
4017
4018 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004019 RuntimeException e = null;
4020 if (!HIDE_STACK_CRAWLS) {
4021 e = new RuntimeException();
4022 e.fillInStackTrace();
4023 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004024 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004025 + "): mNextAppTransition=" + mNextAppTransition
4026 + " hidden=" + wtoken.hidden
4027 + " hiddenRequested=" + wtoken.hiddenRequested, e);
4028 }
Romain Guy06882f82009-06-10 13:36:04 -07004029
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004030 // If we are preparing an app transition, then delay changing
4031 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004032 if (!mDisplayFrozen && mPolicy.isScreenOn()
4033 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004034 // Already in requested state, don't do anything more.
4035 if (wtoken.hiddenRequested != visible) {
4036 return;
4037 }
4038 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07004039
Joe Onorato8a9b2202010-02-26 18:56:32 -08004040 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004041 TAG, "Setting dummy animation on: " + wtoken);
4042 wtoken.setDummyAnimation();
4043 mOpeningApps.remove(wtoken);
4044 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004045 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004046 wtoken.inPendingTransaction = true;
4047 if (visible) {
4048 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004049 wtoken.startingDisplayed = false;
4050 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004051
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004052 // If the token is currently hidden (should be the
4053 // common case), then we need to set up to wait for
4054 // its windows to be ready.
4055 if (wtoken.hidden) {
4056 wtoken.allDrawn = false;
4057 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004058
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004059 if (wtoken.clientHidden) {
4060 // In the case where we are making an app visible
4061 // but holding off for a transition, we still need
4062 // to tell the client to make its windows visible so
4063 // they get drawn. Otherwise, we will wait on
4064 // performing the transition until all windows have
4065 // been drawn, they never will be, and we are sad.
4066 wtoken.clientHidden = false;
4067 wtoken.sendAppVisibilityToClients();
4068 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004069 }
4070 } else {
4071 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004072
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004073 // If the token is currently visible (should be the
4074 // common case), then set up to wait for it to be hidden.
4075 if (!wtoken.hidden) {
4076 wtoken.waitingToHide = true;
4077 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004078 }
4079 return;
4080 }
Romain Guy06882f82009-06-10 13:36:04 -07004081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004082 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004083 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004084 wtoken.updateReportedVisibilityLocked();
4085 Binder.restoreCallingIdentity(origId);
4086 }
4087 }
4088
4089 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4090 boolean unfreezeSurfaceNow, boolean force) {
4091 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004092 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004093 + " force=" + force);
4094 final int N = wtoken.allAppWindows.size();
4095 boolean unfrozeWindows = false;
4096 for (int i=0; i<N; i++) {
4097 WindowState w = wtoken.allAppWindows.get(i);
4098 if (w.mAppFreezing) {
4099 w.mAppFreezing = false;
4100 if (w.mSurface != null && !w.mOrientationChanging) {
4101 w.mOrientationChanging = true;
4102 }
4103 unfrozeWindows = true;
4104 }
4105 }
4106 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004107 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004108 wtoken.freezingScreen = false;
4109 mAppsFreezingScreen--;
4110 }
4111 if (unfreezeSurfaceNow) {
4112 if (unfrozeWindows) {
4113 mLayoutNeeded = true;
4114 performLayoutAndPlaceSurfacesLocked();
4115 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004116 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004117 }
4118 }
4119 }
Romain Guy06882f82009-06-10 13:36:04 -07004120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004121 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4122 int configChanges) {
4123 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004124 RuntimeException e = null;
4125 if (!HIDE_STACK_CRAWLS) {
4126 e = new RuntimeException();
4127 e.fillInStackTrace();
4128 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004129 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004130 + ": hidden=" + wtoken.hidden + " freezing="
4131 + wtoken.freezingScreen, e);
4132 }
4133 if (!wtoken.hiddenRequested) {
4134 if (!wtoken.freezingScreen) {
4135 wtoken.freezingScreen = true;
4136 mAppsFreezingScreen++;
4137 if (mAppsFreezingScreen == 1) {
4138 startFreezingDisplayLocked();
4139 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4140 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
4141 5000);
4142 }
4143 }
4144 final int N = wtoken.allAppWindows.size();
4145 for (int i=0; i<N; i++) {
4146 WindowState w = wtoken.allAppWindows.get(i);
4147 w.mAppFreezing = true;
4148 }
4149 }
4150 }
Romain Guy06882f82009-06-10 13:36:04 -07004151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004152 public void startAppFreezingScreen(IBinder token, int configChanges) {
4153 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4154 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004155 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004156 }
4157
4158 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004159 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004160 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004161 return;
4162 }
Romain Guy06882f82009-06-10 13:36:04 -07004163
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004164 AppWindowToken wtoken = findAppWindowToken(token);
4165 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004166 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004167 return;
4168 }
4169 final long origId = Binder.clearCallingIdentity();
4170 startAppFreezingScreenLocked(wtoken, configChanges);
4171 Binder.restoreCallingIdentity(origId);
4172 }
4173 }
Romain Guy06882f82009-06-10 13:36:04 -07004174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004175 public void stopAppFreezingScreen(IBinder token, boolean force) {
4176 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4177 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004178 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004179 }
4180
4181 synchronized(mWindowMap) {
4182 AppWindowToken wtoken = findAppWindowToken(token);
4183 if (wtoken == null || wtoken.appToken == null) {
4184 return;
4185 }
4186 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004187 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004188 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
4189 unsetAppFreezingScreenLocked(wtoken, true, force);
4190 Binder.restoreCallingIdentity(origId);
4191 }
4192 }
Romain Guy06882f82009-06-10 13:36:04 -07004193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004194 public void removeAppToken(IBinder token) {
4195 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4196 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004197 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004198 }
4199
4200 AppWindowToken wtoken = null;
4201 AppWindowToken startingToken = null;
4202 boolean delayed = false;
4203
4204 final long origId = Binder.clearCallingIdentity();
4205 synchronized(mWindowMap) {
4206 WindowToken basewtoken = mTokenMap.remove(token);
4207 mTokenList.remove(basewtoken);
4208 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004209 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004210 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004211 wtoken.inPendingTransaction = false;
4212 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004213 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004214 if (mClosingApps.contains(wtoken)) {
4215 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004216 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004217 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004218 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004219 delayed = true;
4220 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004221 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004222 TAG, "Removing app " + wtoken + " delayed=" + delayed
4223 + " animation=" + wtoken.animation
4224 + " animating=" + wtoken.animating);
4225 if (delayed) {
4226 // set the token aside because it has an active animation to be finished
4227 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004228 } else {
4229 // Make sure there is no animation running on this token,
4230 // so any windows associated with it will be removed as
4231 // soon as their animations are complete
4232 wtoken.animation = null;
4233 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004234 }
4235 mAppTokens.remove(wtoken);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004236 if (mLastEnterAnimToken == wtoken) {
4237 mLastEnterAnimToken = null;
4238 mLastEnterAnimParams = null;
4239 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004240 wtoken.removed = true;
4241 if (wtoken.startingData != null) {
4242 startingToken = wtoken;
4243 }
4244 unsetAppFreezingScreenLocked(wtoken, true, true);
4245 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004246 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004247 mFocusedApp = null;
4248 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004249 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004250 }
4251 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004252 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004253 }
Romain Guy06882f82009-06-10 13:36:04 -07004254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004255 if (!delayed && wtoken != null) {
4256 wtoken.updateReportedVisibilityLocked();
4257 }
4258 }
4259 Binder.restoreCallingIdentity(origId);
4260
4261 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004262 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004263 + startingToken + ": app token removed");
4264 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4265 mH.sendMessage(m);
4266 }
4267 }
4268
4269 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4270 final int NW = token.windows.size();
4271 for (int i=0; i<NW; i++) {
4272 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004273 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004274 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004275 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004276 int j = win.mChildWindows.size();
4277 while (j > 0) {
4278 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004279 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004280 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004281 "Tmp removing child window " + cwin);
4282 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004283 }
4284 }
4285 return NW > 0;
4286 }
4287
4288 void dumpAppTokensLocked() {
4289 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004290 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004291 }
4292 }
Romain Guy06882f82009-06-10 13:36:04 -07004293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004294 void dumpWindowsLocked() {
4295 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004296 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004297 }
4298 }
Romain Guy06882f82009-06-10 13:36:04 -07004299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004300 private int findWindowOffsetLocked(int tokenPos) {
4301 final int NW = mWindows.size();
4302
4303 if (tokenPos >= mAppTokens.size()) {
4304 int i = NW;
4305 while (i > 0) {
4306 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07004307 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004308 if (win.getAppToken() != null) {
4309 return i+1;
4310 }
4311 }
4312 }
4313
4314 while (tokenPos > 0) {
4315 // Find the first app token below the new position that has
4316 // a window displayed.
4317 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004318 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004319 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004320 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004321 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004322 "Skipping token -- currently sending to bottom");
4323 tokenPos--;
4324 continue;
4325 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004326 int i = wtoken.windows.size();
4327 while (i > 0) {
4328 i--;
4329 WindowState win = wtoken.windows.get(i);
4330 int j = win.mChildWindows.size();
4331 while (j > 0) {
4332 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004333 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004334 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004335 for (int pos=NW-1; pos>=0; pos--) {
4336 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004337 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004338 "Found child win @" + (pos+1));
4339 return pos+1;
4340 }
4341 }
4342 }
4343 }
4344 for (int pos=NW-1; pos>=0; pos--) {
4345 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004346 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004347 return pos+1;
4348 }
4349 }
4350 }
4351 tokenPos--;
4352 }
4353
4354 return 0;
4355 }
4356
4357 private final int reAddWindowLocked(int index, WindowState win) {
4358 final int NCW = win.mChildWindows.size();
4359 boolean added = false;
4360 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004361 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004362 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004363 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004364 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004365 mWindows.add(index, win);
4366 index++;
4367 added = true;
4368 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004369 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004370 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004371 mWindows.add(index, cwin);
4372 index++;
4373 }
4374 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004375 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004376 + index + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004377 mWindows.add(index, win);
4378 index++;
4379 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004380 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004381 return index;
4382 }
Romain Guy06882f82009-06-10 13:36:04 -07004383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004384 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4385 final int NW = token.windows.size();
4386 for (int i=0; i<NW; i++) {
4387 index = reAddWindowLocked(index, token.windows.get(i));
4388 }
4389 return index;
4390 }
4391
4392 public void moveAppToken(int index, IBinder token) {
4393 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4394 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004395 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004396 }
4397
4398 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004399 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004400 if (DEBUG_REORDER) dumpAppTokensLocked();
4401 final AppWindowToken wtoken = findAppWindowToken(token);
4402 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004403 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004404 + token + " (" + wtoken + ")");
4405 return;
4406 }
4407 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004408 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004409 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004411 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004412 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004413 if (DEBUG_REORDER) dumpWindowsLocked();
4414 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004415 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004416 if (DEBUG_REORDER) dumpWindowsLocked();
4417 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004418 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004419 if (DEBUG_REORDER) dumpWindowsLocked();
4420 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004421 mLayoutNeeded = true;
4422 performLayoutAndPlaceSurfacesLocked();
4423 }
4424 Binder.restoreCallingIdentity(origId);
4425 }
4426 }
4427
4428 private void removeAppTokensLocked(List<IBinder> tokens) {
4429 // XXX This should be done more efficiently!
4430 // (take advantage of the fact that both lists should be
4431 // ordered in the same way.)
4432 int N = tokens.size();
4433 for (int i=0; i<N; i++) {
4434 IBinder token = tokens.get(i);
4435 final AppWindowToken wtoken = findAppWindowToken(token);
4436 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004437 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004438 + token + " (" + wtoken + ")");
4439 i--;
4440 N--;
4441 }
4442 }
4443 }
4444
Dianne Hackborna8f60182009-09-01 19:01:50 -07004445 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4446 boolean updateFocusAndLayout) {
4447 // First remove all of the windows from the list.
4448 tmpRemoveAppWindowsLocked(wtoken);
4449
4450 // Where to start adding?
4451 int pos = findWindowOffsetLocked(tokenPos);
4452
4453 // And now add them back at the correct place.
4454 pos = reAddAppWindowsLocked(pos, wtoken);
4455
4456 if (updateFocusAndLayout) {
4457 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4458 assignLayersLocked();
4459 }
4460 mLayoutNeeded = true;
4461 performLayoutAndPlaceSurfacesLocked();
4462 }
4463 }
4464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004465 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4466 // First remove all of the windows from the list.
4467 final int N = tokens.size();
4468 int i;
4469 for (i=0; i<N; i++) {
4470 WindowToken token = mTokenMap.get(tokens.get(i));
4471 if (token != null) {
4472 tmpRemoveAppWindowsLocked(token);
4473 }
4474 }
4475
4476 // Where to start adding?
4477 int pos = findWindowOffsetLocked(tokenPos);
4478
4479 // And now add them back at the correct place.
4480 for (i=0; i<N; i++) {
4481 WindowToken token = mTokenMap.get(tokens.get(i));
4482 if (token != null) {
4483 pos = reAddAppWindowsLocked(pos, token);
4484 }
4485 }
4486
Dianne Hackborna8f60182009-09-01 19:01:50 -07004487 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4488 assignLayersLocked();
4489 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004490 mLayoutNeeded = true;
4491 performLayoutAndPlaceSurfacesLocked();
4492
4493 //dump();
4494 }
4495
4496 public void moveAppTokensToTop(List<IBinder> tokens) {
4497 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4498 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004499 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004500 }
4501
4502 final long origId = Binder.clearCallingIdentity();
4503 synchronized(mWindowMap) {
4504 removeAppTokensLocked(tokens);
4505 final int N = tokens.size();
4506 for (int i=0; i<N; i++) {
4507 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4508 if (wt != null) {
4509 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004510 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004511 mToTopApps.remove(wt);
4512 mToBottomApps.remove(wt);
4513 mToTopApps.add(wt);
4514 wt.sendingToBottom = false;
4515 wt.sendingToTop = true;
4516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004517 }
4518 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004519
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004520 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004521 moveAppWindowsLocked(tokens, mAppTokens.size());
4522 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004523 }
4524 Binder.restoreCallingIdentity(origId);
4525 }
4526
4527 public void moveAppTokensToBottom(List<IBinder> tokens) {
4528 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4529 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004530 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004531 }
4532
4533 final long origId = Binder.clearCallingIdentity();
4534 synchronized(mWindowMap) {
4535 removeAppTokensLocked(tokens);
4536 final int N = tokens.size();
4537 int pos = 0;
4538 for (int i=0; i<N; i++) {
4539 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4540 if (wt != null) {
4541 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004542 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004543 mToTopApps.remove(wt);
4544 mToBottomApps.remove(wt);
4545 mToBottomApps.add(i, wt);
4546 wt.sendingToTop = false;
4547 wt.sendingToBottom = true;
4548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004549 pos++;
4550 }
4551 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004552
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004553 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004554 moveAppWindowsLocked(tokens, 0);
4555 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004556 }
4557 Binder.restoreCallingIdentity(origId);
4558 }
4559
4560 // -------------------------------------------------------------
4561 // Misc IWindowSession methods
4562 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004563
Jim Miller284b62e2010-06-08 14:27:42 -07004564 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004565 {
Jim Miller284b62e2010-06-08 14:27:42 -07004566 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4567 // called before DevicePolicyManagerService has started.
4568 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4569 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4570 Context.DEVICE_POLICY_SERVICE);
4571 if (dpm != null) {
4572 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4573 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4574 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4575 }
Jim Millerd6b57052010-06-07 17:52:42 -07004576 }
Jim Miller284b62e2010-06-08 14:27:42 -07004577 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004578 }
4579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004580 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004581 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004582 != PackageManager.PERMISSION_GRANTED) {
4583 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4584 }
Jim Millerd6b57052010-06-07 17:52:42 -07004585
Jim Miller284b62e2010-06-08 14:27:42 -07004586 synchronized (mKeyguardTokenWatcher) {
4587 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004588 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004589 }
4590
4591 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004592 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004593 != PackageManager.PERMISSION_GRANTED) {
4594 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4595 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004596
Jim Miller284b62e2010-06-08 14:27:42 -07004597 synchronized (mKeyguardTokenWatcher) {
4598 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004599
Jim Miller284b62e2010-06-08 14:27:42 -07004600 if (!mKeyguardTokenWatcher.isAcquired()) {
4601 // If we are the last one to reenable the keyguard wait until
4602 // we have actually finished reenabling until returning.
4603 // It is possible that reenableKeyguard() can be called before
4604 // the previous disableKeyguard() is handled, in which case
4605 // neither mKeyguardTokenWatcher.acquired() or released() would
4606 // be called. In that case mKeyguardDisabled will be false here
4607 // and we have nothing to wait for.
4608 while (mKeyguardDisabled) {
4609 try {
4610 mKeyguardTokenWatcher.wait();
4611 } catch (InterruptedException e) {
4612 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004613 }
4614 }
4615 }
4616 }
4617 }
4618
4619 /**
4620 * @see android.app.KeyguardManager#exitKeyguardSecurely
4621 */
4622 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004623 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004624 != PackageManager.PERMISSION_GRANTED) {
4625 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4626 }
4627 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4628 public void onKeyguardExitResult(boolean success) {
4629 try {
4630 callback.onKeyguardExitResult(success);
4631 } catch (RemoteException e) {
4632 // Client has died, we don't care.
4633 }
4634 }
4635 });
4636 }
4637
4638 public boolean inKeyguardRestrictedInputMode() {
4639 return mPolicy.inKeyguardRestrictedKeyInputMode();
4640 }
Romain Guy06882f82009-06-10 13:36:04 -07004641
Dianne Hackbornffa42482009-09-23 22:20:11 -07004642 public void closeSystemDialogs(String reason) {
4643 synchronized(mWindowMap) {
4644 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004645 WindowState w = mWindows.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004646 if (w.mSurface != null) {
4647 try {
4648 w.mClient.closeSystemDialogs(reason);
4649 } catch (RemoteException e) {
4650 }
4651 }
4652 }
4653 }
4654 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004656 static float fixScale(float scale) {
4657 if (scale < 0) scale = 0;
4658 else if (scale > 20) scale = 20;
4659 return Math.abs(scale);
4660 }
Romain Guy06882f82009-06-10 13:36:04 -07004661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004662 public void setAnimationScale(int which, float scale) {
4663 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4664 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004665 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004666 }
4667
4668 if (scale < 0) scale = 0;
4669 else if (scale > 20) scale = 20;
4670 scale = Math.abs(scale);
4671 switch (which) {
4672 case 0: mWindowAnimationScale = fixScale(scale); break;
4673 case 1: mTransitionAnimationScale = fixScale(scale); break;
4674 }
Romain Guy06882f82009-06-10 13:36:04 -07004675
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004676 // Persist setting
4677 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4678 }
Romain Guy06882f82009-06-10 13:36:04 -07004679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004680 public void setAnimationScales(float[] scales) {
4681 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4682 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004683 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004684 }
4685
4686 if (scales != null) {
4687 if (scales.length >= 1) {
4688 mWindowAnimationScale = fixScale(scales[0]);
4689 }
4690 if (scales.length >= 2) {
4691 mTransitionAnimationScale = fixScale(scales[1]);
4692 }
4693 }
Romain Guy06882f82009-06-10 13:36:04 -07004694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004695 // Persist setting
4696 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4697 }
Romain Guy06882f82009-06-10 13:36:04 -07004698
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004699 public float getAnimationScale(int which) {
4700 switch (which) {
4701 case 0: return mWindowAnimationScale;
4702 case 1: return mTransitionAnimationScale;
4703 }
4704 return 0;
4705 }
Romain Guy06882f82009-06-10 13:36:04 -07004706
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004707 public float[] getAnimationScales() {
4708 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4709 }
Romain Guy06882f82009-06-10 13:36:04 -07004710
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004711 public int getSwitchState(int sw) {
4712 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4713 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004714 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004715 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004716 return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004717 }
Romain Guy06882f82009-06-10 13:36:04 -07004718
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004719 public int getSwitchStateForDevice(int devid, int sw) {
4720 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4721 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004722 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004723 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004724 return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004725 }
Romain Guy06882f82009-06-10 13:36:04 -07004726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004727 public int getScancodeState(int sw) {
4728 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4729 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004730 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004731 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004732 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004733 }
Romain Guy06882f82009-06-10 13:36:04 -07004734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004735 public int getScancodeStateForDevice(int devid, int sw) {
4736 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4737 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004738 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004739 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004740 return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004741 }
Romain Guy06882f82009-06-10 13:36:04 -07004742
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004743 public int getTrackballScancodeState(int sw) {
4744 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4745 "getTrackballScancodeState()")) {
4746 throw new SecurityException("Requires READ_INPUT_STATE permission");
4747 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004748 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004749 }
4750
4751 public int getDPadScancodeState(int sw) {
4752 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4753 "getDPadScancodeState()")) {
4754 throw new SecurityException("Requires READ_INPUT_STATE permission");
4755 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004756 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004757 }
4758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004759 public int getKeycodeState(int sw) {
4760 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4761 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004762 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004763 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004764 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004765 }
Romain Guy06882f82009-06-10 13:36:04 -07004766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004767 public int getKeycodeStateForDevice(int devid, int sw) {
4768 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4769 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004770 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004771 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004772 return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004773 }
Romain Guy06882f82009-06-10 13:36:04 -07004774
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004775 public int getTrackballKeycodeState(int sw) {
4776 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4777 "getTrackballKeycodeState()")) {
4778 throw new SecurityException("Requires READ_INPUT_STATE permission");
4779 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004780 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004781 }
4782
4783 public int getDPadKeycodeState(int sw) {
4784 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4785 "getDPadKeycodeState()")) {
4786 throw new SecurityException("Requires READ_INPUT_STATE permission");
4787 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004788 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004789 }
Jeff Browna41ca772010-08-11 14:46:32 -07004790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004791 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown6d0fec22010-07-23 21:28:06 -07004792 return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004793 }
Romain Guy06882f82009-06-10 13:36:04 -07004794
Jeff Browna41ca772010-08-11 14:46:32 -07004795 public InputChannel monitorInput(String inputChannelName) {
4796 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4797 "monitorInput()")) {
4798 throw new SecurityException("Requires READ_INPUT_STATE permission");
4799 }
4800 return mInputManager.monitorInput(inputChannelName);
4801 }
4802
Jeff Brown8d608662010-08-30 03:02:23 -07004803 public InputDevice getInputDevice(int deviceId) {
4804 return mInputManager.getInputDevice(deviceId);
4805 }
4806
4807 public int[] getInputDeviceIds() {
4808 return mInputManager.getInputDeviceIds();
4809 }
4810
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004811 public void enableScreenAfterBoot() {
4812 synchronized(mWindowMap) {
4813 if (mSystemBooted) {
4814 return;
4815 }
4816 mSystemBooted = true;
4817 }
Romain Guy06882f82009-06-10 13:36:04 -07004818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004819 performEnableScreen();
4820 }
Romain Guy06882f82009-06-10 13:36:04 -07004821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004822 public void enableScreenIfNeededLocked() {
4823 if (mDisplayEnabled) {
4824 return;
4825 }
4826 if (!mSystemBooted) {
4827 return;
4828 }
4829 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4830 }
Romain Guy06882f82009-06-10 13:36:04 -07004831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004832 public void performEnableScreen() {
4833 synchronized(mWindowMap) {
4834 if (mDisplayEnabled) {
4835 return;
4836 }
4837 if (!mSystemBooted) {
4838 return;
4839 }
Romain Guy06882f82009-06-10 13:36:04 -07004840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004841 // Don't enable the screen until all existing windows
4842 // have been drawn.
4843 final int N = mWindows.size();
4844 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004845 WindowState w = mWindows.get(i);
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08004846 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004847 return;
4848 }
4849 }
Romain Guy06882f82009-06-10 13:36:04 -07004850
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004851 mDisplayEnabled = true;
4852 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004853 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004854 StringWriter sw = new StringWriter();
4855 PrintWriter pw = new PrintWriter(sw);
4856 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004857 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004858 }
4859 try {
4860 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4861 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004862 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004863 Parcel data = Parcel.obtain();
4864 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4865 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4866 data, null, 0);
4867 data.recycle();
4868 }
4869 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004870 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004871 }
4872 }
Romain Guy06882f82009-06-10 13:36:04 -07004873
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004874 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004875
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004876 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004877 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4878 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004879 }
Romain Guy06882f82009-06-10 13:36:04 -07004880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004881 public void setInTouchMode(boolean mode) {
4882 synchronized(mWindowMap) {
4883 mInTouchMode = mode;
4884 }
4885 }
4886
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004887 // TODO: more accounting of which pid(s) turned it on, keep count,
4888 // only allow disables from pids which have count on, etc.
4889 public void showStrictModeViolation(boolean on) {
4890 int pid = Binder.getCallingPid();
4891 synchronized(mWindowMap) {
4892 // Ignoring requests to enable the red border from clients
4893 // which aren't on screen. (e.g. Broadcast Receivers in
4894 // the background..)
4895 if (on) {
4896 boolean isVisible = false;
4897 for (WindowState ws : mWindows) {
4898 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
4899 isVisible = true;
4900 break;
4901 }
4902 }
4903 if (!isVisible) {
4904 return;
4905 }
4906 }
4907
4908 Surface.openTransaction();
4909 if (mStrictModeFlash == null) {
4910 mStrictModeFlash = new StrictModeFlash(mDisplay, mFxSession);
4911 }
4912 mStrictModeFlash.setVisibility(on);
4913 Surface.closeTransaction();
4914 }
4915 }
4916
Daniel Sandlerb73617d2010-08-17 00:41:00 -04004917 public void freezeRotation() {
4918 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
4919 "setRotation()")) {
4920 throw new SecurityException("Requires SET_ORIENTATION permission");
4921 }
4922
4923 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, mRotation);
4924 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
4925 }
4926
4927 public void thawRotation() {
4928 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
4929 "setRotation()")) {
4930 throw new SecurityException("Requires SET_ORIENTATION permission");
4931 }
4932
4933 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 0);
4934 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
4935 }
4936
Romain Guy06882f82009-06-10 13:36:04 -07004937 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004938 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004939 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004940 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004941 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004942 }
4943
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004944 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004945 }
Romain Guy06882f82009-06-10 13:36:04 -07004946
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004947 public void setRotationUnchecked(int rotation,
4948 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004949 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004950 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07004951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004952 long origId = Binder.clearCallingIdentity();
4953 boolean changed;
4954 synchronized(mWindowMap) {
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004955 changed = setRotationUncheckedLocked(rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004956 }
Romain Guy06882f82009-06-10 13:36:04 -07004957
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004958 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004959 sendNewConfiguration();
4960 }
Romain Guy06882f82009-06-10 13:36:04 -07004961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004962 Binder.restoreCallingIdentity(origId);
4963 }
Romain Guy06882f82009-06-10 13:36:04 -07004964
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004965 /**
4966 * Apply a new rotation to the screen, respecting the requests of
4967 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
4968 * re-evaluate the desired rotation.
4969 *
4970 * Returns null if the rotation has been changed. In this case YOU
4971 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
4972 */
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004973 public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004974 boolean changed;
4975 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
4976 rotation = mRequestedRotation;
4977 } else {
4978 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07004979 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004980 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004981 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07004982 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004983 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004984 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004985 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07004986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004987 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004988 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004989 "Rotation changed to " + rotation
4990 + " from " + mRotation
4991 + " (forceApp=" + mForcedAppOrientation
4992 + ", req=" + mRequestedRotation + ")");
4993 mRotation = rotation;
4994 mWindowsFreezingScreen = true;
4995 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
4996 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
4997 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004998 mWaitingForConfig = true;
4999 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005000 startFreezingDisplayLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005001 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005002 mInputManager.setDisplayOrientation(0, rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005003 if (mDisplayEnabled) {
Dianne Hackborn321ae682009-03-27 16:16:03 -07005004 Surface.setOrientation(0, rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005005 }
5006 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07005007 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005008 if (w.mSurface != null) {
5009 w.mOrientationChanging = true;
5010 }
5011 }
5012 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
5013 try {
5014 mRotationWatchers.get(i).onRotationChanged(rotation);
5015 } catch (RemoteException e) {
5016 }
5017 }
5018 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07005019
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005020 return changed;
5021 }
Romain Guy06882f82009-06-10 13:36:04 -07005022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005023 public int getRotation() {
5024 return mRotation;
5025 }
5026
5027 public int watchRotation(IRotationWatcher watcher) {
5028 final IBinder watcherBinder = watcher.asBinder();
5029 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
5030 public void binderDied() {
5031 synchronized (mWindowMap) {
5032 for (int i=0; i<mRotationWatchers.size(); i++) {
5033 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07005034 IRotationWatcher removed = mRotationWatchers.remove(i);
5035 if (removed != null) {
5036 removed.asBinder().unlinkToDeath(this, 0);
5037 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005038 i--;
5039 }
5040 }
5041 }
5042 }
5043 };
Romain Guy06882f82009-06-10 13:36:04 -07005044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005045 synchronized (mWindowMap) {
5046 try {
5047 watcher.asBinder().linkToDeath(dr, 0);
5048 mRotationWatchers.add(watcher);
5049 } catch (RemoteException e) {
5050 // Client died, no cleanup needed.
5051 }
Romain Guy06882f82009-06-10 13:36:04 -07005052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005053 return mRotation;
5054 }
5055 }
5056
5057 /**
5058 * Starts the view server on the specified port.
5059 *
5060 * @param port The port to listener to.
5061 *
5062 * @return True if the server was successfully started, false otherwise.
5063 *
5064 * @see com.android.server.ViewServer
5065 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
5066 */
5067 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07005068 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005069 return false;
5070 }
5071
5072 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
5073 return false;
5074 }
5075
5076 if (port < 1024) {
5077 return false;
5078 }
5079
5080 if (mViewServer != null) {
5081 if (!mViewServer.isRunning()) {
5082 try {
5083 return mViewServer.start();
5084 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005085 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005086 }
5087 }
5088 return false;
5089 }
5090
5091 try {
5092 mViewServer = new ViewServer(this, port);
5093 return mViewServer.start();
5094 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005095 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005096 }
5097 return false;
5098 }
5099
Romain Guy06882f82009-06-10 13:36:04 -07005100 private boolean isSystemSecure() {
5101 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
5102 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5103 }
5104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005105 /**
5106 * Stops the view server if it exists.
5107 *
5108 * @return True if the server stopped, false if it wasn't started or
5109 * couldn't be stopped.
5110 *
5111 * @see com.android.server.ViewServer
5112 */
5113 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07005114 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005115 return false;
5116 }
5117
5118 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
5119 return false;
5120 }
5121
5122 if (mViewServer != null) {
5123 return mViewServer.stop();
5124 }
5125 return false;
5126 }
5127
5128 /**
5129 * Indicates whether the view server is running.
5130 *
5131 * @return True if the server is running, false otherwise.
5132 *
5133 * @see com.android.server.ViewServer
5134 */
5135 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07005136 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005137 return false;
5138 }
5139
5140 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
5141 return false;
5142 }
5143
5144 return mViewServer != null && mViewServer.isRunning();
5145 }
5146
5147 /**
5148 * Lists all availble windows in the system. The listing is written in the
5149 * specified Socket's output stream with the following syntax:
5150 * windowHashCodeInHexadecimal windowName
5151 * Each line of the ouput represents a different window.
5152 *
5153 * @param client The remote client to send the listing to.
5154 * @return False if an error occured, true otherwise.
5155 */
5156 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07005157 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005158 return false;
5159 }
5160
5161 boolean result = true;
5162
Jeff Browne33348b2010-07-15 23:54:05 -07005163 WindowState[] windows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005164 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005165 //noinspection unchecked
Jeff Browne33348b2010-07-15 23:54:05 -07005166 windows = mWindows.toArray(new WindowState[mWindows.size()]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005167 }
5168
5169 BufferedWriter out = null;
5170
5171 // Any uncaught exception will crash the system process
5172 try {
5173 OutputStream clientStream = client.getOutputStream();
5174 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5175
5176 final int count = windows.length;
5177 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005178 final WindowState w = windows[i];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005179 out.write(Integer.toHexString(System.identityHashCode(w)));
5180 out.write(' ');
5181 out.append(w.mAttrs.getTitle());
5182 out.write('\n');
5183 }
5184
5185 out.write("DONE.\n");
5186 out.flush();
5187 } catch (Exception e) {
5188 result = false;
5189 } finally {
5190 if (out != null) {
5191 try {
5192 out.close();
5193 } catch (IOException e) {
5194 result = false;
5195 }
5196 }
5197 }
5198
5199 return result;
5200 }
5201
5202 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07005203 * Returns the focused window in the following format:
5204 * windowHashCodeInHexadecimal windowName
5205 *
5206 * @param client The remote client to send the listing to.
5207 * @return False if an error occurred, true otherwise.
5208 */
5209 boolean viewServerGetFocusedWindow(Socket client) {
5210 if (isSystemSecure()) {
5211 return false;
5212 }
5213
5214 boolean result = true;
5215
5216 WindowState focusedWindow = getFocusedWindow();
5217
5218 BufferedWriter out = null;
5219
5220 // Any uncaught exception will crash the system process
5221 try {
5222 OutputStream clientStream = client.getOutputStream();
5223 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5224
5225 if(focusedWindow != null) {
5226 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
5227 out.write(' ');
5228 out.append(focusedWindow.mAttrs.getTitle());
5229 }
5230 out.write('\n');
5231 out.flush();
5232 } catch (Exception e) {
5233 result = false;
5234 } finally {
5235 if (out != null) {
5236 try {
5237 out.close();
5238 } catch (IOException e) {
5239 result = false;
5240 }
5241 }
5242 }
5243
5244 return result;
5245 }
5246
5247 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005248 * Sends a command to a target window. The result of the command, if any, will be
5249 * written in the output stream of the specified socket.
5250 *
5251 * The parameters must follow this syntax:
5252 * windowHashcode extra
5253 *
5254 * Where XX is the length in characeters of the windowTitle.
5255 *
5256 * The first parameter is the target window. The window with the specified hashcode
5257 * will be the target. If no target can be found, nothing happens. The extra parameters
5258 * will be delivered to the target window and as parameters to the command itself.
5259 *
5260 * @param client The remote client to sent the result, if any, to.
5261 * @param command The command to execute.
5262 * @param parameters The command parameters.
5263 *
5264 * @return True if the command was successfully delivered, false otherwise. This does
5265 * not indicate whether the command itself was successful.
5266 */
5267 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07005268 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005269 return false;
5270 }
5271
5272 boolean success = true;
5273 Parcel data = null;
5274 Parcel reply = null;
5275
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005276 BufferedWriter out = null;
5277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005278 // Any uncaught exception will crash the system process
5279 try {
5280 // Find the hashcode of the window
5281 int index = parameters.indexOf(' ');
5282 if (index == -1) {
5283 index = parameters.length();
5284 }
5285 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08005286 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005287
5288 // Extract the command's parameter after the window description
5289 if (index < parameters.length()) {
5290 parameters = parameters.substring(index + 1);
5291 } else {
5292 parameters = "";
5293 }
5294
5295 final WindowManagerService.WindowState window = findWindow(hashCode);
5296 if (window == null) {
5297 return false;
5298 }
5299
5300 data = Parcel.obtain();
5301 data.writeInterfaceToken("android.view.IWindow");
5302 data.writeString(command);
5303 data.writeString(parameters);
5304 data.writeInt(1);
5305 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
5306
5307 reply = Parcel.obtain();
5308
5309 final IBinder binder = window.mClient.asBinder();
5310 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
5311 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
5312
5313 reply.readException();
5314
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005315 if (!client.isOutputShutdown()) {
5316 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
5317 out.write("DONE\n");
5318 out.flush();
5319 }
5320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005321 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005322 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005323 success = false;
5324 } finally {
5325 if (data != null) {
5326 data.recycle();
5327 }
5328 if (reply != null) {
5329 reply.recycle();
5330 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005331 if (out != null) {
5332 try {
5333 out.close();
5334 } catch (IOException e) {
5335
5336 }
5337 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005338 }
5339
5340 return success;
5341 }
5342
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07005343 public void addWindowChangeListener(WindowChangeListener listener) {
5344 synchronized(mWindowMap) {
5345 mWindowChangeListeners.add(listener);
5346 }
5347 }
5348
5349 public void removeWindowChangeListener(WindowChangeListener listener) {
5350 synchronized(mWindowMap) {
5351 mWindowChangeListeners.remove(listener);
5352 }
5353 }
5354
5355 private void notifyWindowsChanged() {
5356 WindowChangeListener[] windowChangeListeners;
5357 synchronized(mWindowMap) {
5358 if(mWindowChangeListeners.isEmpty()) {
5359 return;
5360 }
5361 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5362 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5363 }
5364 int N = windowChangeListeners.length;
5365 for(int i = 0; i < N; i++) {
5366 windowChangeListeners[i].windowsChanged();
5367 }
5368 }
5369
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07005370 private void notifyFocusChanged() {
5371 WindowChangeListener[] windowChangeListeners;
5372 synchronized(mWindowMap) {
5373 if(mWindowChangeListeners.isEmpty()) {
5374 return;
5375 }
5376 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5377 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5378 }
5379 int N = windowChangeListeners.length;
5380 for(int i = 0; i < N; i++) {
5381 windowChangeListeners[i].focusChanged();
5382 }
5383 }
5384
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005385 private WindowState findWindow(int hashCode) {
5386 if (hashCode == -1) {
5387 return getFocusedWindow();
5388 }
5389
5390 synchronized (mWindowMap) {
Jeff Browne33348b2010-07-15 23:54:05 -07005391 final ArrayList<WindowState> windows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005392 final int count = windows.size();
5393
5394 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005395 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005396 if (System.identityHashCode(w) == hashCode) {
5397 return w;
5398 }
5399 }
5400 }
5401
5402 return null;
5403 }
5404
5405 /*
5406 * Instruct the Activity Manager to fetch the current configuration and broadcast
5407 * that to config-changed listeners if appropriate.
5408 */
5409 void sendNewConfiguration() {
5410 try {
5411 mActivityManager.updateConfiguration(null);
5412 } catch (RemoteException e) {
5413 }
5414 }
Romain Guy06882f82009-06-10 13:36:04 -07005415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005416 public Configuration computeNewConfiguration() {
5417 synchronized (mWindowMap) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07005418 return computeNewConfigurationLocked();
5419 }
5420 }
Romain Guy06882f82009-06-10 13:36:04 -07005421
Dianne Hackbornc485a602009-03-24 22:39:49 -07005422 Configuration computeNewConfigurationLocked() {
5423 Configuration config = new Configuration();
5424 if (!computeNewConfigurationLocked(config)) {
5425 return null;
5426 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07005427 return config;
5428 }
Romain Guy06882f82009-06-10 13:36:04 -07005429
Dianne Hackbornc485a602009-03-24 22:39:49 -07005430 boolean computeNewConfigurationLocked(Configuration config) {
5431 if (mDisplay == null) {
5432 return false;
5433 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005434
5435 mInputManager.getInputConfiguration(config);
Christopher Tateb696aee2010-04-02 19:08:30 -07005436
5437 // Use the effective "visual" dimensions based on current rotation
5438 final boolean rotated = (mRotation == Surface.ROTATION_90
5439 || mRotation == Surface.ROTATION_270);
5440 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
5441 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
5442
Dianne Hackbornc485a602009-03-24 22:39:49 -07005443 int orientation = Configuration.ORIENTATION_SQUARE;
5444 if (dw < dh) {
5445 orientation = Configuration.ORIENTATION_PORTRAIT;
5446 } else if (dw > dh) {
5447 orientation = Configuration.ORIENTATION_LANDSCAPE;
5448 }
5449 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005450
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005451 DisplayMetrics dm = new DisplayMetrics();
5452 mDisplay.getMetrics(dm);
5453 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
5454
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005455 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07005456 // Note we only do this once because at this point we don't
5457 // expect the screen to change in this way at runtime, and want
5458 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07005459 int longSize = dw;
5460 int shortSize = dh;
5461 if (longSize < shortSize) {
5462 int tmp = longSize;
5463 longSize = shortSize;
5464 shortSize = tmp;
5465 }
5466 longSize = (int)(longSize/dm.density);
5467 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005468
Dianne Hackborn723738c2009-06-25 19:48:04 -07005469 // These semi-magic numbers define our compatibility modes for
5470 // applications with different screens. Don't change unless you
5471 // make sure to test lots and lots of apps!
5472 if (longSize < 470) {
5473 // This is shorter than an HVGA normal density screen (which
5474 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005475 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5476 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005477 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07005478 // What size is this screen screen?
5479 if (longSize >= 800 && shortSize >= 600) {
5480 // SVGA or larger screens at medium density are the point
5481 // at which we consider it to be an extra large screen.
5482 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
Dianne Hackbornb51dc0f2010-10-21 15:34:47 -07005483 } else if (longSize >= 530 && shortSize >= 400) {
5484 // SVGA or larger screens at high density are the point
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005485 // at which we consider it to be a large screen.
5486 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5487 } else {
5488 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005489
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005490 // If this screen is wider than normal HVGA, or taller
5491 // than FWVGA, then for old apps we want to run in size
5492 // compatibility mode.
5493 if (shortSize > 321 || longSize > 570) {
5494 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5495 }
5496 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005497
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005498 // Is this a long screen?
5499 if (((longSize*3)/5) >= (shortSize-1)) {
5500 // Anything wider than WVGA (5:3) is considering to be long.
5501 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5502 } else {
5503 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5504 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07005505 }
5506 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005507 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005508
Dianne Hackbornc485a602009-03-24 22:39:49 -07005509 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5510 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5511 mPolicy.adjustConfigurationLw(config);
5512 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005513 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005514
5515 // -------------------------------------------------------------
5516 // Drag and drop
5517 // -------------------------------------------------------------
5518
5519 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
5520 boolean localOnly, int width, int height, Surface outSurface) {
5521 if (DEBUG_DRAG) {
5522 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
5523 + " local=" + localOnly + " win=" + window
5524 + " asbinder=" + window.asBinder());
5525 }
5526
5527 final int callerPid = Binder.getCallingPid();
5528 final long origId = Binder.clearCallingIdentity();
5529 IBinder token = null;
5530
5531 try {
5532 synchronized (mWindowMap) {
5533 try {
5534 // !!! TODO: fail if the given window does not currently have touch focus?
5535
5536 if (mDragState == null) {
5537 Surface surface = new Surface(session, callerPid, "drag surface", 0,
5538 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
5539 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07005540 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07005541 token = new Binder();
Chris Tate7b362e42010-11-04 16:02:52 -07005542 mDragState = new DragState(token, surface, localOnly, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005543 mDragState.mSurface = surface;
5544 mDragState.mLocalOnly = localOnly;
5545 token = mDragState.mToken = new Binder();
5546
5547 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07005548 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
5549 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005550 mH.sendMessageDelayed(msg, 5000);
5551 } else {
5552 Slog.w(TAG, "Drag already in progress");
5553 }
5554 } catch (Surface.OutOfResourcesException e) {
5555 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
5556 if (mDragState != null) {
5557 mDragState.reset();
5558 mDragState = null;
5559 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005560 }
5561 }
5562 } finally {
5563 Binder.restoreCallingIdentity(origId);
5564 }
5565
5566 return token;
5567 }
5568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005569 // -------------------------------------------------------------
5570 // Input Events and Focus Management
5571 // -------------------------------------------------------------
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005572
Jeff Brown349703e2010-06-22 01:27:15 -07005573 InputMonitor mInputMonitor = new InputMonitor();
5574
5575 /* Tracks the progress of input dispatch and ensures that input dispatch state
5576 * is kept in sync with changes in window focus, visibility, registration, and
5577 * other relevant Window Manager state transitions. */
5578 final class InputMonitor {
5579 // Current window with input focus for keys and other non-touch events. May be null.
5580 private WindowState mInputFocus;
5581
5582 // When true, prevents input dispatch from proceeding until set to false again.
5583 private boolean mInputDispatchFrozen;
5584
5585 // When true, input dispatch proceeds normally. Otherwise all events are dropped.
5586 private boolean mInputDispatchEnabled = true;
5587
5588 // Temporary list of windows information to provide to the input dispatcher.
5589 private InputWindowList mTempInputWindows = new InputWindowList();
5590
5591 // Temporary input application object to provide to the input dispatcher.
5592 private InputApplication mTempInputApplication = new InputApplication();
5593
5594 /* Notifies the window manager about a broken input channel.
5595 *
5596 * Called by the InputManager.
5597 */
5598 public void notifyInputChannelBroken(InputChannel inputChannel) {
5599 synchronized (mWindowMap) {
5600 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5601 if (windowState == null) {
5602 return; // irrelevant
5603 }
5604
5605 Slog.i(TAG, "WINDOW DIED " + windowState);
5606 removeWindowLocked(windowState.mSession, windowState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005607 }
5608 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005609
Jeff Brown519e0242010-09-15 15:18:56 -07005610 /* Notifies the window manager about an application that is not responding.
Jeff Brownb88102f2010-09-08 11:49:43 -07005611 * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
Jeff Brown349703e2010-06-22 01:27:15 -07005612 *
5613 * Called by the InputManager.
5614 */
Jeff Brown519e0242010-09-15 15:18:56 -07005615 public long notifyANR(Object token, InputChannel inputChannel) {
5616 AppWindowToken appWindowToken = null;
5617 if (inputChannel != null) {
5618 synchronized (mWindowMap) {
5619 WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
5620 if (windowState != null) {
5621 Slog.i(TAG, "Input event dispatching timed out sending to "
5622 + windowState.mAttrs.getTitle());
5623 appWindowToken = windowState.mAppToken;
5624 }
Jeff Brown349703e2010-06-22 01:27:15 -07005625 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005626 }
5627
Jeff Brown519e0242010-09-15 15:18:56 -07005628 if (appWindowToken == null && token != null) {
5629 appWindowToken = (AppWindowToken) token;
5630 Slog.i(TAG, "Input event dispatching timed out sending to application "
5631 + appWindowToken.stringName);
5632 }
Jeff Brown349703e2010-06-22 01:27:15 -07005633
Jeff Brown519e0242010-09-15 15:18:56 -07005634 if (appWindowToken != null && appWindowToken.appToken != null) {
Jeff Brown349703e2010-06-22 01:27:15 -07005635 try {
5636 // Notify the activity manager about the timeout and let it decide whether
5637 // to abort dispatching or keep waiting.
Jeff Brown519e0242010-09-15 15:18:56 -07005638 boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
Jeff Brown349703e2010-06-22 01:27:15 -07005639 if (! abort) {
5640 // The activity manager declined to abort dispatching.
5641 // Wait a bit longer and timeout again later.
Jeff Brown519e0242010-09-15 15:18:56 -07005642 return appWindowToken.inputDispatchingTimeoutNanos;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005643 }
Jeff Brown349703e2010-06-22 01:27:15 -07005644 } catch (RemoteException ex) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07005645 }
5646 }
Jeff Brownb88102f2010-09-08 11:49:43 -07005647 return 0; // abort dispatching
Jeff Brown7fbdc842010-06-17 20:52:56 -07005648 }
5649
Jeff Brown349703e2010-06-22 01:27:15 -07005650 private WindowState getWindowStateForInputChannel(InputChannel inputChannel) {
5651 synchronized (mWindowMap) {
5652 return getWindowStateForInputChannelLocked(inputChannel);
5653 }
5654 }
5655
5656 private WindowState getWindowStateForInputChannelLocked(InputChannel inputChannel) {
5657 int windowCount = mWindows.size();
5658 for (int i = 0; i < windowCount; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005659 WindowState windowState = mWindows.get(i);
Jeff Brown349703e2010-06-22 01:27:15 -07005660 if (windowState.mInputChannel == inputChannel) {
5661 return windowState;
5662 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005663 }
5664
Jeff Brown349703e2010-06-22 01:27:15 -07005665 return null;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005666 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005667
Chris Tatea32dcf72010-10-14 12:13:50 -07005668 private void addDragInputWindowLw(InputWindowList windowList) {
Christopher Tatea53146c2010-09-07 11:57:52 -07005669 final InputWindow inputWindow = windowList.add();
5670 inputWindow.inputChannel = mDragState.mServerChannel;
5671 inputWindow.name = "drag";
5672 inputWindow.layoutParamsFlags = 0;
5673 inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
5674 inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
5675 inputWindow.visible = true;
5676 inputWindow.canReceiveKeys = false;
5677 inputWindow.hasFocus = true;
5678 inputWindow.hasWallpaper = false;
5679 inputWindow.paused = false;
Chris Tatea32dcf72010-10-14 12:13:50 -07005680 inputWindow.layer = mDragState.getDragLayerLw();
Christopher Tatea53146c2010-09-07 11:57:52 -07005681 inputWindow.ownerPid = Process.myPid();
5682 inputWindow.ownerUid = Process.myUid();
5683
5684 // The drag window covers the entire display
5685 inputWindow.frameLeft = 0;
5686 inputWindow.frameTop = 0;
5687 inputWindow.frameRight = mDisplay.getWidth();
5688 inputWindow.frameBottom = mDisplay.getHeight();
Christopher Tate2c095f32010-10-04 14:13:40 -07005689
Christopher Tatea53146c2010-09-07 11:57:52 -07005690 inputWindow.visibleFrameLeft = inputWindow.frameLeft;
5691 inputWindow.visibleFrameTop = inputWindow.frameTop;
5692 inputWindow.visibleFrameRight = inputWindow.frameRight;
5693 inputWindow.visibleFrameBottom = inputWindow.frameBottom;
5694
5695 inputWindow.touchableAreaLeft = inputWindow.frameLeft;
5696 inputWindow.touchableAreaTop = inputWindow.frameTop;
5697 inputWindow.touchableAreaRight = inputWindow.frameRight;
5698 inputWindow.touchableAreaBottom = inputWindow.frameBottom;
5699 }
5700
Jeff Brown349703e2010-06-22 01:27:15 -07005701 /* Updates the cached window information provided to the input dispatcher. */
5702 public void updateInputWindowsLw() {
5703 // Populate the input window list with information about all of the windows that
5704 // could potentially receive input.
5705 // As an optimization, we could try to prune the list of windows but this turns
5706 // out to be difficult because only the native code knows for sure which window
5707 // currently has touch focus.
Jeff Browne33348b2010-07-15 23:54:05 -07005708 final ArrayList<WindowState> windows = mWindows;
Christopher Tatea53146c2010-09-07 11:57:52 -07005709
5710 // If there's a drag in flight, provide a pseudowindow to catch drag input
5711 final boolean inDrag = (mDragState != null);
5712 if (inDrag) {
5713 if (DEBUG_DRAG) {
5714 Log.d(TAG, "Inserting drag window");
5715 }
Chris Tatea32dcf72010-10-14 12:13:50 -07005716 addDragInputWindowLw(mTempInputWindows);
Christopher Tatea53146c2010-09-07 11:57:52 -07005717 }
5718
Jeff Brown7fbdc842010-06-17 20:52:56 -07005719 final int N = windows.size();
Jeff Brown349703e2010-06-22 01:27:15 -07005720 for (int i = N - 1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07005721 final WindowState child = windows.get(i);
Jeff Brownc5ed5912010-07-14 18:48:53 -07005722 if (child.mInputChannel == null || child.mRemoved) {
Jeff Brown349703e2010-06-22 01:27:15 -07005723 // Skip this window because it cannot possibly receive input.
Jeff Brown7fbdc842010-06-17 20:52:56 -07005724 continue;
5725 }
5726
Jeff Brown349703e2010-06-22 01:27:15 -07005727 final int flags = child.mAttrs.flags;
5728 final int type = child.mAttrs.type;
5729
5730 final boolean hasFocus = (child == mInputFocus);
5731 final boolean isVisible = child.isVisibleLw();
5732 final boolean hasWallpaper = (child == mWallpaperTarget)
5733 && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
Christopher Tatea53146c2010-09-07 11:57:52 -07005734
5735 // If there's a drag in progress and 'child' is a potential drop target,
5736 // make sure it's been told about the drag
5737 if (inDrag && isVisible) {
5738 mDragState.sendDragStartedIfNeededLw(child);
5739 }
5740
Jeff Brown349703e2010-06-22 01:27:15 -07005741 // Add a window to our list of input windows.
5742 final InputWindow inputWindow = mTempInputWindows.add();
5743 inputWindow.inputChannel = child.mInputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -07005744 inputWindow.name = child.toString();
Jeff Brown349703e2010-06-22 01:27:15 -07005745 inputWindow.layoutParamsFlags = flags;
5746 inputWindow.layoutParamsType = type;
5747 inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
5748 inputWindow.visible = isVisible;
Jeff Brown519e0242010-09-15 15:18:56 -07005749 inputWindow.canReceiveKeys = child.canReceiveKeys();
Jeff Brown349703e2010-06-22 01:27:15 -07005750 inputWindow.hasFocus = hasFocus;
5751 inputWindow.hasWallpaper = hasWallpaper;
5752 inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
Jeff Brown519e0242010-09-15 15:18:56 -07005753 inputWindow.layer = child.mLayer;
Jeff Brown349703e2010-06-22 01:27:15 -07005754 inputWindow.ownerPid = child.mSession.mPid;
5755 inputWindow.ownerUid = child.mSession.mUid;
5756
5757 final Rect frame = child.mFrame;
5758 inputWindow.frameLeft = frame.left;
5759 inputWindow.frameTop = frame.top;
Jeff Brown85a31762010-09-01 17:01:00 -07005760 inputWindow.frameRight = frame.right;
5761 inputWindow.frameBottom = frame.bottom;
5762
5763 final Rect visibleFrame = child.mVisibleFrame;
5764 inputWindow.visibleFrameLeft = visibleFrame.left;
5765 inputWindow.visibleFrameTop = visibleFrame.top;
5766 inputWindow.visibleFrameRight = visibleFrame.right;
5767 inputWindow.visibleFrameBottom = visibleFrame.bottom;
Jeff Brown349703e2010-06-22 01:27:15 -07005768
5769 switch (child.mTouchableInsets) {
5770 default:
5771 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
5772 inputWindow.touchableAreaLeft = frame.left;
5773 inputWindow.touchableAreaTop = frame.top;
5774 inputWindow.touchableAreaRight = frame.right;
5775 inputWindow.touchableAreaBottom = frame.bottom;
5776 break;
5777
5778 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
5779 Rect inset = child.mGivenContentInsets;
5780 inputWindow.touchableAreaLeft = frame.left + inset.left;
5781 inputWindow.touchableAreaTop = frame.top + inset.top;
5782 inputWindow.touchableAreaRight = frame.right - inset.right;
5783 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
5784 break;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005785 }
Jeff Brown349703e2010-06-22 01:27:15 -07005786
5787 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
5788 Rect inset = child.mGivenVisibleInsets;
5789 inputWindow.touchableAreaLeft = frame.left + inset.left;
5790 inputWindow.touchableAreaTop = frame.top + inset.top;
5791 inputWindow.touchableAreaRight = frame.right - inset.right;
5792 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005793 break;
5794 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005795 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005796 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005797
Jeff Brown349703e2010-06-22 01:27:15 -07005798 // Send windows to native code.
5799 mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005800
Jeff Brown349703e2010-06-22 01:27:15 -07005801 // Clear the list in preparation for the next round.
5802 // Also avoids keeping InputChannel objects referenced unnecessarily.
5803 mTempInputWindows.clear();
5804 }
5805
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005806 /* Notifies that the lid switch changed state. */
5807 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
5808 mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
5809 }
5810
Jeff Brown349703e2010-06-22 01:27:15 -07005811 /* Provides an opportunity for the window manager policy to intercept early key
5812 * processing as soon as the key has been read from the device. */
Jeff Brown4d396052010-10-29 21:50:21 -07005813 public int interceptKeyBeforeQueueing(long whenNanos, int action, int flags,
5814 int keyCode, int scanCode, int policyFlags, boolean isScreenOn) {
5815 return mPolicy.interceptKeyBeforeQueueing(whenNanos, action, flags,
5816 keyCode, scanCode, policyFlags, isScreenOn);
Jeff Brown349703e2010-06-22 01:27:15 -07005817 }
5818
5819 /* Provides an opportunity for the window manager policy to process a key before
5820 * ordinary dispatch. */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005821 public boolean interceptKeyBeforeDispatching(InputChannel focus,
Jeff Brown4d396052010-10-29 21:50:21 -07005822 int action, int flags, int keyCode, int scanCode, int metaState, int repeatCount,
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005823 int policyFlags) {
Jeff Brown349703e2010-06-22 01:27:15 -07005824 WindowState windowState = getWindowStateForInputChannel(focus);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005825 return mPolicy.interceptKeyBeforeDispatching(windowState, action, flags,
Jeff Brown4d396052010-10-29 21:50:21 -07005826 keyCode, scanCode, metaState, repeatCount, policyFlags);
Jeff Brown349703e2010-06-22 01:27:15 -07005827 }
5828
Jeff Brown3915bb82010-11-05 15:02:16 -07005829 /* Provides an opportunity for the window manager policy to process a key that
5830 * the application did not handle. */
5831 public boolean dispatchUnhandledKey(InputChannel focus,
5832 int action, int flags, int keyCode, int scanCode, int metaState, int repeatCount,
5833 int policyFlags) {
5834 WindowState windowState = getWindowStateForInputChannel(focus);
5835 return mPolicy.dispatchUnhandledKey(windowState, action, flags,
5836 keyCode, scanCode, metaState, repeatCount, policyFlags);
5837 }
5838
Jeff Brown349703e2010-06-22 01:27:15 -07005839 /* Called when the current input focus changes.
5840 * Layer assignment is assumed to be complete by the time this is called.
5841 */
5842 public void setInputFocusLw(WindowState newWindow) {
5843 if (DEBUG_INPUT) {
5844 Slog.d(TAG, "Input focus has changed to " + newWindow);
5845 }
5846
5847 if (newWindow != mInputFocus) {
5848 if (newWindow != null && newWindow.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07005849 // Displaying a window implicitly causes dispatching to be unpaused.
5850 // This is to protect against bugs if someone pauses dispatching but
5851 // forgets to resume.
5852 newWindow.mToken.paused = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005853 }
Jeff Brown349703e2010-06-22 01:27:15 -07005854
5855 mInputFocus = newWindow;
5856 updateInputWindowsLw();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005857 }
5858 }
5859
Jeff Brown349703e2010-06-22 01:27:15 -07005860 public void setFocusedAppLw(AppWindowToken newApp) {
5861 // Focused app has changed.
5862 if (newApp == null) {
5863 mInputManager.setFocusedApplication(null);
5864 } else {
5865 mTempInputApplication.name = newApp.toString();
5866 mTempInputApplication.dispatchingTimeoutNanos =
5867 newApp.inputDispatchingTimeoutNanos;
5868 mTempInputApplication.token = newApp;
5869
5870 mInputManager.setFocusedApplication(mTempInputApplication);
5871 }
5872 }
5873
Jeff Brown349703e2010-06-22 01:27:15 -07005874 public void pauseDispatchingLw(WindowToken window) {
5875 if (! window.paused) {
5876 if (DEBUG_INPUT) {
5877 Slog.v(TAG, "Pausing WindowToken " + window);
5878 }
5879
5880 window.paused = true;
5881 updateInputWindowsLw();
5882 }
5883 }
5884
5885 public void resumeDispatchingLw(WindowToken window) {
5886 if (window.paused) {
5887 if (DEBUG_INPUT) {
5888 Slog.v(TAG, "Resuming WindowToken " + window);
5889 }
5890
5891 window.paused = false;
5892 updateInputWindowsLw();
5893 }
5894 }
5895
5896 public void freezeInputDispatchingLw() {
5897 if (! mInputDispatchFrozen) {
5898 if (DEBUG_INPUT) {
5899 Slog.v(TAG, "Freezing input dispatching");
5900 }
5901
5902 mInputDispatchFrozen = true;
5903 updateInputDispatchModeLw();
5904 }
5905 }
5906
5907 public void thawInputDispatchingLw() {
5908 if (mInputDispatchFrozen) {
5909 if (DEBUG_INPUT) {
5910 Slog.v(TAG, "Thawing input dispatching");
5911 }
5912
5913 mInputDispatchFrozen = false;
5914 updateInputDispatchModeLw();
5915 }
5916 }
5917
5918 public void setEventDispatchingLw(boolean enabled) {
5919 if (mInputDispatchEnabled != enabled) {
5920 if (DEBUG_INPUT) {
5921 Slog.v(TAG, "Setting event dispatching to " + enabled);
5922 }
5923
5924 mInputDispatchEnabled = enabled;
5925 updateInputDispatchModeLw();
5926 }
5927 }
5928
5929 private void updateInputDispatchModeLw() {
5930 mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
5931 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005932 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005933
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005934 public void pauseKeyDispatching(IBinder _token) {
5935 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5936 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005937 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005938 }
5939
5940 synchronized (mWindowMap) {
5941 WindowToken token = mTokenMap.get(_token);
5942 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005943 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005944 }
5945 }
5946 }
5947
5948 public void resumeKeyDispatching(IBinder _token) {
5949 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5950 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005951 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005952 }
5953
5954 synchronized (mWindowMap) {
5955 WindowToken token = mTokenMap.get(_token);
5956 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005957 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005958 }
5959 }
5960 }
5961
5962 public void setEventDispatching(boolean enabled) {
5963 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5964 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005965 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005966 }
5967
5968 synchronized (mWindowMap) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005969 mInputMonitor.setEventDispatchingLw(enabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005970 }
5971 }
Romain Guy06882f82009-06-10 13:36:04 -07005972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005973 /**
5974 * Injects a keystroke event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005975 * Even when sync is false, this method may block while waiting for current
5976 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005977 *
5978 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005979 * {@link SystemClock#uptimeMillis()} as the timebase.)
5980 * @param sync If true, wait for the event to be completed before returning to the caller.
5981 * @return Returns true if event was dispatched, false if it was dropped for any reason
5982 */
5983 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
5984 long downTime = ev.getDownTime();
5985 long eventTime = ev.getEventTime();
5986
5987 int action = ev.getAction();
5988 int code = ev.getKeyCode();
5989 int repeatCount = ev.getRepeatCount();
5990 int metaState = ev.getMetaState();
5991 int deviceId = ev.getDeviceId();
5992 int scancode = ev.getScanCode();
Jeff Brownc5ed5912010-07-14 18:48:53 -07005993 int source = ev.getSource();
5994
5995 if (source == InputDevice.SOURCE_UNKNOWN) {
5996 source = InputDevice.SOURCE_KEYBOARD;
5997 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005998
5999 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
6000 if (downTime == 0) downTime = eventTime;
6001
6002 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
Jeff Brownc5ed5912010-07-14 18:48:53 -07006003 deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM, source);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006004
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006005 final int pid = Binder.getCallingPid();
6006 final int uid = Binder.getCallingUid();
6007 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006008
Jeff Brownbbda99d2010-07-28 15:48:59 -07006009 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6010 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6011 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6012 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006013
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006014 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006015 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006016 }
6017
6018 /**
6019 * Inject a pointer (touch) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006020 * Even when sync is false, this method may block while waiting for current
6021 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006022 *
6023 * @param ev A motion event describing the pointer (touch) action. (As noted in
6024 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006025 * {@link SystemClock#uptimeMillis()} as the timebase.)
6026 * @param sync If true, wait for the event to be completed before returning to the caller.
6027 * @return Returns true if event was dispatched, false if it was dropped for any reason
6028 */
6029 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006030 final int pid = Binder.getCallingPid();
6031 final int uid = Binder.getCallingUid();
6032 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006033
Jeff Brownc5ed5912010-07-14 18:48:53 -07006034 MotionEvent newEvent = MotionEvent.obtain(ev);
6035 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
6036 newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
6037 }
6038
Jeff Brownbbda99d2010-07-28 15:48:59 -07006039 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6040 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6041 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6042 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006043
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006044 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006045 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006046 }
Romain Guy06882f82009-06-10 13:36:04 -07006047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006048 /**
6049 * Inject a trackball (navigation device) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006050 * Even when sync is false, this method may block while waiting for current
6051 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006052 *
6053 * @param ev A motion event describing the trackball action. (As noted in
6054 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006055 * {@link SystemClock#uptimeMillis()} as the timebase.)
6056 * @param sync If true, wait for the event to be completed before returning to the caller.
6057 * @return Returns true if event was dispatched, false if it was dropped for any reason
6058 */
6059 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006060 final int pid = Binder.getCallingPid();
6061 final int uid = Binder.getCallingUid();
6062 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006063
Jeff Brownc5ed5912010-07-14 18:48:53 -07006064 MotionEvent newEvent = MotionEvent.obtain(ev);
6065 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
6066 newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
6067 }
6068
Jeff Brownbbda99d2010-07-28 15:48:59 -07006069 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6070 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6071 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6072 INJECTION_TIMEOUT_MILLIS);
6073
6074 Binder.restoreCallingIdentity(ident);
6075 return reportInjectionResult(result);
6076 }
6077
6078 /**
6079 * Inject an input event into the UI without waiting for dispatch to commence.
6080 * This variant is useful for fire-and-forget input event injection. It does not
6081 * block any longer than it takes to enqueue the input event.
6082 *
6083 * @param ev An input event. (Be sure to set the input source correctly.)
6084 * @return Returns true if event was dispatched, false if it was dropped for any reason
6085 */
6086 public boolean injectInputEventNoWait(InputEvent ev) {
6087 final int pid = Binder.getCallingPid();
6088 final int uid = Binder.getCallingUid();
6089 final long ident = Binder.clearCallingIdentity();
6090
6091 final int result = mInputManager.injectInputEvent(ev, pid, uid,
6092 InputManager.INPUT_EVENT_INJECTION_SYNC_NONE,
6093 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006094
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006095 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006096 return reportInjectionResult(result);
6097 }
6098
6099 private boolean reportInjectionResult(int result) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006100 switch (result) {
6101 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
6102 Slog.w(TAG, "Input event injection permission denied.");
6103 throw new SecurityException(
6104 "Injecting to another application requires INJECT_EVENTS permission");
6105 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
Christopher Tate09e85dc2010-08-02 11:54:41 -07006106 //Slog.v(TAG, "Input event injection succeeded.");
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006107 return true;
6108 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
6109 Slog.w(TAG, "Input event injection timed out.");
6110 return false;
6111 case InputManager.INPUT_EVENT_INJECTION_FAILED:
6112 default:
6113 Slog.w(TAG, "Input event injection failed.");
6114 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07006115 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006116 }
Romain Guy06882f82009-06-10 13:36:04 -07006117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006118 private WindowState getFocusedWindow() {
6119 synchronized (mWindowMap) {
6120 return getFocusedWindowLocked();
6121 }
6122 }
6123
6124 private WindowState getFocusedWindowLocked() {
6125 return mCurrentFocus;
6126 }
Romain Guy06882f82009-06-10 13:36:04 -07006127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006128 public boolean detectSafeMode() {
6129 mSafeMode = mPolicy.detectSafeMode();
6130 return mSafeMode;
6131 }
Romain Guy06882f82009-06-10 13:36:04 -07006132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006133 public void systemReady() {
Dianne Hackborn5132b372010-07-29 12:51:35 -07006134 synchronized(mWindowMap) {
6135 if (mDisplay != null) {
6136 throw new IllegalStateException("Display already initialized");
6137 }
6138 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
6139 mDisplay = wm.getDefaultDisplay();
6140 mInitialDisplayWidth = mDisplay.getWidth();
6141 mInitialDisplayHeight = mDisplay.getHeight();
6142 mInputManager.setDisplaySize(0, mInitialDisplayWidth, mInitialDisplayHeight);
6143 }
6144
6145 try {
6146 mActivityManager.updateConfiguration(null);
6147 } catch (RemoteException e) {
6148 }
Dianne Hackborn154db5f2010-07-29 19:15:19 -07006149
6150 mPolicy.systemReady();
Dianne Hackborn5132b372010-07-29 12:51:35 -07006151 }
6152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006153 // -------------------------------------------------------------
6154 // Client Session State
6155 // -------------------------------------------------------------
6156
6157 private final class Session extends IWindowSession.Stub
6158 implements IBinder.DeathRecipient {
6159 final IInputMethodClient mClient;
6160 final IInputContext mInputContext;
6161 final int mUid;
6162 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006163 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006164 SurfaceSession mSurfaceSession;
6165 int mNumWindow = 0;
6166 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07006167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006168 public Session(IInputMethodClient client, IInputContext inputContext) {
6169 mClient = client;
6170 mInputContext = inputContext;
6171 mUid = Binder.getCallingUid();
6172 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006173 StringBuilder sb = new StringBuilder();
6174 sb.append("Session{");
6175 sb.append(Integer.toHexString(System.identityHashCode(this)));
6176 sb.append(" uid ");
6177 sb.append(mUid);
6178 sb.append("}");
6179 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07006180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006181 synchronized (mWindowMap) {
6182 if (mInputMethodManager == null && mHaveInputMethods) {
6183 IBinder b = ServiceManager.getService(
6184 Context.INPUT_METHOD_SERVICE);
6185 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
6186 }
6187 }
6188 long ident = Binder.clearCallingIdentity();
6189 try {
6190 // Note: it is safe to call in to the input method manager
6191 // here because we are not holding our lock.
6192 if (mInputMethodManager != null) {
6193 mInputMethodManager.addClient(client, inputContext,
6194 mUid, mPid);
6195 } else {
6196 client.setUsingInputMethod(false);
6197 }
6198 client.asBinder().linkToDeath(this, 0);
6199 } catch (RemoteException e) {
6200 // The caller has died, so we can just forget about this.
6201 try {
6202 if (mInputMethodManager != null) {
6203 mInputMethodManager.removeClient(client);
6204 }
6205 } catch (RemoteException ee) {
6206 }
6207 } finally {
6208 Binder.restoreCallingIdentity(ident);
6209 }
6210 }
Romain Guy06882f82009-06-10 13:36:04 -07006211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006212 @Override
6213 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
6214 throws RemoteException {
6215 try {
6216 return super.onTransact(code, data, reply, flags);
6217 } catch (RuntimeException e) {
6218 // Log all 'real' exceptions thrown to the caller
6219 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006220 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006221 }
6222 throw e;
6223 }
6224 }
6225
6226 public void binderDied() {
6227 // Note: it is safe to call in to the input method manager
6228 // here because we are not holding our lock.
6229 try {
6230 if (mInputMethodManager != null) {
6231 mInputMethodManager.removeClient(mClient);
6232 }
6233 } catch (RemoteException e) {
6234 }
6235 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006236 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006237 mClientDead = true;
6238 killSessionLocked();
6239 }
6240 }
6241
6242 public int add(IWindow window, WindowManager.LayoutParams attrs,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006243 int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
6244 return addWindow(this, window, attrs, viewVisibility, outContentInsets,
6245 outInputChannel);
6246 }
6247
6248 public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006249 int viewVisibility, Rect outContentInsets) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006250 return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006251 }
Romain Guy06882f82009-06-10 13:36:04 -07006252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006253 public void remove(IWindow window) {
6254 removeWindow(this, window);
6255 }
Romain Guy06882f82009-06-10 13:36:04 -07006256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006257 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
6258 int requestedWidth, int requestedHeight, int viewFlags,
6259 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006260 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Dianne Hackbornf123e492010-09-24 11:16:23 -07006261 //Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
6262 int res = relayoutWindow(this, window, attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006263 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006264 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
Dianne Hackbornf123e492010-09-24 11:16:23 -07006265 //Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
6266 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006267 }
Romain Guy06882f82009-06-10 13:36:04 -07006268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006269 public void setTransparentRegion(IWindow window, Region region) {
6270 setTransparentRegionWindow(this, window, region);
6271 }
Romain Guy06882f82009-06-10 13:36:04 -07006272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006273 public void setInsets(IWindow window, int touchableInsets,
6274 Rect contentInsets, Rect visibleInsets) {
6275 setInsetsWindow(this, window, touchableInsets, contentInsets,
6276 visibleInsets);
6277 }
Romain Guy06882f82009-06-10 13:36:04 -07006278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006279 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
6280 getWindowDisplayFrame(this, window, outDisplayFrame);
6281 }
Romain Guy06882f82009-06-10 13:36:04 -07006282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006283 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006284 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006285 TAG, "IWindow finishDrawing called for " + window);
6286 finishDrawingWindow(this, window);
6287 }
6288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006289 public void setInTouchMode(boolean mode) {
6290 synchronized(mWindowMap) {
6291 mInTouchMode = mode;
6292 }
6293 }
6294
6295 public boolean getInTouchMode() {
6296 synchronized(mWindowMap) {
6297 return mInTouchMode;
6298 }
6299 }
6300
6301 public boolean performHapticFeedback(IWindow window, int effectId,
6302 boolean always) {
6303 synchronized(mWindowMap) {
6304 long ident = Binder.clearCallingIdentity();
6305 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07006306 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006307 windowForClientLocked(this, window, true),
6308 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006309 } finally {
6310 Binder.restoreCallingIdentity(ident);
6311 }
6312 }
6313 }
Romain Guy06882f82009-06-10 13:36:04 -07006314
Christopher Tatea53146c2010-09-07 11:57:52 -07006315 /* Drag/drop */
6316 public IBinder prepareDrag(IWindow window, boolean localOnly,
6317 int width, int height, Surface outSurface) {
6318 return prepareDragSurface(window, mSurfaceSession, localOnly,
6319 width, height, outSurface);
6320 }
6321
6322 public boolean performDrag(IWindow window, IBinder dragToken,
6323 float touchX, float touchY, float thumbCenterX, float thumbCenterY,
6324 ClipData data) {
6325 if (DEBUG_DRAG) {
6326 Slog.d(TAG, "perform drag: win=" + window + " data=" + data);
6327 }
6328
6329 synchronized (mWindowMap) {
6330 if (mDragState == null) {
6331 Slog.w(TAG, "No drag prepared");
6332 throw new IllegalStateException("performDrag() without prepareDrag()");
6333 }
6334
6335 if (dragToken != mDragState.mToken) {
6336 Slog.w(TAG, "Performing mismatched drag");
6337 throw new IllegalStateException("performDrag() does not match prepareDrag()");
6338 }
6339
6340 WindowState callingWin = windowForClientLocked(null, window, false);
6341 if (callingWin == null) {
6342 Slog.w(TAG, "Bad requesting window " + window);
6343 return false; // !!! TODO: throw here?
6344 }
6345
6346 // !!! TODO: if input is not still focused on the initiating window, fail
6347 // the drag initiation (e.g. an alarm window popped up just as the application
6348 // called performDrag()
6349
6350 mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
6351
Christopher Tate2c095f32010-10-04 14:13:40 -07006352 // !!! TODO: extract the current touch (x, y) in screen coordinates. That
6353 // will let us eliminate the (touchX,touchY) parameters from the API.
Christopher Tatea53146c2010-09-07 11:57:52 -07006354
Chris Tateb478f462010-10-15 16:02:26 -07006355 // !!! FIXME: put all this heavy stuff onto the mH looper, as well as
6356 // the actual drag event dispatch stuff in the dragstate
6357
Christopher Tatea53146c2010-09-07 11:57:52 -07006358 mDragState.register();
6359 mInputMonitor.updateInputWindowsLw();
Chris Tateef70a072010-10-22 19:10:34 -07006360 if (!mInputManager.transferTouchFocus(callingWin.mInputChannel,
6361 mDragState.mServerChannel)) {
6362 Slog.e(TAG, "Unable to transfer touch focus");
6363 mDragState.unregister();
6364 mDragState = null;
6365 mInputMonitor.updateInputWindowsLw();
6366 return false;
6367 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006368
6369 mDragState.mData = data;
Chris Tateb478f462010-10-15 16:02:26 -07006370 mDragState.mCurrentX = touchX;
6371 mDragState.mCurrentY = touchY;
Chris Tateb8203e92010-10-12 14:23:21 -07006372 mDragState.broadcastDragStartedLw(touchX, touchY);
Christopher Tatea53146c2010-09-07 11:57:52 -07006373
6374 // remember the thumb offsets for later
6375 mDragState.mThumbOffsetX = thumbCenterX;
6376 mDragState.mThumbOffsetY = thumbCenterY;
6377
6378 // Make the surface visible at the proper location
6379 final Surface surface = mDragState.mSurface;
Chris Tateb478f462010-10-15 16:02:26 -07006380 Surface.openTransaction();
Christopher Tatea53146c2010-09-07 11:57:52 -07006381 try {
6382 surface.setPosition((int)(touchX - thumbCenterX),
6383 (int)(touchY - thumbCenterY));
Chris Tateb478f462010-10-15 16:02:26 -07006384 surface.setAlpha(.7071f);
Chris Tatea32dcf72010-10-14 12:13:50 -07006385 surface.setLayer(mDragState.getDragLayerLw());
Christopher Tatea53146c2010-09-07 11:57:52 -07006386 surface.show();
6387 } finally {
Chris Tateb478f462010-10-15 16:02:26 -07006388 Surface.closeTransaction();
Christopher Tatea53146c2010-09-07 11:57:52 -07006389 }
6390 }
6391
6392 return true; // success!
6393 }
6394
Chris Tated4533f142010-10-19 15:15:08 -07006395 public void reportDropResult(IWindow window, boolean consumed) {
6396 IBinder token = window.asBinder();
6397 if (DEBUG_DRAG) {
6398 Slog.d(TAG, "Drop result=" + consumed + " reported by " + token);
6399 }
6400
6401 synchronized (mWindowMap) {
6402 if (mDragState.mToken != token) {
6403 Slog.w(TAG, "Invalid drop-result claim by " + window);
6404 throw new IllegalStateException("reportDropResult() by non-recipient");
6405 }
6406
6407 // The right window has responded, even if it's no longer around,
6408 // so be sure to halt the timeout even if the later WindowState
6409 // lookup fails.
6410 mH.removeMessages(H.DRAG_END_TIMEOUT, window.asBinder());
6411
6412 WindowState callingWin = windowForClientLocked(null, window, false);
6413 if (callingWin == null) {
6414 Slog.w(TAG, "Bad result-reporting window " + window);
6415 return; // !!! TODO: throw here?
6416 }
6417
6418 mDragState.mDragResult = consumed;
6419 mDragState.endDragLw();
6420 }
6421 }
6422
Christopher Tatea53146c2010-09-07 11:57:52 -07006423 public void dragRecipientEntered(IWindow window) {
6424 if (DEBUG_DRAG) {
Chris Tated4533f142010-10-19 15:15:08 -07006425 Slog.d(TAG, "Drag into new candidate view @ " + window.asBinder());
Christopher Tatea53146c2010-09-07 11:57:52 -07006426 }
6427 }
6428
6429 public void dragRecipientExited(IWindow window) {
6430 if (DEBUG_DRAG) {
Chris Tated4533f142010-10-19 15:15:08 -07006431 Slog.d(TAG, "Drag from old candidate view @ " + window.asBinder());
Christopher Tatea53146c2010-09-07 11:57:52 -07006432 }
6433 }
6434
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006435 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006436 synchronized(mWindowMap) {
6437 long ident = Binder.clearCallingIdentity();
6438 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006439 setWindowWallpaperPositionLocked(
6440 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006441 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006442 } finally {
6443 Binder.restoreCallingIdentity(ident);
6444 }
6445 }
6446 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006447
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006448 public void wallpaperOffsetsComplete(IBinder window) {
6449 WindowManagerService.this.wallpaperOffsetsComplete(window);
6450 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006451
Dianne Hackborn75804932009-10-20 20:15:20 -07006452 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
6453 int z, Bundle extras, boolean sync) {
6454 synchronized(mWindowMap) {
6455 long ident = Binder.clearCallingIdentity();
6456 try {
6457 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006458 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07006459 action, x, y, z, extras, sync);
6460 } finally {
6461 Binder.restoreCallingIdentity(ident);
6462 }
6463 }
6464 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006465
Dianne Hackborn75804932009-10-20 20:15:20 -07006466 public void wallpaperCommandComplete(IBinder window, Bundle result) {
6467 WindowManagerService.this.wallpaperCommandComplete(window, result);
6468 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006470 void windowAddedLocked() {
6471 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006472 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006473 TAG, "First window added to " + this + ", creating SurfaceSession");
6474 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006475 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006476 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006477 mSessions.add(this);
6478 }
6479 mNumWindow++;
6480 }
6481
6482 void windowRemovedLocked() {
6483 mNumWindow--;
6484 killSessionLocked();
6485 }
Romain Guy06882f82009-06-10 13:36:04 -07006486
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006487 void killSessionLocked() {
6488 if (mNumWindow <= 0 && mClientDead) {
6489 mSessions.remove(this);
6490 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006491 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006492 TAG, "Last window removed from " + this
6493 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006494 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006495 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006496 try {
6497 mSurfaceSession.kill();
6498 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006499 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006500 + mSurfaceSession + " in session " + this
6501 + ": " + e.toString());
6502 }
6503 mSurfaceSession = null;
6504 }
6505 }
6506 }
Romain Guy06882f82009-06-10 13:36:04 -07006507
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006508 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006509 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
6510 pw.print(" mClientDead="); pw.print(mClientDead);
6511 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006512 }
6513
6514 @Override
6515 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006516 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006517 }
6518 }
6519
6520 // -------------------------------------------------------------
6521 // Client Window State
6522 // -------------------------------------------------------------
6523
6524 private final class WindowState implements WindowManagerPolicy.WindowState {
6525 final Session mSession;
6526 final IWindow mClient;
6527 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07006528 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006529 AppWindowToken mAppToken;
6530 AppWindowToken mTargetAppToken;
6531 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
6532 final DeathRecipient mDeathRecipient;
6533 final WindowState mAttachedWindow;
Jeff Browne33348b2010-07-15 23:54:05 -07006534 final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006535 final int mBaseLayer;
6536 final int mSubLayer;
6537 final boolean mLayoutAttached;
6538 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006539 final boolean mIsWallpaper;
6540 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006541 int mViewVisibility;
6542 boolean mPolicyVisibility = true;
6543 boolean mPolicyVisibilityAfterAnim = true;
6544 boolean mAppFreezing;
6545 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006546 boolean mReportDestroySurface;
6547 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006548 boolean mAttachedHidden; // is our parent window hidden?
6549 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006550 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006551 int mRequestedWidth;
6552 int mRequestedHeight;
6553 int mLastRequestedWidth;
6554 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006555 int mLayer;
6556 int mAnimLayer;
6557 int mLastLayer;
6558 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07006559 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07006560 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006561
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006562 int mLayoutSeq = -1;
6563
6564 Configuration mConfiguration = null;
6565
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006566 // Actual frame shown on-screen (may be modified by animation)
6567 final Rect mShownFrame = new Rect();
6568 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006569
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006570 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08006571 * Set when we have changed the size of the surface, to know that
6572 * we must tell them application to resize (and thus redraw itself).
6573 */
6574 boolean mSurfaceResized;
6575
6576 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006577 * Insets that determine the actually visible area
6578 */
6579 final Rect mVisibleInsets = new Rect();
6580 final Rect mLastVisibleInsets = new Rect();
6581 boolean mVisibleInsetsChanged;
6582
6583 /**
6584 * Insets that are covered by system windows
6585 */
6586 final Rect mContentInsets = new Rect();
6587 final Rect mLastContentInsets = new Rect();
6588 boolean mContentInsetsChanged;
6589
6590 /**
6591 * Set to true if we are waiting for this window to receive its
6592 * given internal insets before laying out other windows based on it.
6593 */
6594 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07006595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006596 /**
6597 * These are the content insets that were given during layout for
6598 * this window, to be applied to windows behind it.
6599 */
6600 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006602 /**
6603 * These are the visible insets that were given during layout for
6604 * this window, to be applied to windows behind it.
6605 */
6606 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006608 /**
6609 * Flag indicating whether the touchable region should be adjusted by
6610 * the visible insets; if false the area outside the visible insets is
6611 * NOT touchable, so we must use those to adjust the frame during hit
6612 * tests.
6613 */
6614 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07006615
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006616 // Current transformation being applied.
6617 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
6618 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
6619 float mHScale=1, mVScale=1;
6620 float mLastHScale=1, mLastVScale=1;
6621 final Matrix mTmpMatrix = new Matrix();
6622
6623 // "Real" frame that the application sees.
6624 final Rect mFrame = new Rect();
6625 final Rect mLastFrame = new Rect();
6626
6627 final Rect mContainingFrame = new Rect();
6628 final Rect mDisplayFrame = new Rect();
6629 final Rect mContentFrame = new Rect();
6630 final Rect mVisibleFrame = new Rect();
6631
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006632 boolean mContentChanged;
6633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006634 float mShownAlpha = 1;
6635 float mAlpha = 1;
6636 float mLastAlpha = 1;
6637
6638 // Set to true if, when the window gets displayed, it should perform
6639 // an enter animation.
6640 boolean mEnterAnimationPending;
6641
6642 // Currently running animation.
6643 boolean mAnimating;
6644 boolean mLocalAnimating;
6645 Animation mAnimation;
6646 boolean mAnimationIsEntrance;
6647 boolean mHasTransformation;
6648 boolean mHasLocalTransformation;
6649 final Transformation mTransformation = new Transformation();
6650
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006651 // If a window showing a wallpaper: the requested offset for the
6652 // wallpaper; if a wallpaper window: the currently applied offset.
6653 float mWallpaperX = -1;
6654 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006655
6656 // If a window showing a wallpaper: what fraction of the offset
6657 // range corresponds to a full virtual screen.
6658 float mWallpaperXStep = -1;
6659 float mWallpaperYStep = -1;
6660
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006661 // Wallpaper windows: pixels offset based on above variables.
6662 int mXOffset;
6663 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006665 // This is set after IWindowSession.relayout() has been called at
6666 // least once for the window. It allows us to detect the situation
6667 // where we don't yet have a surface, but should have one soon, so
6668 // we can give the window focus before waiting for the relayout.
6669 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07006670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006671 // This is set after the Surface has been created but before the
6672 // window has been drawn. During this time the surface is hidden.
6673 boolean mDrawPending;
6674
6675 // This is set after the window has finished drawing for the first
6676 // time but before its surface is shown. The surface will be
6677 // displayed when the next layout is run.
6678 boolean mCommitDrawPending;
6679
6680 // This is set during the time after the window's drawing has been
6681 // committed, and before its surface is actually shown. It is used
6682 // to delay showing the surface until all windows in a token are ready
6683 // to be shown.
6684 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07006685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006686 // Set when the window has been shown in the screen the first time.
6687 boolean mHasDrawn;
6688
6689 // Currently running an exit animation?
6690 boolean mExiting;
6691
6692 // Currently on the mDestroySurface list?
6693 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07006694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006695 // Completely remove from window manager after exit animation?
6696 boolean mRemoveOnExit;
6697
6698 // Set when the orientation is changing and this window has not yet
6699 // been updated for the new orientation.
6700 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07006701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006702 // Is this window now (or just being) removed?
6703 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07006704
Dianne Hackborn16064f92010-03-25 00:47:24 -07006705 // For debugging, this is the last information given to the surface flinger.
6706 boolean mSurfaceShown;
6707 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
6708 int mSurfaceLayer;
6709 float mSurfaceAlpha;
6710
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006711 // Input channel
6712 InputChannel mInputChannel;
6713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006714 WindowState(Session s, IWindow c, WindowToken token,
6715 WindowState attachedWindow, WindowManager.LayoutParams a,
6716 int viewVisibility) {
6717 mSession = s;
6718 mClient = c;
6719 mToken = token;
6720 mAttrs.copyFrom(a);
6721 mViewVisibility = viewVisibility;
6722 DeathRecipient deathRecipient = new DeathRecipient();
6723 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006724 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006725 TAG, "Window " + this + " client=" + c.asBinder()
6726 + " token=" + token + " (" + mAttrs.token + ")");
6727 try {
6728 c.asBinder().linkToDeath(deathRecipient, 0);
6729 } catch (RemoteException e) {
6730 mDeathRecipient = null;
6731 mAttachedWindow = null;
6732 mLayoutAttached = false;
6733 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006734 mIsWallpaper = false;
6735 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006736 mBaseLayer = 0;
6737 mSubLayer = 0;
6738 return;
6739 }
6740 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07006741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006742 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
6743 mAttrs.type <= LAST_SUB_WINDOW)) {
6744 // The multiplier here is to reserve space for multiple
6745 // windows in the same type layer.
6746 mBaseLayer = mPolicy.windowTypeToLayerLw(
6747 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
6748 + TYPE_LAYER_OFFSET;
6749 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
6750 mAttachedWindow = attachedWindow;
6751 mAttachedWindow.mChildWindows.add(this);
6752 mLayoutAttached = mAttrs.type !=
6753 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
6754 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
6755 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006756 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
6757 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006758 } else {
6759 // The multiplier here is to reserve space for multiple
6760 // windows in the same type layer.
6761 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
6762 * TYPE_LAYER_MULTIPLIER
6763 + TYPE_LAYER_OFFSET;
6764 mSubLayer = 0;
6765 mAttachedWindow = null;
6766 mLayoutAttached = false;
6767 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
6768 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006769 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
6770 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006771 }
6772
6773 WindowState appWin = this;
6774 while (appWin.mAttachedWindow != null) {
6775 appWin = mAttachedWindow;
6776 }
6777 WindowToken appToken = appWin.mToken;
6778 while (appToken.appWindowToken == null) {
6779 WindowToken parent = mTokenMap.get(appToken.token);
6780 if (parent == null || appToken == parent) {
6781 break;
6782 }
6783 appToken = parent;
6784 }
The Android Open Source Project10592532009-03-18 17:39:46 -07006785 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006786 mAppToken = appToken.appWindowToken;
6787
6788 mSurface = null;
6789 mRequestedWidth = 0;
6790 mRequestedHeight = 0;
6791 mLastRequestedWidth = 0;
6792 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006793 mXOffset = 0;
6794 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006795 mLayer = 0;
6796 mAnimLayer = 0;
6797 mLastLayer = 0;
6798 }
6799
6800 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006801 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006802 TAG, "Attaching " + this + " token=" + mToken
6803 + ", list=" + mToken.windows);
6804 mSession.windowAddedLocked();
6805 }
6806
6807 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
6808 mHaveFrame = true;
6809
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006810 final Rect container = mContainingFrame;
6811 container.set(pf);
6812
6813 final Rect display = mDisplayFrame;
6814 display.set(df);
6815
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07006816 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006817 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07006818 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
6819 display.intersect(mCompatibleScreenFrame);
6820 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006821 }
6822
6823 final int pw = container.right - container.left;
6824 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006825
6826 int w,h;
6827 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
6828 w = mAttrs.width < 0 ? pw : mAttrs.width;
6829 h = mAttrs.height< 0 ? ph : mAttrs.height;
6830 } else {
Romain Guy980a9382010-01-08 15:06:28 -08006831 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
6832 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006833 }
Romain Guy06882f82009-06-10 13:36:04 -07006834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006835 final Rect content = mContentFrame;
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006836 mContentChanged |= !content.equals(cf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006837 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07006838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006839 final Rect visible = mVisibleFrame;
6840 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07006841
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006842 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07006843 final int fw = frame.width();
6844 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07006845
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006846 //System.out.println("In: w=" + w + " h=" + h + " container=" +
6847 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
6848
6849 Gravity.apply(mAttrs.gravity, w, h, container,
6850 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
6851 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
6852
6853 //System.out.println("Out: " + mFrame);
6854
6855 // Now make sure the window fits in the overall display.
6856 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006857
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006858 // Make sure the content and visible frames are inside of the
6859 // final window frame.
6860 if (content.left < frame.left) content.left = frame.left;
6861 if (content.top < frame.top) content.top = frame.top;
6862 if (content.right > frame.right) content.right = frame.right;
6863 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
6864 if (visible.left < frame.left) visible.left = frame.left;
6865 if (visible.top < frame.top) visible.top = frame.top;
6866 if (visible.right > frame.right) visible.right = frame.right;
6867 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006868
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006869 final Rect contentInsets = mContentInsets;
6870 contentInsets.left = content.left-frame.left;
6871 contentInsets.top = content.top-frame.top;
6872 contentInsets.right = frame.right-content.right;
6873 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006874
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006875 final Rect visibleInsets = mVisibleInsets;
6876 visibleInsets.left = visible.left-frame.left;
6877 visibleInsets.top = visible.top-frame.top;
6878 visibleInsets.right = frame.right-visible.right;
6879 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07006880
Dianne Hackborn284ac932009-08-28 10:34:25 -07006881 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
6882 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006883 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07006884 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006886 if (localLOGV) {
6887 //if ("com.google.android.youtube".equals(mAttrs.packageName)
6888 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006889 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006890 + mRequestedWidth + ", mRequestedheight="
6891 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
6892 + "): frame=" + mFrame.toShortString()
6893 + " ci=" + contentInsets.toShortString()
6894 + " vi=" + visibleInsets.toShortString());
6895 //}
6896 }
6897 }
Romain Guy06882f82009-06-10 13:36:04 -07006898
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006899 public Rect getFrameLw() {
6900 return mFrame;
6901 }
6902
6903 public Rect getShownFrameLw() {
6904 return mShownFrame;
6905 }
6906
6907 public Rect getDisplayFrameLw() {
6908 return mDisplayFrame;
6909 }
6910
6911 public Rect getContentFrameLw() {
6912 return mContentFrame;
6913 }
6914
6915 public Rect getVisibleFrameLw() {
6916 return mVisibleFrame;
6917 }
6918
6919 public boolean getGivenInsetsPendingLw() {
6920 return mGivenInsetsPending;
6921 }
6922
6923 public Rect getGivenContentInsetsLw() {
6924 return mGivenContentInsets;
6925 }
Romain Guy06882f82009-06-10 13:36:04 -07006926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006927 public Rect getGivenVisibleInsetsLw() {
6928 return mGivenVisibleInsets;
6929 }
Romain Guy06882f82009-06-10 13:36:04 -07006930
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006931 public WindowManager.LayoutParams getAttrs() {
6932 return mAttrs;
6933 }
6934
6935 public int getSurfaceLayer() {
6936 return mLayer;
6937 }
Romain Guy06882f82009-06-10 13:36:04 -07006938
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006939 public IApplicationToken getAppToken() {
6940 return mAppToken != null ? mAppToken.appToken : null;
6941 }
Jeff Brown349703e2010-06-22 01:27:15 -07006942
6943 public long getInputDispatchingTimeoutNanos() {
6944 return mAppToken != null
6945 ? mAppToken.inputDispatchingTimeoutNanos
6946 : DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
6947 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006948
6949 public boolean hasAppShownWindows() {
6950 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
6951 }
6952
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006953 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006954 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006955 TAG, "Setting animation in " + this + ": " + anim);
6956 mAnimating = false;
6957 mLocalAnimating = false;
6958 mAnimation = anim;
6959 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
6960 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
6961 }
6962
6963 public void clearAnimation() {
6964 if (mAnimation != null) {
6965 mAnimating = true;
6966 mLocalAnimating = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07006967 mAnimation.cancel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006968 mAnimation = null;
6969 }
6970 }
Romain Guy06882f82009-06-10 13:36:04 -07006971
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006972 Surface createSurfaceLocked() {
6973 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006974 mReportDestroySurface = false;
6975 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006976 mDrawPending = true;
6977 mCommitDrawPending = false;
6978 mReadyToShow = false;
6979 if (mAppToken != null) {
6980 mAppToken.allDrawn = false;
6981 }
6982
6983 int flags = 0;
Mathias Agopian317a6282009-08-13 17:29:02 -07006984 if (mAttrs.memoryType == MEMORY_TYPE_PUSH_BUFFERS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006985 flags |= Surface.PUSH_BUFFERS;
6986 }
6987
6988 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
6989 flags |= Surface.SECURE;
6990 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006991 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006992 TAG, "Creating surface in session "
6993 + mSession.mSurfaceSession + " window " + this
6994 + " w=" + mFrame.width()
6995 + " h=" + mFrame.height() + " format="
6996 + mAttrs.format + " flags=" + flags);
6997
6998 int w = mFrame.width();
6999 int h = mFrame.height();
7000 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
7001 // for a scaled surface, we always want the requested
7002 // size.
7003 w = mRequestedWidth;
7004 h = mRequestedHeight;
7005 }
7006
Romain Guy9825ec62009-10-01 00:58:09 -07007007 // Something is wrong and SurfaceFlinger will not like this,
7008 // try to revert to sane values
7009 if (w <= 0) w = 1;
7010 if (h <= 0) h = 1;
7011
Dianne Hackborn16064f92010-03-25 00:47:24 -07007012 mSurfaceShown = false;
7013 mSurfaceLayer = 0;
7014 mSurfaceAlpha = 1;
7015 mSurfaceX = 0;
7016 mSurfaceY = 0;
7017 mSurfaceW = w;
7018 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007019 try {
Romain Guyd10cd572010-10-10 13:33:22 -07007020 final boolean isHwAccelerated = (mAttrs.flags &
7021 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
7022 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format;
7023 if (isHwAccelerated && mAttrs.format == PixelFormat.OPAQUE) {
7024 flags |= Surface.OPAQUE;
7025 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007026 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07007027 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08007028 mAttrs.getTitle().toString(),
Romain Guyd10cd572010-10-10 13:33:22 -07007029 0, w, h, format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007030 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007031 + mSurface + " IN SESSION "
7032 + mSession.mSurfaceSession
7033 + ": pid=" + mSession.mPid + " format="
7034 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007035 + Integer.toHexString(flags)
7036 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007037 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007038 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007039 reclaimSomeSurfaceMemoryLocked(this, "create");
7040 return null;
7041 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007042 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007043 return null;
7044 }
Romain Guy06882f82009-06-10 13:36:04 -07007045
Joe Onorato8a9b2202010-02-26 18:56:32 -08007046 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007047 TAG, "Got surface: " + mSurface
7048 + ", set left=" + mFrame.left + " top=" + mFrame.top
7049 + ", animLayer=" + mAnimLayer);
7050 if (SHOW_TRANSACTIONS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007051 Slog.i(TAG, ">>> OPEN TRANSACTION");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007052 if (SHOW_TRANSACTIONS) logSurface(this,
7053 "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
7054 mFrame.width() + "x" + mFrame.height() + "), layer=" +
7055 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007056 }
7057 Surface.openTransaction();
7058 try {
7059 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07007060 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07007061 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07007062 mSurface.setPosition(mSurfaceX, mSurfaceY);
7063 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007064 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007065 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007066 mSurface.hide();
7067 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007068 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007069 mSurface.setFlags(Surface.SURFACE_DITHER,
7070 Surface.SURFACE_DITHER);
7071 }
7072 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007073 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007074 reclaimSomeSurfaceMemoryLocked(this, "create-init");
7075 }
7076 mLastHidden = true;
7077 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007078 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007079 Surface.closeTransaction();
7080 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007081 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007082 TAG, "Created surface " + this);
7083 }
7084 return mSurface;
7085 }
Romain Guy06882f82009-06-10 13:36:04 -07007086
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007087 void destroySurfaceLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007088 if (mAppToken != null && this == mAppToken.startingWindow) {
7089 mAppToken.startingDisplayed = false;
7090 }
Romain Guy06882f82009-06-10 13:36:04 -07007091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007092 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007093 mDrawPending = false;
7094 mCommitDrawPending = false;
7095 mReadyToShow = false;
7096
7097 int i = mChildWindows.size();
7098 while (i > 0) {
7099 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007100 WindowState c = mChildWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007101 c.mAttachedHidden = true;
7102 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007103
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007104 if (mReportDestroySurface) {
7105 mReportDestroySurface = false;
7106 mSurfacePendingDestroy = true;
7107 try {
7108 mClient.dispatchGetNewSurface();
7109 // We'll really destroy on the next time around.
7110 return;
7111 } catch (RemoteException e) {
7112 }
7113 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007115 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007116 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007117 RuntimeException e = null;
7118 if (!HIDE_STACK_CRAWLS) {
7119 e = new RuntimeException();
7120 e.fillInStackTrace();
7121 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007122 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007123 + mSurface + ", session " + mSession, e);
7124 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007125 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007126 RuntimeException e = null;
7127 if (!HIDE_STACK_CRAWLS) {
7128 e = new RuntimeException();
7129 e.fillInStackTrace();
7130 }
7131 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007132 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007133 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007134 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007135 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007136 + " surface " + mSurface + " session " + mSession
7137 + ": " + e.toString());
7138 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007139
Dianne Hackborn16064f92010-03-25 00:47:24 -07007140 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007141 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007142 }
7143 }
7144
7145 boolean finishDrawingLocked() {
7146 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007147 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007148 TAG, "finishDrawingLocked: " + mSurface);
7149 mCommitDrawPending = true;
7150 mDrawPending = false;
7151 return true;
7152 }
7153 return false;
7154 }
7155
7156 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007157 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007158 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007159 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007160 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007161 }
7162 mCommitDrawPending = false;
7163 mReadyToShow = true;
7164 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
7165 final AppWindowToken atoken = mAppToken;
7166 if (atoken == null || atoken.allDrawn || starting) {
7167 performShowLocked();
7168 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007169 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007170 }
7171
7172 // This must be called while inside a transaction.
7173 boolean performShowLocked() {
7174 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007175 RuntimeException e = null;
7176 if (!HIDE_STACK_CRAWLS) {
7177 e = new RuntimeException();
7178 e.fillInStackTrace();
7179 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007180 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007181 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
7182 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
7183 }
7184 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007185 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
7186 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007187 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007188 + " during animation: policyVis=" + mPolicyVisibility
7189 + " attHidden=" + mAttachedHidden
7190 + " tok.hiddenRequested="
7191 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07007192 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007193 + (mAppToken != null ? mAppToken.hidden : false)
7194 + " animating=" + mAnimating
7195 + " tok animating="
7196 + (mAppToken != null ? mAppToken.animating : false));
7197 if (!showSurfaceRobustlyLocked(this)) {
7198 return false;
7199 }
7200 mLastAlpha = -1;
7201 mHasDrawn = true;
7202 mLastHidden = false;
7203 mReadyToShow = false;
7204 enableScreenIfNeededLocked();
7205
7206 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07007207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007208 int i = mChildWindows.size();
7209 while (i > 0) {
7210 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007211 WindowState c = mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007212 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007213 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007214 if (c.mSurface != null) {
7215 c.performShowLocked();
7216 // It hadn't been shown, which means layout not
7217 // performed on it, so now we want to make sure to
7218 // do a layout. If called from within the transaction
7219 // loop, this will cause it to restart with a new
7220 // layout.
7221 mLayoutNeeded = true;
7222 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007223 }
7224 }
Romain Guy06882f82009-06-10 13:36:04 -07007225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007226 if (mAttrs.type != TYPE_APPLICATION_STARTING
7227 && mAppToken != null) {
7228 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007229
Dianne Hackborn248b1882009-09-16 16:46:44 -07007230 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007231 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007232 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007233 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07007234 // If this initial window is animating, stop it -- we
7235 // will do an animation to reveal it from behind the
7236 // starting window, so there is no need for it to also
7237 // be doing its own stuff.
7238 if (mAnimation != null) {
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007239 mAnimation.cancel();
Dianne Hackborn248b1882009-09-16 16:46:44 -07007240 mAnimation = null;
7241 // Make sure we clean up the animation.
7242 mAnimating = true;
7243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007244 mFinishedStarting.add(mAppToken);
7245 mH.sendEmptyMessage(H.FINISHED_STARTING);
7246 }
7247 mAppToken.updateReportedVisibilityLocked();
7248 }
7249 }
7250 return true;
7251 }
Romain Guy06882f82009-06-10 13:36:04 -07007252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007253 // This must be called while inside a transaction. Returns true if
7254 // there is more animation to run.
7255 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007256 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007257 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07007258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007259 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
7260 mHasTransformation = true;
7261 mHasLocalTransformation = true;
7262 if (!mLocalAnimating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007263 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007264 TAG, "Starting animation in " + this +
7265 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
7266 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
7267 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
7268 mAnimation.setStartTime(currentTime);
7269 mLocalAnimating = true;
7270 mAnimating = true;
7271 }
7272 mTransformation.clear();
7273 final boolean more = mAnimation.getTransformation(
7274 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007275 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007276 TAG, "Stepped animation in " + this +
7277 ": more=" + more + ", xform=" + mTransformation);
7278 if (more) {
7279 // we're not done!
7280 return true;
7281 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007282 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007283 TAG, "Finished animation in " + this +
7284 " @ " + currentTime);
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007285
7286 if (mAnimation != null) {
7287 mAnimation.cancel();
7288 mAnimation = null;
7289 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007290 //WindowManagerService.this.dump();
7291 }
7292 mHasLocalTransformation = false;
7293 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007294 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007295 // When our app token is animating, we kind-of pretend like
7296 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
7297 // part of this check means that we will only do this if
7298 // our window is not currently exiting, or it is not
7299 // locally animating itself. The idea being that one that
7300 // is exiting and doing a local animation should be removed
7301 // once that animation is done.
7302 mAnimating = true;
7303 mHasTransformation = true;
7304 mTransformation.clear();
7305 return false;
7306 } else if (mHasTransformation) {
7307 // Little trick to get through the path below to act like
7308 // we have finished an animation.
7309 mAnimating = true;
7310 } else if (isAnimating()) {
7311 mAnimating = true;
7312 }
7313 } else if (mAnimation != null) {
7314 // If the display is frozen, and there is a pending animation,
7315 // clear it and make sure we run the cleanup code.
7316 mAnimating = true;
7317 mLocalAnimating = true;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007318 mAnimation.cancel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007319 mAnimation = null;
7320 }
Romain Guy06882f82009-06-10 13:36:04 -07007321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007322 if (!mAnimating && !mLocalAnimating) {
7323 return false;
7324 }
7325
Joe Onorato8a9b2202010-02-26 18:56:32 -08007326 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007327 TAG, "Animation done in " + this + ": exiting=" + mExiting
7328 + ", reportedVisible="
7329 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07007330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007331 mAnimating = false;
7332 mLocalAnimating = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007333 if (mAnimation != null) {
7334 mAnimation.cancel();
7335 mAnimation = null;
7336 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007337 mAnimLayer = mLayer;
7338 if (mIsImWindow) {
7339 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007340 } else if (mIsWallpaper) {
7341 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007342 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007343 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007344 + " anim layer: " + mAnimLayer);
7345 mHasTransformation = false;
7346 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007347 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
7348 if (DEBUG_VISIBILITY) {
7349 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
7350 + mPolicyVisibilityAfterAnim);
7351 }
7352 mPolicyVisibility = mPolicyVisibilityAfterAnim;
7353 if (!mPolicyVisibility) {
7354 if (mCurrentFocus == this) {
7355 mFocusMayChange = true;
7356 }
7357 // Window is no longer visible -- make sure if we were waiting
7358 // for it to be displayed before enabling the display, that
7359 // we allow the display to be enabled now.
7360 enableScreenIfNeededLocked();
7361 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007362 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007363 mTransformation.clear();
7364 if (mHasDrawn
7365 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
7366 && mAppToken != null
7367 && mAppToken.firstWindowDrawn
7368 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007369 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007370 + mToken + ": first real window done animating");
7371 mFinishedStarting.add(mAppToken);
7372 mH.sendEmptyMessage(H.FINISHED_STARTING);
7373 }
Romain Guy06882f82009-06-10 13:36:04 -07007374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007375 finishExit();
7376
7377 if (mAppToken != null) {
7378 mAppToken.updateReportedVisibilityLocked();
7379 }
7380
7381 return false;
7382 }
7383
7384 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007385 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007386 TAG, "finishExit in " + this
7387 + ": exiting=" + mExiting
7388 + " remove=" + mRemoveOnExit
7389 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07007390
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007391 final int N = mChildWindows.size();
7392 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07007393 mChildWindows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007394 }
Romain Guy06882f82009-06-10 13:36:04 -07007395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007396 if (!mExiting) {
7397 return;
7398 }
Romain Guy06882f82009-06-10 13:36:04 -07007399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007400 if (isWindowAnimating()) {
7401 return;
7402 }
7403
Joe Onorato8a9b2202010-02-26 18:56:32 -08007404 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007405 TAG, "Exit animation finished in " + this
7406 + ": remove=" + mRemoveOnExit);
7407 if (mSurface != null) {
7408 mDestroySurface.add(this);
7409 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007410 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007411 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007412 try {
7413 mSurface.hide();
7414 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007415 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007416 }
7417 mLastHidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007418 }
7419 mExiting = false;
7420 if (mRemoveOnExit) {
7421 mPendingRemove.add(this);
7422 mRemoveOnExit = false;
7423 }
7424 }
Romain Guy06882f82009-06-10 13:36:04 -07007425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007426 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
7427 if (dsdx < .99999f || dsdx > 1.00001f) return false;
7428 if (dtdy < .99999f || dtdy > 1.00001f) return false;
7429 if (dtdx < -.000001f || dtdx > .000001f) return false;
7430 if (dsdy < -.000001f || dsdy > .000001f) return false;
7431 return true;
7432 }
Romain Guy06882f82009-06-10 13:36:04 -07007433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007434 void computeShownFrameLocked() {
7435 final boolean selfTransformation = mHasLocalTransformation;
7436 Transformation attachedTransformation =
7437 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
7438 ? mAttachedWindow.mTransformation : null;
7439 Transformation appTransformation =
7440 (mAppToken != null && mAppToken.hasTransformation)
7441 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007442
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007443 // Wallpapers are animated based on the "real" window they
7444 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007445 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007446 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07007447 if (mWallpaperTarget.mHasLocalTransformation &&
7448 mWallpaperTarget.mAnimation != null &&
7449 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007450 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007451 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007452 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007453 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007454 }
7455 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07007456 mWallpaperTarget.mAppToken.hasTransformation &&
7457 mWallpaperTarget.mAppToken.animation != null &&
7458 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007459 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007460 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007461 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007462 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007463 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007464 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007466 if (selfTransformation || attachedTransformation != null
7467 || appTransformation != null) {
Romain Guy06882f82009-06-10 13:36:04 -07007468 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007469 final Rect frame = mFrame;
7470 final float tmpFloats[] = mTmpFloats;
7471 final Matrix tmpMatrix = mTmpMatrix;
7472
7473 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07007474 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007475 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007476 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007477 }
Dianne Hackborn65c23872009-09-18 17:47:02 -07007478 tmpMatrix.postTranslate(frame.left, frame.top);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007479 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007480 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007481 }
7482 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007483 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007484 }
7485
7486 // "convert" it into SurfaceFlinger's format
7487 // (a 2x2 matrix + an offset)
7488 // Here we must not transform the position of the surface
7489 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08007490 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07007491
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007492 tmpMatrix.getValues(tmpFloats);
7493 mDsDx = tmpFloats[Matrix.MSCALE_X];
7494 mDtDx = tmpFloats[Matrix.MSKEW_X];
7495 mDsDy = tmpFloats[Matrix.MSKEW_Y];
7496 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007497 int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
7498 int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007499 int w = frame.width();
7500 int h = frame.height();
7501 mShownFrame.set(x, y, x+w, y+h);
7502
7503 // Now set the alpha... but because our current hardware
7504 // can't do alpha transformation on a non-opaque surface,
7505 // turn it off if we are running an animation that is also
7506 // transforming since it is more important to have that
7507 // animation be smooth.
7508 mShownAlpha = mAlpha;
7509 if (!mLimitedAlphaCompositing
7510 || (!PixelFormat.formatHasAlpha(mAttrs.format)
7511 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
7512 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007513 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007514 if (selfTransformation) {
7515 mShownAlpha *= mTransformation.getAlpha();
7516 }
7517 if (attachedTransformation != null) {
7518 mShownAlpha *= attachedTransformation.getAlpha();
7519 }
7520 if (appTransformation != null) {
7521 mShownAlpha *= appTransformation.getAlpha();
7522 }
7523 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007524 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007525 }
Romain Guy06882f82009-06-10 13:36:04 -07007526
Joe Onorato8a9b2202010-02-26 18:56:32 -08007527 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007528 TAG, "Continuing animation in " + this +
7529 ": " + mShownFrame +
7530 ", alpha=" + mTransformation.getAlpha());
7531 return;
7532 }
Romain Guy06882f82009-06-10 13:36:04 -07007533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007534 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007535 if (mXOffset != 0 || mYOffset != 0) {
7536 mShownFrame.offset(mXOffset, mYOffset);
7537 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007538 mShownAlpha = mAlpha;
7539 mDsDx = 1;
7540 mDtDx = 0;
7541 mDsDy = 0;
7542 mDtDy = 1;
7543 }
Romain Guy06882f82009-06-10 13:36:04 -07007544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007545 /**
7546 * Is this window visible? It is not visible if there is no
7547 * surface, or we are in the process of running an exit animation
7548 * that will remove the surface, or its app token has been hidden.
7549 */
7550 public boolean isVisibleLw() {
7551 final AppWindowToken atoken = mAppToken;
7552 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7553 && (atoken == null || !atoken.hiddenRequested)
7554 && !mExiting && !mDestroying;
7555 }
7556
7557 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007558 * Like {@link #isVisibleLw}, but also counts a window that is currently
7559 * "hidden" behind the keyguard as visible. This allows us to apply
7560 * things like window flags that impact the keyguard.
7561 * XXX I am starting to think we need to have ANOTHER visibility flag
7562 * for this "hidden behind keyguard" state rather than overloading
7563 * mPolicyVisibility. Ungh.
7564 */
7565 public boolean isVisibleOrBehindKeyguardLw() {
7566 final AppWindowToken atoken = mAppToken;
7567 return mSurface != null && !mAttachedHidden
7568 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007569 && !mDrawPending && !mCommitDrawPending
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007570 && !mExiting && !mDestroying;
7571 }
7572
7573 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007574 * Is this window visible, ignoring its app token? It is not visible
7575 * if there is no surface, or we are in the process of running an exit animation
7576 * that will remove the surface.
7577 */
7578 public boolean isWinVisibleLw() {
7579 final AppWindowToken atoken = mAppToken;
7580 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7581 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
7582 && !mExiting && !mDestroying;
7583 }
7584
7585 /**
7586 * The same as isVisible(), but follows the current hidden state of
7587 * the associated app token, not the pending requested hidden state.
7588 */
7589 boolean isVisibleNow() {
7590 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07007591 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007592 }
7593
7594 /**
Christopher Tatea53146c2010-09-07 11:57:52 -07007595 * Can this window possibly be a drag/drop target? The test here is
7596 * a combination of the above "visible now" with the check that the
7597 * Input Manager uses when discarding windows from input consideration.
7598 */
7599 boolean isPotentialDragTarget() {
7600 return isVisibleNow() && (mInputChannel != null) && !mRemoved;
7601 }
7602
7603 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007604 * Same as isVisible(), but we also count it as visible between the
7605 * call to IWindowSession.add() and the first relayout().
7606 */
7607 boolean isVisibleOrAdding() {
7608 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007609 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007610 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
7611 && mPolicyVisibility && !mAttachedHidden
7612 && (atoken == null || !atoken.hiddenRequested)
7613 && !mExiting && !mDestroying;
7614 }
7615
7616 /**
7617 * Is this window currently on-screen? It is on-screen either if it
7618 * is visible or it is currently running an animation before no longer
7619 * being visible.
7620 */
7621 boolean isOnScreen() {
7622 final AppWindowToken atoken = mAppToken;
7623 if (atoken != null) {
7624 return mSurface != null && mPolicyVisibility && !mDestroying
7625 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007626 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007627 } else {
7628 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007629 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007630 }
7631 }
Romain Guy06882f82009-06-10 13:36:04 -07007632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007633 /**
7634 * Like isOnScreen(), but we don't return true if the window is part
7635 * of a transition that has not yet been started.
7636 */
7637 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007638 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007639 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007640 return false;
7641 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007642 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007643 final boolean animating = atoken != null
7644 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007645 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007646 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
7647 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007648 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007649 }
7650
7651 /** Is the window or its container currently animating? */
7652 boolean isAnimating() {
7653 final WindowState attached = mAttachedWindow;
7654 final AppWindowToken atoken = mAppToken;
7655 return mAnimation != null
7656 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07007657 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007658 (atoken.animation != null
7659 || atoken.inPendingTransaction));
7660 }
7661
7662 /** Is this window currently animating? */
7663 boolean isWindowAnimating() {
7664 return mAnimation != null;
7665 }
7666
7667 /**
7668 * Like isOnScreen, but returns false if the surface hasn't yet
7669 * been drawn.
7670 */
7671 public boolean isDisplayedLw() {
7672 final AppWindowToken atoken = mAppToken;
7673 return mSurface != null && mPolicyVisibility && !mDestroying
7674 && !mDrawPending && !mCommitDrawPending
7675 && ((!mAttachedHidden &&
7676 (atoken == null || !atoken.hiddenRequested))
7677 || mAnimating);
7678 }
7679
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007680 /**
7681 * Returns true if the window has a surface that it has drawn a
7682 * complete UI in to.
7683 */
7684 public boolean isDrawnLw() {
7685 final AppWindowToken atoken = mAppToken;
7686 return mSurface != null && !mDestroying
7687 && !mDrawPending && !mCommitDrawPending;
7688 }
7689
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007690 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07007691 * Return true if the window is opaque and fully drawn. This indicates
7692 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007693 */
7694 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07007695 return (mAttrs.format == PixelFormat.OPAQUE
7696 || mAttrs.type == TYPE_WALLPAPER)
7697 && mSurface != null && mAnimation == null
7698 && (mAppToken == null || mAppToken.animation == null)
7699 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007700 }
7701
7702 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
7703 return
7704 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007705 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
7706 // only if it's visible
7707 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007708 // and only if the application fills the compatible screen
7709 mFrame.left <= mCompatibleScreenFrame.left &&
7710 mFrame.top <= mCompatibleScreenFrame.top &&
7711 mFrame.right >= mCompatibleScreenFrame.right &&
7712 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007713 // and starting window do not need background filler
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007714 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007715 }
7716
7717 boolean isFullscreen(int screenWidth, int screenHeight) {
7718 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007719 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007720 }
7721
7722 void removeLocked() {
Jeff Brownc5ed5912010-07-14 18:48:53 -07007723 disposeInputChannel();
7724
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007725 if (mAttachedWindow != null) {
7726 mAttachedWindow.mChildWindows.remove(this);
7727 }
7728 destroySurfaceLocked();
7729 mSession.windowRemovedLocked();
7730 try {
7731 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
7732 } catch (RuntimeException e) {
7733 // Ignore if it has already been removed (usually because
7734 // we are doing this as part of processing a death note.)
7735 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07007736 }
7737
7738 void disposeInputChannel() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07007739 if (mInputChannel != null) {
7740 mInputManager.unregisterInputChannel(mInputChannel);
7741
7742 mInputChannel.dispose();
7743 mInputChannel = null;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007744 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007745 }
7746
7747 private class DeathRecipient implements IBinder.DeathRecipient {
7748 public void binderDied() {
7749 try {
7750 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007751 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007752 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007753 if (win != null) {
7754 removeWindowLocked(mSession, win);
7755 }
7756 }
7757 } catch (IllegalArgumentException ex) {
7758 // This will happen if the window has already been
7759 // removed.
7760 }
7761 }
7762 }
7763
7764 /** Returns true if this window desires key events. */
7765 public final boolean canReceiveKeys() {
7766 return isVisibleOrAdding()
7767 && (mViewVisibility == View.VISIBLE)
7768 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
7769 }
7770
7771 public boolean hasDrawnLw() {
7772 return mHasDrawn;
7773 }
7774
7775 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007776 return showLw(doAnimation, true);
7777 }
7778
7779 boolean showLw(boolean doAnimation, boolean requestAnim) {
7780 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
7781 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007782 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007783 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007784 if (doAnimation) {
7785 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
7786 + mPolicyVisibility + " mAnimation=" + mAnimation);
7787 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
7788 doAnimation = false;
7789 } else if (mPolicyVisibility && mAnimation == null) {
7790 // Check for the case where we are currently visible and
7791 // not animating; we do not want to do animation at such a
7792 // point to become visible when we already are.
7793 doAnimation = false;
7794 }
7795 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007796 mPolicyVisibility = true;
7797 mPolicyVisibilityAfterAnim = true;
7798 if (doAnimation) {
7799 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
7800 }
7801 if (requestAnim) {
7802 requestAnimationLocked(0);
7803 }
7804 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007805 }
7806
7807 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007808 return hideLw(doAnimation, true);
7809 }
7810
7811 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007812 if (doAnimation) {
7813 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
7814 doAnimation = false;
7815 }
7816 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007817 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
7818 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007819 if (!current) {
7820 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007821 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007822 if (doAnimation) {
7823 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
7824 if (mAnimation == null) {
7825 doAnimation = false;
7826 }
7827 }
7828 if (doAnimation) {
7829 mPolicyVisibilityAfterAnim = false;
7830 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007831 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007832 mPolicyVisibilityAfterAnim = false;
7833 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007834 // Window is no longer visible -- make sure if we were waiting
7835 // for it to be displayed before enabling the display, that
7836 // we allow the display to be enabled now.
7837 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007838 if (mCurrentFocus == this) {
7839 mFocusMayChange = true;
7840 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007841 }
7842 if (requestAnim) {
7843 requestAnimationLocked(0);
7844 }
7845 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007846 }
7847
7848 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007849 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
7850 pw.print(" mClient="); pw.println(mClient.asBinder());
7851 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
7852 if (mAttachedWindow != null || mLayoutAttached) {
7853 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
7854 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
7855 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007856 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
7857 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
7858 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007859 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
7860 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007861 }
7862 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
7863 pw.print(" mSubLayer="); pw.print(mSubLayer);
7864 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
7865 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
7866 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
7867 pw.print("="); pw.print(mAnimLayer);
7868 pw.print(" mLastLayer="); pw.println(mLastLayer);
7869 if (mSurface != null) {
7870 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007871 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
7872 pw.print(" layer="); pw.print(mSurfaceLayer);
7873 pw.print(" alpha="); pw.print(mSurfaceAlpha);
7874 pw.print(" rect=("); pw.print(mSurfaceX);
7875 pw.print(","); pw.print(mSurfaceY);
7876 pw.print(") "); pw.print(mSurfaceW);
7877 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007878 }
7879 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
7880 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
7881 if (mAppToken != null) {
7882 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
7883 }
7884 if (mTargetAppToken != null) {
7885 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
7886 }
7887 pw.print(prefix); pw.print("mViewVisibility=0x");
7888 pw.print(Integer.toHexString(mViewVisibility));
7889 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007890 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
7891 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007892 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
7893 pw.print(prefix); pw.print("mPolicyVisibility=");
7894 pw.print(mPolicyVisibility);
7895 pw.print(" mPolicyVisibilityAfterAnim=");
7896 pw.print(mPolicyVisibilityAfterAnim);
7897 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
7898 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08007899 if (!mRelayoutCalled) {
7900 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
7901 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007902 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007903 pw.print(" h="); pw.print(mRequestedHeight);
7904 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007905 if (mXOffset != 0 || mYOffset != 0) {
7906 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
7907 pw.print(" y="); pw.println(mYOffset);
7908 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007909 pw.print(prefix); pw.print("mGivenContentInsets=");
7910 mGivenContentInsets.printShortString(pw);
7911 pw.print(" mGivenVisibleInsets=");
7912 mGivenVisibleInsets.printShortString(pw);
7913 pw.println();
7914 if (mTouchableInsets != 0 || mGivenInsetsPending) {
7915 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
7916 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
7917 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007918 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007919 pw.print(prefix); pw.print("mShownFrame=");
7920 mShownFrame.printShortString(pw);
7921 pw.print(" last="); mLastShownFrame.printShortString(pw);
7922 pw.println();
7923 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
7924 pw.print(" last="); mLastFrame.printShortString(pw);
7925 pw.println();
7926 pw.print(prefix); pw.print("mContainingFrame=");
7927 mContainingFrame.printShortString(pw);
7928 pw.print(" mDisplayFrame=");
7929 mDisplayFrame.printShortString(pw);
7930 pw.println();
7931 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
7932 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
7933 pw.println();
7934 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
7935 pw.print(" last="); mLastContentInsets.printShortString(pw);
7936 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
7937 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
7938 pw.println();
7939 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
7940 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
7941 pw.print(" mAlpha="); pw.print(mAlpha);
7942 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
7943 }
7944 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
7945 || mAnimation != null) {
7946 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
7947 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
7948 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
7949 pw.print(" mAnimation="); pw.println(mAnimation);
7950 }
7951 if (mHasTransformation || mHasLocalTransformation) {
7952 pw.print(prefix); pw.print("XForm: has=");
7953 pw.print(mHasTransformation);
7954 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
7955 pw.print(" "); mTransformation.printShortString(pw);
7956 pw.println();
7957 }
7958 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
7959 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
7960 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
7961 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
7962 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
7963 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
7964 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
7965 pw.print(" mDestroying="); pw.print(mDestroying);
7966 pw.print(" mRemoved="); pw.println(mRemoved);
7967 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007968 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007969 pw.print(prefix); pw.print("mOrientationChanging=");
7970 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007971 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
7972 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007973 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07007974 if (mHScale != 1 || mVScale != 1) {
7975 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
7976 pw.print(" mVScale="); pw.println(mVScale);
7977 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007978 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007979 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
7980 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
7981 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007982 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
7983 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
7984 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
7985 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007986 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007987
7988 String makeInputChannelName() {
7989 return Integer.toHexString(System.identityHashCode(this))
7990 + " " + mAttrs.getTitle();
7991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007992
7993 @Override
7994 public String toString() {
7995 return "Window{"
7996 + Integer.toHexString(System.identityHashCode(this))
7997 + " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
7998 }
7999 }
Romain Guy06882f82009-06-10 13:36:04 -07008000
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008001 // -------------------------------------------------------------
8002 // Window Token State
8003 // -------------------------------------------------------------
8004
8005 class WindowToken {
8006 // The actual token.
8007 final IBinder token;
8008
8009 // The type of window this token is for, as per WindowManager.LayoutParams.
8010 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07008011
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008012 // Set if this token was explicitly added by a client, so should
8013 // not be removed when all windows are removed.
8014 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07008015
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008016 // For printing.
8017 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07008018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008019 // If this is an AppWindowToken, this is non-null.
8020 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07008021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008022 // All of the windows associated with this token.
8023 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
8024
8025 // Is key dispatching paused for this token?
8026 boolean paused = false;
8027
8028 // Should this token's windows be hidden?
8029 boolean hidden;
8030
8031 // Temporary for finding which tokens no longer have visible windows.
8032 boolean hasVisible;
8033
Dianne Hackborna8f60182009-09-01 19:01:50 -07008034 // Set to true when this token is in a pending transaction where it
8035 // will be shown.
8036 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008037
Dianne Hackborna8f60182009-09-01 19:01:50 -07008038 // Set to true when this token is in a pending transaction where it
8039 // will be hidden.
8040 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008041
Dianne Hackborna8f60182009-09-01 19:01:50 -07008042 // Set to true when this token is in a pending transaction where its
8043 // windows will be put to the bottom of the list.
8044 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008045
Dianne Hackborna8f60182009-09-01 19:01:50 -07008046 // Set to true when this token is in a pending transaction where its
8047 // windows will be put to the top of the list.
8048 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008050 WindowToken(IBinder _token, int type, boolean _explicit) {
8051 token = _token;
8052 windowType = type;
8053 explicit = _explicit;
8054 }
8055
8056 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008057 pw.print(prefix); pw.print("token="); pw.println(token);
8058 pw.print(prefix); pw.print("windows="); pw.println(windows);
8059 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
8060 pw.print(" hidden="); pw.print(hidden);
8061 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008062 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
8063 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
8064 pw.print(" waitingToHide="); pw.print(waitingToHide);
8065 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
8066 pw.print(" sendingToTop="); pw.println(sendingToTop);
8067 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008068 }
8069
8070 @Override
8071 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008072 if (stringName == null) {
8073 StringBuilder sb = new StringBuilder();
8074 sb.append("WindowToken{");
8075 sb.append(Integer.toHexString(System.identityHashCode(this)));
8076 sb.append(" token="); sb.append(token); sb.append('}');
8077 stringName = sb.toString();
8078 }
8079 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008080 }
8081 };
8082
8083 class AppWindowToken extends WindowToken {
8084 // Non-null only for application tokens.
8085 final IApplicationToken appToken;
8086
8087 // All of the windows and child windows that are included in this
8088 // application token. Note this list is NOT sorted!
8089 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
8090
8091 int groupId = -1;
8092 boolean appFullscreen;
8093 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jeff Brown349703e2010-06-22 01:27:15 -07008094
8095 // The input dispatching timeout for this application token in nanoseconds.
8096 long inputDispatchingTimeoutNanos;
Romain Guy06882f82009-06-10 13:36:04 -07008097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008098 // These are used for determining when all windows associated with
8099 // an activity have been drawn, so they can be made visible together
8100 // at the same time.
8101 int lastTransactionSequence = mTransactionSequence-1;
8102 int numInterestingWindows;
8103 int numDrawnWindows;
8104 boolean inPendingTransaction;
8105 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07008106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008107 // Is this token going to be hidden in a little while? If so, it
8108 // won't be taken into account for setting the screen orientation.
8109 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008110
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008111 // Is this window's surface needed? This is almost like hidden, except
8112 // it will sometimes be true a little earlier: when the token has
8113 // been shown, but is still waiting for its app transition to execute
8114 // before making its windows shown.
8115 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07008116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008117 // Have we told the window clients to hide themselves?
8118 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008120 // Last visibility state we reported to the app token.
8121 boolean reportedVisible;
8122
8123 // Set to true when the token has been removed from the window mgr.
8124 boolean removed;
8125
8126 // Have we been asked to have this token keep the screen frozen?
8127 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07008128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008129 boolean animating;
8130 Animation animation;
8131 boolean hasTransformation;
8132 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07008133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008134 // Offset to the window of all layers in the token, for use by
8135 // AppWindowToken animations.
8136 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07008137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008138 // Information about an application starting window if displayed.
8139 StartingData startingData;
8140 WindowState startingWindow;
8141 View startingView;
8142 boolean startingDisplayed;
8143 boolean startingMoved;
8144 boolean firstWindowDrawn;
8145
8146 AppWindowToken(IApplicationToken _token) {
8147 super(_token.asBinder(),
8148 WindowManager.LayoutParams.TYPE_APPLICATION, true);
8149 appWindowToken = this;
8150 appToken = _token;
8151 }
Romain Guy06882f82009-06-10 13:36:04 -07008152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008153 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008154 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008155 TAG, "Setting animation in " + this + ": " + anim);
8156 animation = anim;
8157 animating = false;
8158 anim.restrictDuration(MAX_ANIMATION_DURATION);
8159 anim.scaleCurrentDuration(mTransitionAnimationScale);
8160 int zorder = anim.getZAdjustment();
8161 int adj = 0;
8162 if (zorder == Animation.ZORDER_TOP) {
8163 adj = TYPE_LAYER_OFFSET;
8164 } else if (zorder == Animation.ZORDER_BOTTOM) {
8165 adj = -TYPE_LAYER_OFFSET;
8166 }
Romain Guy06882f82009-06-10 13:36:04 -07008167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008168 if (animLayerAdjustment != adj) {
8169 animLayerAdjustment = adj;
8170 updateLayers();
8171 }
8172 }
Romain Guy06882f82009-06-10 13:36:04 -07008173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008174 public void setDummyAnimation() {
8175 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008176 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008177 TAG, "Setting dummy animation in " + this);
8178 animation = sDummyAnimation;
8179 }
8180 }
8181
8182 public void clearAnimation() {
8183 if (animation != null) {
8184 animation = null;
8185 animating = true;
8186 }
8187 }
Romain Guy06882f82009-06-10 13:36:04 -07008188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008189 void updateLayers() {
8190 final int N = allAppWindows.size();
8191 final int adj = animLayerAdjustment;
8192 for (int i=0; i<N; i++) {
8193 WindowState w = allAppWindows.get(i);
8194 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008195 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008196 + w.mAnimLayer);
8197 if (w == mInputMethodTarget) {
8198 setInputMethodAnimLayerAdjustment(adj);
8199 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008200 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008201 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008203 }
8204 }
Romain Guy06882f82009-06-10 13:36:04 -07008205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008206 void sendAppVisibilityToClients() {
8207 final int N = allAppWindows.size();
8208 for (int i=0; i<N; i++) {
8209 WindowState win = allAppWindows.get(i);
8210 if (win == startingWindow && clientHidden) {
8211 // Don't hide the starting window.
8212 continue;
8213 }
8214 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008215 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008216 "Setting visibility of " + win + ": " + (!clientHidden));
8217 win.mClient.dispatchAppVisibility(!clientHidden);
8218 } catch (RemoteException e) {
8219 }
8220 }
8221 }
Romain Guy06882f82009-06-10 13:36:04 -07008222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008223 void showAllWindowsLocked() {
8224 final int NW = allAppWindows.size();
8225 for (int i=0; i<NW; i++) {
8226 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008227 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008228 "performing show on: " + w);
8229 w.performShowLocked();
8230 }
8231 }
Romain Guy06882f82009-06-10 13:36:04 -07008232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008233 // This must be called while inside a transaction.
8234 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008235 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008236 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07008237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008238 if (animation == sDummyAnimation) {
8239 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008240 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008241 // when it is really time to animate, this will be set to
8242 // a real animation and the next call will execute normally.
8243 return false;
8244 }
Romain Guy06882f82009-06-10 13:36:04 -07008245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008246 if ((allDrawn || animating || startingDisplayed) && animation != null) {
8247 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008248 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008249 TAG, "Starting animation in " + this +
8250 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
8251 + " scale=" + mTransitionAnimationScale
8252 + " allDrawn=" + allDrawn + " animating=" + animating);
8253 animation.initialize(dw, dh, dw, dh);
8254 animation.setStartTime(currentTime);
8255 animating = true;
8256 }
8257 transformation.clear();
8258 final boolean more = animation.getTransformation(
8259 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008260 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008261 TAG, "Stepped animation in " + this +
8262 ": more=" + more + ", xform=" + transformation);
8263 if (more) {
8264 // we're done!
8265 hasTransformation = true;
8266 return true;
8267 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008268 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008269 TAG, "Finished animation in " + this +
8270 " @ " + currentTime);
8271 animation = null;
8272 }
8273 } else if (animation != null) {
8274 // If the display is frozen, and there is a pending animation,
8275 // clear it and make sure we run the cleanup code.
8276 animating = true;
8277 animation = null;
8278 }
8279
8280 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07008281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008282 if (!animating) {
8283 return false;
8284 }
8285
8286 clearAnimation();
8287 animating = false;
8288 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
8289 moveInputMethodWindowsIfNeededLocked(true);
8290 }
Romain Guy06882f82009-06-10 13:36:04 -07008291
Joe Onorato8a9b2202010-02-26 18:56:32 -08008292 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008293 TAG, "Animation done in " + this
8294 + ": reportedVisible=" + reportedVisible);
8295
8296 transformation.clear();
8297 if (animLayerAdjustment != 0) {
8298 animLayerAdjustment = 0;
8299 updateLayers();
8300 }
Romain Guy06882f82009-06-10 13:36:04 -07008301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008302 final int N = windows.size();
8303 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008304 windows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008305 }
8306 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07008307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008308 return false;
8309 }
8310
8311 void updateReportedVisibilityLocked() {
8312 if (appToken == null) {
8313 return;
8314 }
Romain Guy06882f82009-06-10 13:36:04 -07008315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008316 int numInteresting = 0;
8317 int numVisible = 0;
8318 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07008319
Joe Onorato8a9b2202010-02-26 18:56:32 -08008320 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008321 final int N = allAppWindows.size();
8322 for (int i=0; i<N; i++) {
8323 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08008324 if (win == startingWindow || win.mAppFreezing
The Android Open Source Project727cec02010-04-08 11:35:37 -07008325 || win.mViewVisibility != View.VISIBLE
Ulf Rosdahl39357702010-09-29 12:34:38 +02008326 || win.mAttrs.type == TYPE_APPLICATION_STARTING
8327 || win.mDestroying) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008328 continue;
8329 }
8330 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008331 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008332 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008333 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008334 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008335 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008336 + " pv=" + win.mPolicyVisibility
8337 + " dp=" + win.mDrawPending
8338 + " cdp=" + win.mCommitDrawPending
8339 + " ah=" + win.mAttachedHidden
8340 + " th="
8341 + (win.mAppToken != null
8342 ? win.mAppToken.hiddenRequested : false)
8343 + " a=" + win.mAnimating);
8344 }
8345 }
8346 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008347 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008348 if (!win.isAnimating()) {
8349 numVisible++;
8350 }
8351 nowGone = false;
8352 } else if (win.isAnimating()) {
8353 nowGone = false;
8354 }
8355 }
Romain Guy06882f82009-06-10 13:36:04 -07008356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008357 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008358 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008359 + numInteresting + " visible=" + numVisible);
8360 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008361 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008362 TAG, "Visibility changed in " + this
8363 + ": vis=" + nowVisible);
8364 reportedVisible = nowVisible;
8365 Message m = mH.obtainMessage(
8366 H.REPORT_APPLICATION_TOKEN_WINDOWS,
8367 nowVisible ? 1 : 0,
8368 nowGone ? 1 : 0,
8369 this);
8370 mH.sendMessage(m);
8371 }
8372 }
Romain Guy06882f82009-06-10 13:36:04 -07008373
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008374 WindowState findMainWindow() {
8375 int j = windows.size();
8376 while (j > 0) {
8377 j--;
8378 WindowState win = windows.get(j);
8379 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
8380 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
8381 return win;
8382 }
8383 }
8384 return null;
8385 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008387 void dump(PrintWriter pw, String prefix) {
8388 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008389 if (appToken != null) {
8390 pw.print(prefix); pw.println("app=true");
8391 }
8392 if (allAppWindows.size() > 0) {
8393 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
8394 }
8395 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008396 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008397 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
8398 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
8399 pw.print(" clientHidden="); pw.print(clientHidden);
8400 pw.print(" willBeHidden="); pw.print(willBeHidden);
8401 pw.print(" reportedVisible="); pw.println(reportedVisible);
8402 if (paused || freezingScreen) {
8403 pw.print(prefix); pw.print("paused="); pw.print(paused);
8404 pw.print(" freezingScreen="); pw.println(freezingScreen);
8405 }
8406 if (numInterestingWindows != 0 || numDrawnWindows != 0
8407 || inPendingTransaction || allDrawn) {
8408 pw.print(prefix); pw.print("numInterestingWindows=");
8409 pw.print(numInterestingWindows);
8410 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
8411 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
8412 pw.print(" allDrawn="); pw.println(allDrawn);
8413 }
8414 if (animating || animation != null) {
8415 pw.print(prefix); pw.print("animating="); pw.print(animating);
8416 pw.print(" animation="); pw.println(animation);
8417 }
8418 if (animLayerAdjustment != 0) {
8419 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
8420 }
8421 if (hasTransformation) {
8422 pw.print(prefix); pw.print("hasTransformation="); pw.print(hasTransformation);
8423 pw.print(" transformation="); transformation.printShortString(pw);
8424 pw.println();
8425 }
8426 if (startingData != null || removed || firstWindowDrawn) {
8427 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
8428 pw.print(" removed="); pw.print(removed);
8429 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
8430 }
8431 if (startingWindow != null || startingView != null
8432 || startingDisplayed || startingMoved) {
8433 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
8434 pw.print(" startingView="); pw.print(startingView);
8435 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
8436 pw.print(" startingMoved"); pw.println(startingMoved);
8437 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008438 }
8439
8440 @Override
8441 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008442 if (stringName == null) {
8443 StringBuilder sb = new StringBuilder();
8444 sb.append("AppWindowToken{");
8445 sb.append(Integer.toHexString(System.identityHashCode(this)));
8446 sb.append(" token="); sb.append(token); sb.append('}');
8447 stringName = sb.toString();
8448 }
8449 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008450 }
8451 }
Romain Guy06882f82009-06-10 13:36:04 -07008452
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008453 // -------------------------------------------------------------
8454 // DummyAnimation
8455 // -------------------------------------------------------------
8456
8457 // This is an animation that does nothing: it just immediately finishes
8458 // itself every time it is called. It is used as a stub animation in cases
8459 // where we want to synchronize multiple things that may be animating.
8460 static final class DummyAnimation extends Animation {
8461 public boolean getTransformation(long currentTime, Transformation outTransformation) {
8462 return false;
8463 }
8464 }
8465 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07008466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008467 // -------------------------------------------------------------
8468 // Async Handler
8469 // -------------------------------------------------------------
8470
8471 static final class StartingData {
8472 final String pkg;
8473 final int theme;
8474 final CharSequence nonLocalizedLabel;
8475 final int labelRes;
8476 final int icon;
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008477 final int windowFlags;
Romain Guy06882f82009-06-10 13:36:04 -07008478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008479 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008480 int _labelRes, int _icon, int _windowFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008481 pkg = _pkg;
8482 theme = _theme;
8483 nonLocalizedLabel = _nonLocalizedLabel;
8484 labelRes = _labelRes;
8485 icon = _icon;
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008486 windowFlags = _windowFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008487 }
8488 }
8489
8490 private final class H extends Handler {
8491 public static final int REPORT_FOCUS_CHANGE = 2;
8492 public static final int REPORT_LOSING_FOCUS = 3;
8493 public static final int ANIMATE = 4;
8494 public static final int ADD_STARTING = 5;
8495 public static final int REMOVE_STARTING = 6;
8496 public static final int FINISHED_STARTING = 7;
8497 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008498 public static final int WINDOW_FREEZE_TIMEOUT = 11;
8499 public static final int HOLD_SCREEN_CHANGED = 12;
8500 public static final int APP_TRANSITION_TIMEOUT = 13;
8501 public static final int PERSIST_ANIMATION_SCALE = 14;
8502 public static final int FORCE_GC = 15;
8503 public static final int ENABLE_SCREEN = 16;
8504 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008505 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008506 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07008507 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f142010-10-19 15:15:08 -07008508 public static final int DRAG_END_TIMEOUT = 21;
Romain Guy06882f82009-06-10 13:36:04 -07008509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008510 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07008511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008512 public H() {
8513 }
Romain Guy06882f82009-06-10 13:36:04 -07008514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008515 @Override
8516 public void handleMessage(Message msg) {
8517 switch (msg.what) {
8518 case REPORT_FOCUS_CHANGE: {
8519 WindowState lastFocus;
8520 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07008521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008522 synchronized(mWindowMap) {
8523 lastFocus = mLastFocus;
8524 newFocus = mCurrentFocus;
8525 if (lastFocus == newFocus) {
8526 // Focus is not changing, so nothing to do.
8527 return;
8528 }
8529 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008530 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008531 // + " to " + newFocus);
8532 if (newFocus != null && lastFocus != null
8533 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008534 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008535 mLosingFocus.add(lastFocus);
8536 lastFocus = null;
8537 }
8538 }
8539
8540 if (lastFocus != newFocus) {
8541 //System.out.println("Changing focus from " + lastFocus
8542 // + " to " + newFocus);
8543 if (newFocus != null) {
8544 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008545 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008546 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
8547 } catch (RemoteException e) {
8548 // Ignore if process has died.
8549 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07008550 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008551 }
8552
8553 if (lastFocus != null) {
8554 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008555 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008556 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
8557 } catch (RemoteException e) {
8558 // Ignore if process has died.
8559 }
8560 }
8561 }
8562 } break;
8563
8564 case REPORT_LOSING_FOCUS: {
8565 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07008566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008567 synchronized(mWindowMap) {
8568 losers = mLosingFocus;
8569 mLosingFocus = new ArrayList<WindowState>();
8570 }
8571
8572 final int N = losers.size();
8573 for (int i=0; i<N; i++) {
8574 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008575 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008576 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
8577 } catch (RemoteException e) {
8578 // Ignore if process has died.
8579 }
8580 }
8581 } break;
8582
8583 case ANIMATE: {
8584 synchronized(mWindowMap) {
8585 mAnimationPending = false;
8586 performLayoutAndPlaceSurfacesLocked();
8587 }
8588 } break;
8589
8590 case ADD_STARTING: {
8591 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8592 final StartingData sd = wtoken.startingData;
8593
8594 if (sd == null) {
8595 // Animation has been canceled... do nothing.
8596 return;
8597 }
Romain Guy06882f82009-06-10 13:36:04 -07008598
Joe Onorato8a9b2202010-02-26 18:56:32 -08008599 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008600 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07008601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008602 View view = null;
8603 try {
8604 view = mPolicy.addStartingWindow(
8605 wtoken.token, sd.pkg,
8606 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008607 sd.icon, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008608 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008609 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008610 }
8611
8612 if (view != null) {
8613 boolean abort = false;
8614
8615 synchronized(mWindowMap) {
8616 if (wtoken.removed || wtoken.startingData == null) {
8617 // If the window was successfully added, then
8618 // we need to remove it.
8619 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008620 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008621 "Aborted starting " + wtoken
8622 + ": removed=" + wtoken.removed
8623 + " startingData=" + wtoken.startingData);
8624 wtoken.startingWindow = null;
8625 wtoken.startingData = null;
8626 abort = true;
8627 }
8628 } else {
8629 wtoken.startingView = view;
8630 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008631 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008632 "Added starting " + wtoken
8633 + ": startingWindow="
8634 + wtoken.startingWindow + " startingView="
8635 + wtoken.startingView);
8636 }
8637
8638 if (abort) {
8639 try {
8640 mPolicy.removeStartingWindow(wtoken.token, view);
8641 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008642 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008643 }
8644 }
8645 }
8646 } break;
8647
8648 case REMOVE_STARTING: {
8649 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8650 IBinder token = null;
8651 View view = null;
8652 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008653 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008654 + wtoken + ": startingWindow="
8655 + wtoken.startingWindow + " startingView="
8656 + wtoken.startingView);
8657 if (wtoken.startingWindow != null) {
8658 view = wtoken.startingView;
8659 token = wtoken.token;
8660 wtoken.startingData = null;
8661 wtoken.startingView = null;
8662 wtoken.startingWindow = null;
8663 }
8664 }
8665 if (view != null) {
8666 try {
8667 mPolicy.removeStartingWindow(token, view);
8668 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008669 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008670 }
8671 }
8672 } break;
8673
8674 case FINISHED_STARTING: {
8675 IBinder token = null;
8676 View view = null;
8677 while (true) {
8678 synchronized (mWindowMap) {
8679 final int N = mFinishedStarting.size();
8680 if (N <= 0) {
8681 break;
8682 }
8683 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
8684
Joe Onorato8a9b2202010-02-26 18:56:32 -08008685 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008686 "Finished starting " + wtoken
8687 + ": startingWindow=" + wtoken.startingWindow
8688 + " startingView=" + wtoken.startingView);
8689
8690 if (wtoken.startingWindow == null) {
8691 continue;
8692 }
8693
8694 view = wtoken.startingView;
8695 token = wtoken.token;
8696 wtoken.startingData = null;
8697 wtoken.startingView = null;
8698 wtoken.startingWindow = null;
8699 }
8700
8701 try {
8702 mPolicy.removeStartingWindow(token, view);
8703 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008704 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008705 }
8706 }
8707 } break;
8708
8709 case REPORT_APPLICATION_TOKEN_WINDOWS: {
8710 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8711
8712 boolean nowVisible = msg.arg1 != 0;
8713 boolean nowGone = msg.arg2 != 0;
8714
8715 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008716 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008717 TAG, "Reporting visible in " + wtoken
8718 + " visible=" + nowVisible
8719 + " gone=" + nowGone);
8720 if (nowVisible) {
8721 wtoken.appToken.windowsVisible();
8722 } else {
8723 wtoken.appToken.windowsGone();
8724 }
8725 } catch (RemoteException ex) {
8726 }
8727 } break;
Romain Guy06882f82009-06-10 13:36:04 -07008728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008729 case WINDOW_FREEZE_TIMEOUT: {
8730 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008731 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008732 int i = mWindows.size();
8733 while (i > 0) {
8734 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07008735 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008736 if (w.mOrientationChanging) {
8737 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008738 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008739 }
8740 }
8741 performLayoutAndPlaceSurfacesLocked();
8742 }
8743 break;
8744 }
Romain Guy06882f82009-06-10 13:36:04 -07008745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008746 case HOLD_SCREEN_CHANGED: {
8747 Session oldHold;
8748 Session newHold;
8749 synchronized (mWindowMap) {
8750 oldHold = mLastReportedHold;
8751 newHold = (Session)msg.obj;
8752 mLastReportedHold = newHold;
8753 }
Romain Guy06882f82009-06-10 13:36:04 -07008754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008755 if (oldHold != newHold) {
8756 try {
8757 if (oldHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008758 mBatteryStats.noteStopWakelock(oldHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008759 "window",
8760 BatteryStats.WAKE_TYPE_WINDOW);
8761 }
8762 if (newHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008763 mBatteryStats.noteStartWakelock(newHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008764 "window",
8765 BatteryStats.WAKE_TYPE_WINDOW);
8766 }
8767 } catch (RemoteException e) {
8768 }
8769 }
8770 break;
8771 }
Romain Guy06882f82009-06-10 13:36:04 -07008772
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008773 case APP_TRANSITION_TIMEOUT: {
8774 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008775 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008776 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008777 "*** APP TRANSITION TIMEOUT");
8778 mAppTransitionReady = true;
8779 mAppTransitionTimeout = true;
8780 performLayoutAndPlaceSurfacesLocked();
8781 }
8782 }
8783 break;
8784 }
Romain Guy06882f82009-06-10 13:36:04 -07008785
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008786 case PERSIST_ANIMATION_SCALE: {
8787 Settings.System.putFloat(mContext.getContentResolver(),
8788 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
8789 Settings.System.putFloat(mContext.getContentResolver(),
8790 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
8791 break;
8792 }
Romain Guy06882f82009-06-10 13:36:04 -07008793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008794 case FORCE_GC: {
8795 synchronized(mWindowMap) {
8796 if (mAnimationPending) {
8797 // If we are animating, don't do the gc now but
8798 // delay a bit so we don't interrupt the animation.
8799 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
8800 2000);
8801 return;
8802 }
8803 // If we are currently rotating the display, it will
8804 // schedule a new message when done.
8805 if (mDisplayFrozen) {
8806 return;
8807 }
8808 mFreezeGcPending = 0;
8809 }
8810 Runtime.getRuntime().gc();
8811 break;
8812 }
Romain Guy06882f82009-06-10 13:36:04 -07008813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008814 case ENABLE_SCREEN: {
8815 performEnableScreen();
8816 break;
8817 }
Romain Guy06882f82009-06-10 13:36:04 -07008818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008819 case APP_FREEZE_TIMEOUT: {
8820 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008821 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008822 int i = mAppTokens.size();
8823 while (i > 0) {
8824 i--;
8825 AppWindowToken tok = mAppTokens.get(i);
8826 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008827 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008828 unsetAppFreezingScreenLocked(tok, true, true);
8829 }
8830 }
8831 }
8832 break;
8833 }
Romain Guy06882f82009-06-10 13:36:04 -07008834
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008835 case SEND_NEW_CONFIGURATION: {
8836 removeMessages(SEND_NEW_CONFIGURATION);
8837 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07008838 break;
8839 }
Romain Guy06882f82009-06-10 13:36:04 -07008840
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008841 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008842 if (mWindowsChanged) {
8843 synchronized (mWindowMap) {
8844 mWindowsChanged = false;
8845 }
8846 notifyWindowsChanged();
8847 }
8848 break;
8849 }
8850
Christopher Tatea53146c2010-09-07 11:57:52 -07008851 case DRAG_START_TIMEOUT: {
8852 IBinder win = (IBinder)msg.obj;
8853 if (DEBUG_DRAG) {
8854 Slog.w(TAG, "Timeout starting drag by win " + win);
8855 }
8856 synchronized (mWindowMap) {
8857 // !!! TODO: ANR the app that has failed to start the drag in time
8858 if (mDragState != null) {
Chris Tated4533f142010-10-19 15:15:08 -07008859 mDragState.unregister();
8860 mInputMonitor.updateInputWindowsLw();
Christopher Tatea53146c2010-09-07 11:57:52 -07008861 mDragState.reset();
8862 mDragState = null;
8863 }
8864 }
Chris Tated4533f142010-10-19 15:15:08 -07008865 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07008866 }
8867
Chris Tated4533f142010-10-19 15:15:08 -07008868 case DRAG_END_TIMEOUT: {
8869 IBinder win = (IBinder)msg.obj;
8870 if (DEBUG_DRAG) {
8871 Slog.w(TAG, "Timeout ending drag to win " + win);
8872 }
8873 synchronized (mWindowMap) {
8874 // !!! TODO: ANR the drag-receiving app
8875 mDragState.mDragResult = false;
8876 mDragState.endDragLw();
8877 }
8878 break;
8879 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008880 }
8881 }
8882 }
8883
8884 // -------------------------------------------------------------
8885 // IWindowManager API
8886 // -------------------------------------------------------------
8887
8888 public IWindowSession openSession(IInputMethodClient client,
8889 IInputContext inputContext) {
8890 if (client == null) throw new IllegalArgumentException("null client");
8891 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008892 Session session = new Session(client, inputContext);
8893 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008894 }
8895
8896 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
8897 synchronized (mWindowMap) {
8898 // The focus for the client is the window immediately below
8899 // where we would place the input method window.
8900 int idx = findDesiredInputMethodWindowIndexLocked(false);
8901 WindowState imFocus;
8902 if (idx > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07008903 imFocus = mWindows.get(idx-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008904 if (imFocus != null) {
8905 if (imFocus.mSession.mClient != null &&
8906 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
8907 return true;
8908 }
8909 }
8910 }
8911 }
8912 return false;
8913 }
Romain Guy06882f82009-06-10 13:36:04 -07008914
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008915 // -------------------------------------------------------------
8916 // Internals
8917 // -------------------------------------------------------------
8918
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008919 final WindowState windowForClientLocked(Session session, IWindow client,
8920 boolean throwOnError) {
8921 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008922 }
Romain Guy06882f82009-06-10 13:36:04 -07008923
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008924 final WindowState windowForClientLocked(Session session, IBinder client,
8925 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008926 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008927 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008928 TAG, "Looking up client " + client + ": " + win);
8929 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008930 RuntimeException ex = new IllegalArgumentException(
8931 "Requested window " + client + " does not exist");
8932 if (throwOnError) {
8933 throw ex;
8934 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008935 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008936 return null;
8937 }
8938 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008939 RuntimeException ex = new IllegalArgumentException(
8940 "Requested window " + client + " is in session " +
8941 win.mSession + ", not " + session);
8942 if (throwOnError) {
8943 throw ex;
8944 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008945 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008946 return null;
8947 }
8948
8949 return win;
8950 }
8951
Dianne Hackborna8f60182009-09-01 19:01:50 -07008952 final void rebuildAppWindowListLocked() {
8953 int NW = mWindows.size();
8954 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008955 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008956 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008957
Dianne Hackborna8f60182009-09-01 19:01:50 -07008958 // First remove all existing app windows.
8959 i=0;
8960 while (i < NW) {
Jeff Browne33348b2010-07-15 23:54:05 -07008961 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008962 if (w.mAppToken != null) {
Jeff Browne33348b2010-07-15 23:54:05 -07008963 WindowState win = mWindows.remove(i);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008964 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008965 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008966 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008967 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008968 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008969 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008970 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
8971 && lastWallpaper == i-1) {
8972 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008973 }
8974 i++;
8975 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008976
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008977 // The wallpaper window(s) typically live at the bottom of the stack,
8978 // so skip them before adding app tokens.
8979 lastWallpaper++;
8980 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008981
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008982 // First add all of the exiting app tokens... these are no longer
8983 // in the main app list, but still have windows shown. We put them
8984 // in the back because now that the animation is over we no longer
8985 // will care about them.
8986 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008987 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008988 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
8989 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008990
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008991 // And add in the still active app tokens in Z order.
8992 NT = mAppTokens.size();
8993 for (int j=0; j<NT; j++) {
8994 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07008995 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008996
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008997 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008998 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008999 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009000 + " windows but added " + i);
9001 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07009002 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009004 private final void assignLayersLocked() {
9005 int N = mWindows.size();
9006 int curBaseLayer = 0;
9007 int curLayer = 0;
9008 int i;
Romain Guy06882f82009-06-10 13:36:04 -07009009
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009010 if (DEBUG_LAYERS) {
9011 RuntimeException here = new RuntimeException("here");
9012 here.fillInStackTrace();
9013 Log.v(TAG, "Assigning layers", here);
9014 }
9015
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009016 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07009017 WindowState w = mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009018 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
9019 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009020 curLayer += WINDOW_LAYER_MULTIPLIER;
9021 w.mLayer = curLayer;
9022 } else {
9023 curBaseLayer = curLayer = w.mBaseLayer;
9024 w.mLayer = curLayer;
9025 }
9026 if (w.mTargetAppToken != null) {
9027 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
9028 } else if (w.mAppToken != null) {
9029 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
9030 } else {
9031 w.mAnimLayer = w.mLayer;
9032 }
9033 if (w.mIsImWindow) {
9034 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07009035 } else if (w.mIsWallpaper) {
9036 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009037 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009038 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009039 + w.mAnimLayer);
9040 //System.out.println(
9041 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
9042 }
9043 }
9044
9045 private boolean mInLayout = false;
9046 private final void performLayoutAndPlaceSurfacesLocked() {
9047 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07009048 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009049 throw new RuntimeException("Recursive call!");
9050 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009051 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009052 return;
9053 }
9054
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009055 if (mWaitingForConfig) {
9056 // Our configuration has changed (most likely rotation), but we
9057 // don't yet have the complete configuration to report to
9058 // applications. Don't do any window layout until we have it.
9059 return;
9060 }
9061
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009062 if (mDisplay == null) {
9063 // Not yet initialized, nothing to do.
9064 return;
9065 }
9066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009067 boolean recoveringMemory = false;
9068 if (mForceRemoves != null) {
9069 recoveringMemory = true;
9070 // Wait a little it for things to settle down, and off we go.
9071 for (int i=0; i<mForceRemoves.size(); i++) {
9072 WindowState ws = mForceRemoves.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009073 Slog.i(TAG, "Force removing: " + ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009074 removeWindowInnerLocked(ws.mSession, ws);
9075 }
9076 mForceRemoves = null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009077 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009078 Object tmp = new Object();
9079 synchronized (tmp) {
9080 try {
9081 tmp.wait(250);
9082 } catch (InterruptedException e) {
9083 }
9084 }
9085 }
Romain Guy06882f82009-06-10 13:36:04 -07009086
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009087 mInLayout = true;
9088 try {
9089 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07009090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009091 int i = mPendingRemove.size()-1;
9092 if (i >= 0) {
9093 while (i >= 0) {
9094 WindowState w = mPendingRemove.get(i);
9095 removeWindowInnerLocked(w.mSession, w);
9096 i--;
9097 }
9098 mPendingRemove.clear();
9099
9100 mInLayout = false;
9101 assignLayersLocked();
9102 mLayoutNeeded = true;
9103 performLayoutAndPlaceSurfacesLocked();
9104
9105 } else {
9106 mInLayout = false;
9107 if (mLayoutNeeded) {
9108 requestAnimationLocked(0);
9109 }
9110 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009111 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07009112 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
9113 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009114 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009115 } catch (RuntimeException e) {
9116 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009117 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009118 }
9119 }
9120
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009121 private final int performLayoutLockedInner(boolean initial) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009122 if (!mLayoutNeeded) {
9123 return 0;
9124 }
9125
9126 mLayoutNeeded = false;
9127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009128 final int dw = mDisplay.getWidth();
9129 final int dh = mDisplay.getHeight();
9130
9131 final int N = mWindows.size();
9132 int i;
9133
Joe Onorato8a9b2202010-02-26 18:56:32 -08009134 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08009135 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
9136
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009137 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07009138
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009139 int seq = mLayoutSeq+1;
9140 if (seq < 0) seq = 0;
9141 mLayoutSeq = seq;
9142
9143 // First perform layout of any root windows (not attached
9144 // to another window).
9145 int topAttached = -1;
9146 for (i = N-1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009147 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009148
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009149 // Don't do layout of a window if it is not visible, or
9150 // soon won't be visible, to avoid wasting time and funky
9151 // changes while a window is animating away.
9152 final AppWindowToken atoken = win.mAppToken;
9153 final boolean gone = win.mViewVisibility == View.GONE
9154 || !win.mRelayoutCalled
9155 || win.mRootToken.hidden
9156 || (atoken != null && atoken.hiddenRequested)
9157 || win.mAttachedHidden
9158 || win.mExiting || win.mDestroying;
9159
9160 if (!win.mLayoutAttached) {
9161 if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win
9162 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
9163 + " mLayoutAttached=" + win.mLayoutAttached);
9164 if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility="
9165 + win.mViewVisibility + " mRelayoutCalled="
9166 + win.mRelayoutCalled + " hidden="
9167 + win.mRootToken.hidden + " hiddenRequested="
9168 + (atoken != null && atoken.hiddenRequested)
9169 + " mAttachedHidden=" + win.mAttachedHidden);
9170 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009171
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009172 // If this view is GONE, then skip it -- keep the current
9173 // frame, and let the caller know so they can ignore it
9174 // if they want. (We do the normal layout for INVISIBLE
9175 // windows, since that means "perform layout as normal,
9176 // just don't display").
9177 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009178 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009179 if (initial) {
9180 win.mContentChanged = false;
9181 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009182 mPolicy.layoutWindowLw(win, win.mAttrs, null);
9183 win.mLayoutSeq = seq;
9184 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9185 + win.mFrame + " mContainingFrame="
9186 + win.mContainingFrame + " mDisplayFrame="
9187 + win.mDisplayFrame);
9188 } else {
9189 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009190 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07009191 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009192 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009193
9194 // Now perform layout of attached windows, which usually
9195 // depend on the position of the window they are attached to.
9196 // XXX does not deal with windows that are attached to windows
9197 // that are themselves attached.
9198 for (i = topAttached; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009199 WindowState win = mWindows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009200
9201 // If this view is GONE, then skip it -- keep the current
9202 // frame, and let the caller know so they can ignore it
9203 // if they want. (We do the normal layout for INVISIBLE
9204 // windows, since that means "perform layout as normal,
9205 // just don't display").
9206 if (win.mLayoutAttached) {
9207 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
9208 + " mHaveFrame=" + win.mHaveFrame
9209 + " mViewVisibility=" + win.mViewVisibility
9210 + " mRelayoutCalled=" + win.mRelayoutCalled);
9211 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
9212 || !win.mHaveFrame) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009213 if (initial) {
9214 win.mContentChanged = false;
9215 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009216 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
9217 win.mLayoutSeq = seq;
9218 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9219 + win.mFrame + " mContainingFrame="
9220 + win.mContainingFrame + " mDisplayFrame="
9221 + win.mDisplayFrame);
9222 }
9223 }
9224 }
Jeff Brown349703e2010-06-22 01:27:15 -07009225
9226 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009227 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009228
9229 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009230 }
Romain Guy06882f82009-06-10 13:36:04 -07009231
Brad Fitzpatrick68044332010-11-22 18:19:48 -08009232 // "Something has changed! Let's make it correct now."
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009233 private final void performLayoutAndPlaceSurfacesLockedInner(
9234 boolean recoveringMemory) {
Joe Onorato34bcebc2010-07-07 18:05:01 -04009235 if (mDisplay == null) {
9236 Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
9237 return;
9238 }
9239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009240 final long currentTime = SystemClock.uptimeMillis();
9241 final int dw = mDisplay.getWidth();
9242 final int dh = mDisplay.getHeight();
9243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009244 int i;
9245
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009246 if (mFocusMayChange) {
9247 mFocusMayChange = false;
9248 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
9249 }
9250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009251 // Initialize state of exiting tokens.
9252 for (i=mExitingTokens.size()-1; i>=0; i--) {
9253 mExitingTokens.get(i).hasVisible = false;
9254 }
9255
9256 // Initialize state of exiting applications.
9257 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9258 mExitingAppTokens.get(i).hasVisible = false;
9259 }
9260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009261 boolean orientationChangeComplete = true;
9262 Session holdScreen = null;
9263 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009264 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009265 boolean focusDisplayed = false;
9266 boolean animating = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009267 boolean createWatermark = false;
9268
9269 if (mFxSession == null) {
9270 mFxSession = new SurfaceSession();
9271 createWatermark = true;
9272 }
9273
9274 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009275
9276 Surface.openTransaction();
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009277
9278 if (createWatermark) {
9279 createWatermark();
9280 }
9281 if (mWatermark != null) {
9282 mWatermark.positionSurface(dw, dh);
9283 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08009284 if (mStrictModeFlash != null) {
9285 mStrictModeFlash.positionSurface(dw, dh);
9286 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009288 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009289 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009290 int repeats = 0;
9291 int changes = 0;
9292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009293 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009294 repeats++;
9295 if (repeats > 6) {
9296 Slog.w(TAG, "Animation repeat aborted after too many iterations");
9297 mLayoutNeeded = false;
9298 break;
9299 }
9300
9301 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
9302 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
9303 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
9304 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
9305 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
9306 assignLayersLocked();
9307 mLayoutNeeded = true;
9308 }
9309 }
9310 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
9311 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
9312 if (updateOrientationFromAppTokensLocked()) {
9313 mLayoutNeeded = true;
9314 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
9315 }
9316 }
9317 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
9318 mLayoutNeeded = true;
9319 }
9320 }
9321
9322 // FIRST LOOP: Perform a layout, if needed.
9323 if (repeats < 4) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009324 changes = performLayoutLockedInner(repeats == 0);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009325 if (changes != 0) {
9326 continue;
9327 }
9328 } else {
9329 Slog.w(TAG, "Layout repeat skipped after too many iterations");
9330 changes = 0;
9331 }
9332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009333 final int transactionSequence = ++mTransactionSequence;
9334
9335 // Update animations of all applications, including those
9336 // associated with exiting/removed apps
9337 boolean tokensAnimating = false;
9338 final int NAT = mAppTokens.size();
9339 for (i=0; i<NAT; i++) {
9340 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9341 tokensAnimating = true;
9342 }
9343 }
9344 final int NEAT = mExitingAppTokens.size();
9345 for (i=0; i<NEAT; i++) {
9346 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9347 tokensAnimating = true;
9348 }
9349 }
9350
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009351 // SECOND LOOP: Execute animations and update visibility of windows.
9352
Joe Onorato8a9b2202010-02-26 18:56:32 -08009353 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009354 + transactionSequence + " tokensAnimating="
9355 + tokensAnimating);
9356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009357 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009358
9359 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009360 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009361 boolean forceHiding = false;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009362 WindowState windowDetachedWallpaper = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009363
9364 mPolicy.beginAnimationLw(dw, dh);
9365
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009366 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009368 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009369 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009370
9371 final WindowManager.LayoutParams attrs = w.mAttrs;
9372
9373 if (w.mSurface != null) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009374 // Take care of the window being ready to display.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009375 if (w.commitFinishDrawingLocked(currentTime)) {
9376 if ((w.mAttrs.flags
9377 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009378 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009379 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009380 wallpaperMayChange = true;
9381 }
9382 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009383
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009384 final boolean wasAnimating = w.mAnimating;
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009385
9386 int animDw = dw;
9387 int animDh = dh;
9388
9389 // If the window has moved due to its containing
9390 // content frame changing, then we'd like to animate
9391 // it. The checks here are ordered by what is least
Joe Onorato3fe7f2f2010-11-20 13:48:58 -08009392 // likely to be true first.
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009393 if (w.mContentChanged && !wasAnimating && !w.mLastHidden && !mDisplayFrozen
9394 && (w.mFrame.top != w.mLastFrame.top
9395 || w.mFrame.left != w.mLastFrame.left)
9396 && mPolicy.isScreenOn()) {
9397 // Frame has moved, containing content frame
9398 // has also moved, and we're not currently animating...
9399 // let's do something.
9400 Animation a = AnimationUtils.loadAnimation(mContext,
9401 com.android.internal.R.anim.window_move_from_decor);
9402 w.setAnimation(a);
9403 animDw = w.mLastFrame.left - w.mFrame.left;
9404 animDh = w.mLastFrame.top - w.mFrame.top;
9405 }
9406
9407 // Execute animation.
9408 final boolean nowAnimating = w.stepAnimationLocked(currentTime,
9409 animDw, animDh);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009410
9411 // If this window is animating, make a note that we have
9412 // an animating window and take care of a request to run
9413 // a detached wallpaper animation.
9414 if (nowAnimating) {
9415 if (w.mAnimation != null && w.mAnimation.getDetachWallpaper()) {
9416 windowDetachedWallpaper = w;
9417 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009418 animating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009419 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009420
9421 // If this window's app token is running a detached wallpaper
9422 // animation, make a note so we can ensure the wallpaper is
9423 // displayed behind it.
9424 if (w.mAppToken != null && w.mAppToken.animation != null
9425 && w.mAppToken.animation.getDetachWallpaper()) {
9426 windowDetachedWallpaper = w;
9427 }
9428
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009429 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
9430 wallpaperMayChange = true;
9431 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009432
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009433 if (mPolicy.doesForceHide(w, attrs)) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009434 if (!wasAnimating && nowAnimating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009435 if (DEBUG_VISIBILITY) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009436 "Animation started that could impact force hide: "
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009437 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009438 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009439 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009440 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
9441 forceHiding = true;
9442 }
9443 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9444 boolean changed;
9445 if (forceHiding) {
9446 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009447 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9448 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009449 } else {
9450 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009451 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9452 "Now policy shown: " + w);
9453 if (changed) {
9454 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009455 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009456 // Assume we will need to animate. If
9457 // we don't (because the wallpaper will
9458 // stay with the lock screen), then we will
9459 // clean up later.
9460 Animation a = mPolicy.createForceHideEnterAnimation();
9461 if (a != null) {
9462 w.setAnimation(a);
9463 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009464 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009465 if (mCurrentFocus == null ||
9466 mCurrentFocus.mLayer < w.mLayer) {
9467 // We are showing on to of the current
9468 // focus, so re-evaluate focus to make
9469 // sure it is correct.
9470 mFocusMayChange = true;
9471 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009472 }
9473 }
9474 if (changed && (attrs.flags
9475 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
9476 wallpaperMayChange = true;
9477 }
9478 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009480 mPolicy.animatingWindowLw(w, attrs);
9481 }
9482
9483 final AppWindowToken atoken = w.mAppToken;
9484 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
9485 if (atoken.lastTransactionSequence != transactionSequence) {
9486 atoken.lastTransactionSequence = transactionSequence;
9487 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9488 atoken.startingDisplayed = false;
9489 }
9490 if ((w.isOnScreen() || w.mAttrs.type
9491 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
9492 && !w.mExiting && !w.mDestroying) {
9493 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009494 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009495 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009496 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009497 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009498 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009499 + " pv=" + w.mPolicyVisibility
9500 + " dp=" + w.mDrawPending
9501 + " cdp=" + w.mCommitDrawPending
9502 + " ah=" + w.mAttachedHidden
9503 + " th=" + atoken.hiddenRequested
9504 + " a=" + w.mAnimating);
9505 }
9506 }
9507 if (w != atoken.startingWindow) {
9508 if (!atoken.freezingScreen || !w.mAppFreezing) {
9509 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009510 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009511 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009512 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009513 "tokenMayBeDrawn: " + atoken
9514 + " freezingScreen=" + atoken.freezingScreen
9515 + " mAppFreezing=" + w.mAppFreezing);
9516 tokenMayBeDrawn = true;
9517 }
9518 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009519 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009520 atoken.startingDisplayed = true;
9521 }
9522 }
9523 } else if (w.mReadyToShow) {
9524 w.performShowLocked();
9525 }
9526 }
9527
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009528 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009529
9530 if (tokenMayBeDrawn) {
9531 // See if any windows have been drawn, so they (and others
9532 // associated with them) can now be shown.
9533 final int NT = mTokenList.size();
9534 for (i=0; i<NT; i++) {
9535 AppWindowToken wtoken = mTokenList.get(i).appWindowToken;
9536 if (wtoken == null) {
9537 continue;
9538 }
9539 if (wtoken.freezingScreen) {
9540 int numInteresting = wtoken.numInterestingWindows;
9541 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009542 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009543 "allDrawn: " + wtoken
9544 + " interesting=" + numInteresting
9545 + " drawn=" + wtoken.numDrawnWindows);
9546 wtoken.showAllWindowsLocked();
9547 unsetAppFreezingScreenLocked(wtoken, false, true);
9548 orientationChangeComplete = true;
9549 }
9550 } else if (!wtoken.allDrawn) {
9551 int numInteresting = wtoken.numInterestingWindows;
9552 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009553 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009554 "allDrawn: " + wtoken
9555 + " interesting=" + numInteresting
9556 + " drawn=" + wtoken.numDrawnWindows);
9557 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009558 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009559
9560 // We can now show all of the drawn windows!
9561 if (!mOpeningApps.contains(wtoken)) {
9562 wtoken.showAllWindowsLocked();
9563 }
9564 }
9565 }
9566 }
9567 }
9568
9569 // If we are ready to perform an app transition, check through
9570 // all of the app tokens to be shown and see if they are ready
9571 // to go.
9572 if (mAppTransitionReady) {
9573 int NN = mOpeningApps.size();
9574 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009575 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009576 "Checking " + NN + " opening apps (frozen="
9577 + mDisplayFrozen + " timeout="
9578 + mAppTransitionTimeout + ")...");
9579 if (!mDisplayFrozen && !mAppTransitionTimeout) {
9580 // If the display isn't frozen, wait to do anything until
9581 // all of the apps are ready. Otherwise just go because
9582 // we'll unfreeze the display when everyone is ready.
9583 for (i=0; i<NN && goodToGo; i++) {
9584 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009585 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009586 "Check opening app" + wtoken + ": allDrawn="
9587 + wtoken.allDrawn + " startingDisplayed="
9588 + wtoken.startingDisplayed);
9589 if (!wtoken.allDrawn && !wtoken.startingDisplayed
9590 && !wtoken.startingMoved) {
9591 goodToGo = false;
9592 }
9593 }
9594 }
9595 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009596 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009597 int transit = mNextAppTransition;
9598 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009599 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009600 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009601 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009602 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009603 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009604 mAppTransitionTimeout = false;
9605 mStartingIconInTransition = false;
9606 mSkipAppTransitionAnimation = false;
9607
9608 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
9609
Dianne Hackborna8f60182009-09-01 19:01:50 -07009610 // If there are applications waiting to come to the
9611 // top of the stack, now is the time to move their windows.
9612 // (Note that we don't do apps going to the bottom
9613 // here -- we want to keep their windows in the old
9614 // Z-order until the animation completes.)
9615 if (mToTopApps.size() > 0) {
9616 NN = mAppTokens.size();
9617 for (i=0; i<NN; i++) {
9618 AppWindowToken wtoken = mAppTokens.get(i);
9619 if (wtoken.sendingToTop) {
9620 wtoken.sendingToTop = false;
9621 moveAppWindowsLocked(wtoken, NN, false);
9622 }
9623 }
9624 mToTopApps.clear();
9625 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009626
Dianne Hackborn25994b42009-09-04 14:21:19 -07009627 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009628
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009629 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009630 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009631
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009632 // The top-most window will supply the layout params,
9633 // and we will determine it below.
9634 LayoutParams animLp = null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009635 AppWindowToken animToken = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009636 int bestAnimLayer = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009637
Joe Onorato8a9b2202010-02-26 18:56:32 -08009638 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009639 "New wallpaper target=" + mWallpaperTarget
9640 + ", lower target=" + mLowerWallpaperTarget
9641 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -07009642 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009643 // Do a first pass through the tokens for two
9644 // things:
9645 // (1) Determine if both the closing and opening
9646 // app token sets are wallpaper targets, in which
9647 // case special animations are needed
9648 // (since the wallpaper needs to stay static
9649 // behind them).
9650 // (2) Find the layout params of the top-most
9651 // application window in the tokens, which is
9652 // what will control the animation theme.
9653 final int NC = mClosingApps.size();
9654 NN = NC + mOpeningApps.size();
9655 for (i=0; i<NN; i++) {
9656 AppWindowToken wtoken;
9657 int mode;
9658 if (i < NC) {
9659 wtoken = mClosingApps.get(i);
9660 mode = 1;
9661 } else {
9662 wtoken = mOpeningApps.get(i-NC);
9663 mode = 2;
9664 }
9665 if (mLowerWallpaperTarget != null) {
9666 if (mLowerWallpaperTarget.mAppToken == wtoken
9667 || mUpperWallpaperTarget.mAppToken == wtoken) {
9668 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009669 }
9670 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009671 if (wtoken.appFullscreen) {
9672 WindowState ws = wtoken.findMainWindow();
9673 if (ws != null) {
9674 // If this is a compatibility mode
9675 // window, we will always use its anim.
9676 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
9677 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009678 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009679 bestAnimLayer = Integer.MAX_VALUE;
9680 } else if (ws.mLayer > bestAnimLayer) {
9681 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009682 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009683 bestAnimLayer = ws.mLayer;
9684 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07009685 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009686 }
9687 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009688
Dianne Hackborn25994b42009-09-04 14:21:19 -07009689 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009690 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009691 "Wallpaper animation!");
9692 switch (transit) {
9693 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
9694 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
9695 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
9696 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
9697 break;
9698 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
9699 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
9700 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
9701 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
9702 break;
9703 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009704 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009705 "New transit: " + transit);
9706 } else if (oldWallpaper != null) {
9707 // We are transitioning from an activity with
9708 // a wallpaper to one without.
9709 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009710 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009711 "New transit away from wallpaper: " + transit);
9712 } else if (mWallpaperTarget != null) {
9713 // We are transitioning from an activity without
9714 // a wallpaper to now showing the wallpaper
9715 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009716 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009717 "New transit into wallpaper: " + transit);
9718 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009719
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009720 if ((transit&WindowManagerPolicy.TRANSIT_ENTER_MASK) != 0) {
9721 mLastEnterAnimToken = animToken;
9722 mLastEnterAnimParams = animLp;
9723 } else if (mLastEnterAnimParams != null) {
9724 animLp = mLastEnterAnimParams;
9725 mLastEnterAnimToken = null;
9726 mLastEnterAnimParams = null;
9727 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009728
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009729 // If all closing windows are obscured, then there is
9730 // no need to do an animation. This is the case, for
9731 // example, when this transition is being done behind
9732 // the lock screen.
9733 if (!mPolicy.allowAppAnimationsLw()) {
9734 animLp = null;
9735 }
9736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009737 NN = mOpeningApps.size();
9738 for (i=0; i<NN; i++) {
9739 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009740 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009741 "Now opening app" + wtoken);
9742 wtoken.reportedVisible = false;
9743 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07009744 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009745 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009746 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009747 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009748 wtoken.showAllWindowsLocked();
9749 }
9750 NN = mClosingApps.size();
9751 for (i=0; i<NN; i++) {
9752 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009753 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009754 "Now closing app" + wtoken);
9755 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07009756 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009757 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009758 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009759 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009760 // Force the allDrawn flag, because we want to start
9761 // this guy's animations regardless of whether it's
9762 // gotten drawn.
9763 wtoken.allDrawn = true;
9764 }
9765
Dianne Hackborn8b571a82009-09-25 16:09:43 -07009766 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009767
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009768 mOpeningApps.clear();
9769 mClosingApps.clear();
9770
9771 // This has changed the visibility of windows, so perform
9772 // a new layout to get them all up-to-date.
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009773 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009774 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -07009775 if (!moveInputMethodWindowsIfNeededLocked(true)) {
9776 assignLayersLocked();
9777 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009778 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009779 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009780 }
9781 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009782
Dianne Hackborn16064f92010-03-25 00:47:24 -07009783 int adjResult = 0;
9784
Dianne Hackborna8f60182009-09-01 19:01:50 -07009785 if (!animating && mAppTransitionRunning) {
9786 // We have finished the animation of an app transition. To do
9787 // this, we have delayed a lot of operations like showing and
9788 // hiding apps, moving apps in Z-order, etc. The app token list
9789 // reflects the correct Z-order, but the window list may now
9790 // be out of sync with it. So here we will just rebuild the
9791 // entire app window list. Fun!
9792 mAppTransitionRunning = false;
9793 // Clear information about apps that were moving.
9794 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009795
Dianne Hackborna8f60182009-09-01 19:01:50 -07009796 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009797 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -07009798 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009799 moveInputMethodWindowsIfNeededLocked(false);
9800 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -08009801 // Since the window list has been rebuilt, focus might
9802 // have to be recomputed since the actual order of windows
9803 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009804 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009805 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009806
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009807 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009808 // At this point, there was a window with a wallpaper that
9809 // was force hiding other windows behind it, but now it
9810 // is going away. This may be simple -- just animate
9811 // away the wallpaper and its window -- or it may be
9812 // hard -- the wallpaper now needs to be shown behind
9813 // something that was hidden.
9814 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009815 if (mLowerWallpaperTarget != null
9816 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009817 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009818 "wallpaperForceHiding changed with lower="
9819 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009820 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009821 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
9822 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
9823 if (mLowerWallpaperTarget.mAppToken.hidden) {
9824 // The lower target has become hidden before we
9825 // actually started the animation... let's completely
9826 // re-evaluate everything.
9827 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009828 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009829 }
9830 }
Dianne Hackborn16064f92010-03-25 00:47:24 -07009831 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009832 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009833 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009834 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009835 + " NEW: " + mWallpaperTarget
9836 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009837 if (mLowerWallpaperTarget == null) {
9838 // Whoops, we don't need a special wallpaper animation.
9839 // Clear them out.
9840 forceHiding = false;
9841 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009842 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009843 if (w.mSurface != null) {
9844 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -07009845 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009846 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009847 forceHiding = true;
9848 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9849 if (!w.mAnimating) {
9850 // We set the animation above so it
9851 // is not yet running.
9852 w.clearAnimation();
9853 }
9854 }
9855 }
9856 }
9857 }
9858 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009859
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009860 if (mWindowDetachedWallpaper != windowDetachedWallpaper) {
9861 if (DEBUG_WALLPAPER) Slog.v(TAG,
9862 "Detached wallpaper changed from " + mWindowDetachedWallpaper
9863 + windowDetachedWallpaper);
9864 mWindowDetachedWallpaper = windowDetachedWallpaper;
9865 wallpaperMayChange = true;
9866 }
9867
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009868 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009869 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009870 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -07009871 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009872 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009873
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009874 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009875 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009876 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009877 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009878 assignLayersLocked();
9879 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009880 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009881 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009882 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009883 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009884
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009885 if (mFocusMayChange) {
9886 mFocusMayChange = false;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009887 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009888 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009889 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009890 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009891 }
9892
9893 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009894 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009895 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009896
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009897 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
9898 + Integer.toHexString(changes));
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009899
Jeff Browne33348b2010-07-15 23:54:05 -07009900 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009901 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009902
9903 // THIRD LOOP: Update the surfaces of all windows.
9904
9905 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
9906
9907 boolean obscured = false;
9908 boolean blurring = false;
9909 boolean dimming = false;
9910 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07009911 boolean syswin = false;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07009912 boolean backgroundFillerShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009913
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009914 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009916 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009917 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009918
9919 boolean displayed = false;
9920 final WindowManager.LayoutParams attrs = w.mAttrs;
9921 final int attrFlags = attrs.flags;
9922
9923 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009924 // XXX NOTE: The logic here could be improved. We have
9925 // the decision about whether to resize a window separated
9926 // from whether to hide the surface. This can cause us to
9927 // resize a surface even if we are going to hide it. You
9928 // can see this by (1) holding device in landscape mode on
9929 // home screen; (2) tapping browser icon (device will rotate
9930 // to landscape; (3) tap home. The wallpaper will be resized
9931 // in step 2 but then immediately hidden, causing us to
9932 // have to resize and then redraw it again in step 3. It
9933 // would be nice to figure out how to avoid this, but it is
9934 // difficult because we do need to resize surfaces in some
9935 // cases while they are hidden such as when first showing a
9936 // window.
9937
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009938 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009939 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009940 TAG, "Placing surface #" + i + " " + w.mSurface
9941 + ": new=" + w.mShownFrame + ", old="
9942 + w.mLastShownFrame);
9943
9944 boolean resize;
9945 int width, height;
9946 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
9947 resize = w.mLastRequestedWidth != w.mRequestedWidth ||
9948 w.mLastRequestedHeight != w.mRequestedHeight;
9949 // for a scaled surface, we just want to use
9950 // the requested size.
9951 width = w.mRequestedWidth;
9952 height = w.mRequestedHeight;
9953 w.mLastRequestedWidth = width;
9954 w.mLastRequestedHeight = height;
9955 w.mLastShownFrame.set(w.mShownFrame);
9956 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009957 if (SHOW_TRANSACTIONS) logSurface(w,
9958 "POS " + w.mShownFrame.left
9959 + ", " + w.mShownFrame.top, null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009960 w.mSurfaceX = w.mShownFrame.left;
9961 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009962 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
9963 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009964 Slog.w(TAG, "Error positioning surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009965 if (!recoveringMemory) {
9966 reclaimSomeSurfaceMemoryLocked(w, "position");
9967 }
9968 }
9969 } else {
9970 resize = !w.mLastShownFrame.equals(w.mShownFrame);
9971 width = w.mShownFrame.width();
9972 height = w.mShownFrame.height();
9973 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009974 }
9975
9976 if (resize) {
9977 if (width < 1) width = 1;
9978 if (height < 1) height = 1;
9979 if (w.mSurface != null) {
9980 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009981 if (SHOW_TRANSACTIONS) logSurface(w,
9982 "POS " + w.mShownFrame.left + ","
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009983 + w.mShownFrame.top + " SIZE "
9984 + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009985 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009986 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -07009987 w.mSurfaceW = width;
9988 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009989 w.mSurface.setSize(width, height);
Dianne Hackborn16064f92010-03-25 00:47:24 -07009990 w.mSurfaceX = w.mShownFrame.left;
9991 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009992 w.mSurface.setPosition(w.mShownFrame.left,
9993 w.mShownFrame.top);
9994 } catch (RuntimeException e) {
9995 // If something goes wrong with the surface (such
9996 // as running out of memory), don't take down the
9997 // entire system.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009998 Slog.e(TAG, "Failure updating surface of " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009999 + "size=(" + width + "x" + height
10000 + "), pos=(" + w.mShownFrame.left
10001 + "," + w.mShownFrame.top + ")", e);
10002 if (!recoveringMemory) {
10003 reclaimSomeSurfaceMemoryLocked(w, "size");
10004 }
10005 }
10006 }
10007 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010008 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010009 w.mContentInsetsChanged =
10010 !w.mLastContentInsets.equals(w.mContentInsets);
10011 w.mVisibleInsetsChanged =
10012 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010013 boolean configChanged =
10014 w.mConfiguration != mCurConfiguration
10015 && (w.mConfiguration == null
10016 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010017 if (DEBUG_CONFIGURATION && configChanged) {
10018 Slog.v(TAG, "Win " + w + " config changed: "
10019 + mCurConfiguration);
10020 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010021 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010022 + ": configChanged=" + configChanged
10023 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Romain Guy06882f82009-06-10 13:36:04 -070010024 if (!w.mLastFrame.equals(w.mFrame)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010025 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010026 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010027 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010028 || configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010029 w.mLastFrame.set(w.mFrame);
10030 w.mLastContentInsets.set(w.mContentInsets);
10031 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010032 // If the screen is currently frozen, then keep
10033 // it frozen until this window draws at its new
10034 // orientation.
10035 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010036 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010037 "Resizing while display frozen: " + w);
10038 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010039 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010040 mWindowsFreezingScreen = true;
10041 // XXX should probably keep timeout from
10042 // when we first froze the display.
10043 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10044 mH.sendMessageDelayed(mH.obtainMessage(
10045 H.WINDOW_FREEZE_TIMEOUT), 2000);
10046 }
10047 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010048 // If the orientation is changing, then we need to
10049 // hold off on unfreezing the display until this
10050 // window has been redrawn; to do that, we need
10051 // to go through the process of getting informed
10052 // by the application when it has finished drawing.
10053 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010054 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010055 "Orientation start waiting for draw in "
10056 + w + ", surface " + w.mSurface);
10057 w.mDrawPending = true;
10058 w.mCommitDrawPending = false;
10059 w.mReadyToShow = false;
10060 if (w.mAppToken != null) {
10061 w.mAppToken.allDrawn = false;
10062 }
10063 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010064 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010065 "Resizing window " + w + " to " + w.mFrame);
10066 mResizingWindows.add(w);
10067 } else if (w.mOrientationChanging) {
10068 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010069 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010070 "Orientation not waiting for draw in "
10071 + w + ", surface " + w.mSurface);
10072 w.mOrientationChanging = false;
10073 }
10074 }
10075 }
10076
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010077 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010078 if (!w.mLastHidden) {
10079 //dump();
10080 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010081 if (SHOW_TRANSACTIONS) logSurface(w,
10082 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010083 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010084 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010085 try {
10086 w.mSurface.hide();
10087 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010088 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010089 }
10090 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010091 }
10092 // If we are waiting for this window to handle an
10093 // orientation change, well, it is hidden, so
10094 // doesn't really matter. Note that this does
10095 // introduce a potential glitch if the window
10096 // becomes unhidden before it has drawn for the
10097 // new orientation.
10098 if (w.mOrientationChanging) {
10099 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010100 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010101 "Orientation change skips hidden " + w);
10102 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010103 } else if (w.mLastLayer != w.mAnimLayer
10104 || w.mLastAlpha != w.mShownAlpha
10105 || w.mLastDsDx != w.mDsDx
10106 || w.mLastDtDx != w.mDtDx
10107 || w.mLastDsDy != w.mDsDy
10108 || w.mLastDtDy != w.mDtDy
10109 || w.mLastHScale != w.mHScale
10110 || w.mLastVScale != w.mVScale
10111 || w.mLastHidden) {
10112 displayed = true;
10113 w.mLastAlpha = w.mShownAlpha;
10114 w.mLastLayer = w.mAnimLayer;
10115 w.mLastDsDx = w.mDsDx;
10116 w.mLastDtDx = w.mDtDx;
10117 w.mLastDsDy = w.mDsDy;
10118 w.mLastDtDy = w.mDtDy;
10119 w.mLastHScale = w.mHScale;
10120 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010121 if (SHOW_TRANSACTIONS) logSurface(w,
10122 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010123 + " matrix=[" + (w.mDsDx*w.mHScale)
10124 + "," + (w.mDtDx*w.mVScale)
10125 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010126 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010127 if (w.mSurface != null) {
10128 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010129 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010130 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010131 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010132 w.mSurface.setLayer(w.mAnimLayer);
10133 w.mSurface.setMatrix(
10134 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
10135 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
10136 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010137 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010138 if (!recoveringMemory) {
10139 reclaimSomeSurfaceMemoryLocked(w, "update");
10140 }
10141 }
10142 }
10143
10144 if (w.mLastHidden && !w.mDrawPending
10145 && !w.mCommitDrawPending
10146 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010147 if (SHOW_TRANSACTIONS) logSurface(w,
10148 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010149 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010150 + " during relayout");
10151 if (showSurfaceRobustlyLocked(w)) {
10152 w.mHasDrawn = true;
10153 w.mLastHidden = false;
10154 } else {
10155 w.mOrientationChanging = false;
10156 }
10157 }
10158 if (w.mSurface != null) {
10159 w.mToken.hasVisible = true;
10160 }
10161 } else {
10162 displayed = true;
10163 }
10164
10165 if (displayed) {
10166 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -080010167 if (attrs.width == LayoutParams.MATCH_PARENT
10168 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010169 covered = true;
10170 }
10171 }
10172 if (w.mOrientationChanging) {
10173 if (w.mDrawPending || w.mCommitDrawPending) {
10174 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010175 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010176 "Orientation continue waiting for draw in " + w);
10177 } else {
10178 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010179 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010180 "Orientation change complete in " + w);
10181 }
10182 }
10183 w.mToken.hasVisible = true;
10184 }
10185 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010186 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010187 "Orientation change skips hidden " + w);
10188 w.mOrientationChanging = false;
10189 }
10190
10191 final boolean canBeSeen = w.isDisplayedLw();
10192
10193 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
10194 focusDisplayed = true;
10195 }
10196
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010197 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010199 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010200 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010201 if (w.mSurface != null) {
10202 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
10203 holdScreen = w.mSession;
10204 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010205 if (!syswin && w.mAttrs.screenBrightness >= 0
10206 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010207 screenBrightness = w.mAttrs.screenBrightness;
10208 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010209 if (!syswin && w.mAttrs.buttonBrightness >= 0
10210 && buttonBrightness < 0) {
10211 buttonBrightness = w.mAttrs.buttonBrightness;
10212 }
Mike Lockwood46af6a82010-03-09 08:28:22 -050010213 if (canBeSeen
10214 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
10215 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
10216 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010217 syswin = true;
10218 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010219 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010220
Dianne Hackborn25994b42009-09-04 14:21:19 -070010221 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
10222 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010223 // This window completely covers everything behind it,
10224 // so we want to leave all of them as unblurred (for
10225 // performance reasons).
10226 obscured = true;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010227 } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010228 if (SHOW_TRANSACTIONS) Slog.d(TAG, "showing background filler");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010229 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010230 obscured = true;
10231 if (mBackgroundFillerSurface == null) {
10232 try {
10233 mBackgroundFillerSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010234 "BackGroundFiller",
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010235 0, dw, dh,
10236 PixelFormat.OPAQUE,
10237 Surface.FX_SURFACE_NORMAL);
10238 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010239 Slog.e(TAG, "Exception creating filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010240 }
10241 }
10242 try {
10243 mBackgroundFillerSurface.setPosition(0, 0);
10244 mBackgroundFillerSurface.setSize(dw, dh);
10245 // Using the same layer as Dim because they will never be shown at the
10246 // same time.
10247 mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
10248 mBackgroundFillerSurface.show();
10249 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010250 Slog.e(TAG, "Exception showing filler surface");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010251 }
10252 backgroundFillerShown = true;
10253 mBackgroundFillerShown = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010254 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010255 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010256 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010257 + ": blurring=" + blurring
10258 + " obscured=" + obscured
10259 + " displayed=" + displayed);
10260 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
10261 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010262 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010263 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010264 if (mDimAnimator == null) {
10265 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010266 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010267 mDimAnimator.show(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010268 mDimAnimator.updateParameters(w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010269 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010270 }
10271 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
10272 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010273 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010274 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010275 if (mBlurSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010276 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010277 + mBlurSurface + ": CREATE");
10278 try {
Romain Guy06882f82009-06-10 13:36:04 -070010279 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010280 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010281 -1, 16, 16,
10282 PixelFormat.OPAQUE,
10283 Surface.FX_SURFACE_BLUR);
10284 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010285 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010286 }
10287 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010288 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010289 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10290 + mBlurSurface + ": pos=(0,0) (" +
10291 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010292 mBlurSurface.setPosition(0, 0);
10293 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010294 mBlurSurface.setLayer(w.mAnimLayer-2);
10295 if (!mBlurShown) {
10296 try {
10297 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10298 + mBlurSurface + ": SHOW");
10299 mBlurSurface.show();
10300 } catch (RuntimeException e) {
10301 Slog.w(TAG, "Failure showing blur surface", e);
10302 }
10303 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010304 }
10305 }
10306 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010307 }
10308 }
10309 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010310
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010311 if (obscuredChanged && mWallpaperTarget == w) {
10312 // This is the wallpaper target and its obscured state
10313 // changed... make sure the current wallaper's visibility
10314 // has been updated accordingly.
10315 updateWallpaperVisibilityLocked();
10316 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010317 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010318
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010319 if (backgroundFillerShown == false && mBackgroundFillerShown) {
10320 mBackgroundFillerShown = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010321 if (SHOW_TRANSACTIONS) Slog.d(TAG, "hiding background filler");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010322 try {
10323 mBackgroundFillerSurface.hide();
10324 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010325 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010326 }
10327 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010328
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010329 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010330 animating |= mDimAnimator.updateSurface(dimming, currentTime,
10331 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010332 }
Romain Guy06882f82009-06-10 13:36:04 -070010333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010334 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010335 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010336 + ": HIDE");
10337 try {
10338 mBlurSurface.hide();
10339 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010340 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010341 }
10342 mBlurShown = false;
10343 }
10344
Joe Onorato8a9b2202010-02-26 18:56:32 -080010345 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010346 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010347 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010348 }
10349
Jeff Browne33348b2010-07-15 23:54:05 -070010350 mInputMonitor.updateInputWindowsLw();
10351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010352 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -070010353
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010354 if (mWatermark != null) {
10355 mWatermark.drawIfNeeded();
10356 }
10357
Joe Onorato8a9b2202010-02-26 18:56:32 -080010358 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010359 "With display frozen, orientationChangeComplete="
10360 + orientationChangeComplete);
10361 if (orientationChangeComplete) {
10362 if (mWindowsFreezingScreen) {
10363 mWindowsFreezingScreen = false;
10364 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10365 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010366 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010367 }
Romain Guy06882f82009-06-10 13:36:04 -070010368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010369 i = mResizingWindows.size();
10370 if (i > 0) {
10371 do {
10372 i--;
10373 WindowState win = mResizingWindows.get(i);
10374 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010375 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
10376 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010377 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010378 boolean configChanged =
10379 win.mConfiguration != mCurConfiguration
10380 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010381 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
10382 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
10383 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010384 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010385 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010386 + " / " + mCurConfiguration + " / 0x"
10387 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010388 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010389 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010390 win.mClient.resized(win.mFrame.width(),
10391 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010392 win.mLastVisibleInsets, win.mDrawPending,
10393 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010394 win.mContentInsetsChanged = false;
10395 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010396 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010397 } catch (RemoteException e) {
10398 win.mOrientationChanging = false;
10399 }
10400 } while (i > 0);
10401 mResizingWindows.clear();
10402 }
Romain Guy06882f82009-06-10 13:36:04 -070010403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010404 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010405 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010406 i = mDestroySurface.size();
10407 if (i > 0) {
10408 do {
10409 i--;
10410 WindowState win = mDestroySurface.get(i);
10411 win.mDestroying = false;
10412 if (mInputMethodWindow == win) {
10413 mInputMethodWindow = null;
10414 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010415 if (win == mWallpaperTarget) {
10416 wallpaperDestroyed = true;
10417 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010418 win.destroySurfaceLocked();
10419 } while (i > 0);
10420 mDestroySurface.clear();
10421 }
10422
10423 // Time to remove any exiting tokens?
10424 for (i=mExitingTokens.size()-1; i>=0; i--) {
10425 WindowToken token = mExitingTokens.get(i);
10426 if (!token.hasVisible) {
10427 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010428 if (token.windowType == TYPE_WALLPAPER) {
10429 mWallpaperTokens.remove(token);
10430 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010431 }
10432 }
10433
10434 // Time to remove any exiting applications?
10435 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
10436 AppWindowToken token = mExitingAppTokens.get(i);
10437 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070010438 // Make sure there is no animation running on this token,
10439 // so any windows associated with it will be removed as
10440 // soon as their animations are complete
10441 token.animation = null;
10442 token.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010443 mAppTokens.remove(token);
10444 mExitingAppTokens.remove(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010445 if (mLastEnterAnimToken == token) {
10446 mLastEnterAnimToken = null;
10447 mLastEnterAnimParams = null;
10448 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010449 }
10450 }
10451
Dianne Hackborna8f60182009-09-01 19:01:50 -070010452 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010453
Dianne Hackborna8f60182009-09-01 19:01:50 -070010454 if (!animating && mAppTransitionRunning) {
10455 // We have finished the animation of an app transition. To do
10456 // this, we have delayed a lot of operations like showing and
10457 // hiding apps, moving apps in Z-order, etc. The app token list
10458 // reflects the correct Z-order, but the window list may now
10459 // be out of sync with it. So here we will just rebuild the
10460 // entire app window list. Fun!
10461 mAppTransitionRunning = false;
10462 needRelayout = true;
10463 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010464 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010465 // Clear information about apps that were moving.
10466 mToBottomApps.clear();
10467 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010469 if (focusDisplayed) {
10470 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
10471 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010472 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010473 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010474 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010475 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010476 requestAnimationLocked(0);
10477 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010478 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
10479 }
Jeff Browneb857f12010-07-16 10:06:33 -070010480
Jeff Browne33348b2010-07-15 23:54:05 -070010481 mInputMonitor.updateInputWindowsLw();
Jeff Browneb857f12010-07-16 10:06:33 -070010482
Jeff Brown8e03b752010-06-13 19:16:55 -070010483 setHoldScreenLocked(holdScreen != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010484 if (screenBrightness < 0 || screenBrightness > 1.0f) {
10485 mPowerManager.setScreenBrightnessOverride(-1);
10486 } else {
10487 mPowerManager.setScreenBrightnessOverride((int)
10488 (screenBrightness * Power.BRIGHTNESS_ON));
10489 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010490 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
10491 mPowerManager.setButtonBrightnessOverride(-1);
10492 } else {
10493 mPowerManager.setButtonBrightnessOverride((int)
10494 (buttonBrightness * Power.BRIGHTNESS_ON));
10495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010496 if (holdScreen != mHoldingScreenOn) {
10497 mHoldingScreenOn = holdScreen;
10498 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
10499 mH.sendMessage(m);
10500 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010501
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010502 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010503 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010504 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
10505 LocalPowerManager.BUTTON_EVENT, true);
10506 mTurnOnScreen = false;
10507 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080010508
10509 // Check to see if we are now in a state where the screen should
10510 // be enabled, because the window obscured flags have changed.
10511 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010512 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070010513
10514 /**
10515 * Must be called with the main window manager lock held.
10516 */
10517 void setHoldScreenLocked(boolean holding) {
10518 boolean state = mHoldingScreenWakeLock.isHeld();
10519 if (holding != state) {
10520 if (holding) {
10521 mHoldingScreenWakeLock.acquire();
10522 } else {
10523 mPolicy.screenOnStoppedLw();
10524 mHoldingScreenWakeLock.release();
10525 }
10526 }
10527 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010528
10529 void requestAnimationLocked(long delay) {
10530 if (!mAnimationPending) {
10531 mAnimationPending = true;
10532 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
10533 }
10534 }
Romain Guy06882f82009-06-10 13:36:04 -070010535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010536 /**
10537 * Have the surface flinger show a surface, robustly dealing with
10538 * error conditions. In particular, if there is not enough memory
10539 * to show the surface, then we will try to get rid of other surfaces
10540 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -070010541 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010542 * @return Returns true if the surface was successfully shown.
10543 */
10544 boolean showSurfaceRobustlyLocked(WindowState win) {
10545 try {
10546 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010547 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010548 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010549 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010550 if (DEBUG_VISIBILITY) Slog.v(TAG,
10551 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010552 win.mTurnOnScreen = false;
10553 mTurnOnScreen = true;
10554 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010555 }
10556 return true;
10557 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010558 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010559 }
Romain Guy06882f82009-06-10 13:36:04 -070010560
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010561 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -070010562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010563 return false;
10564 }
Romain Guy06882f82009-06-10 13:36:04 -070010565
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010566 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
10567 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -070010568
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010569 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010570 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -070010571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010572 if (mForceRemoves == null) {
10573 mForceRemoves = new ArrayList<WindowState>();
10574 }
Romain Guy06882f82009-06-10 13:36:04 -070010575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010576 long callingIdentity = Binder.clearCallingIdentity();
10577 try {
10578 // There was some problem... first, do a sanity check of the
10579 // window list to make sure we haven't left any dangling surfaces
10580 // around.
10581 int N = mWindows.size();
10582 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010583 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010584 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010585 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010586 if (ws.mSurface != null) {
10587 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010588 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010589 + ws + " surface=" + ws.mSurface
10590 + " token=" + win.mToken
10591 + " pid=" + ws.mSession.mPid
10592 + " uid=" + ws.mSession.mUid);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010593 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010594 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010595 ws.mSurface = null;
10596 mForceRemoves.add(ws);
10597 i--;
10598 N--;
10599 leakedSurface = true;
10600 } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010601 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010602 + ws + " surface=" + ws.mSurface
10603 + " token=" + win.mAppToken);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010604 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010605 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010606 ws.mSurface = null;
10607 leakedSurface = true;
10608 }
10609 }
10610 }
Romain Guy06882f82009-06-10 13:36:04 -070010611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010612 boolean killedApps = false;
10613 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010614 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010615 SparseIntArray pidCandidates = new SparseIntArray();
10616 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010617 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010618 if (ws.mSurface != null) {
10619 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
10620 }
10621 }
10622 if (pidCandidates.size() > 0) {
10623 int[] pids = new int[pidCandidates.size()];
10624 for (int i=0; i<pids.length; i++) {
10625 pids[i] = pidCandidates.keyAt(i);
10626 }
10627 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -070010628 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010629 killedApps = true;
10630 }
10631 } catch (RemoteException e) {
10632 }
10633 }
10634 }
Romain Guy06882f82009-06-10 13:36:04 -070010635
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010636 if (leakedSurface || killedApps) {
10637 // We managed to reclaim some memory, so get rid of the trouble
10638 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010639 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010640 if (surface != null) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010641 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010642 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010643 win.mSurface = null;
10644 }
Romain Guy06882f82009-06-10 13:36:04 -070010645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010646 try {
10647 win.mClient.dispatchGetNewSurface();
10648 } catch (RemoteException e) {
10649 }
10650 }
10651 } finally {
10652 Binder.restoreCallingIdentity(callingIdentity);
10653 }
10654 }
Romain Guy06882f82009-06-10 13:36:04 -070010655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010656 private boolean updateFocusedWindowLocked(int mode) {
10657 WindowState newFocus = computeFocusedWindowLocked();
10658 if (mCurrentFocus != newFocus) {
10659 // This check makes sure that we don't already have the focus
10660 // change message pending.
10661 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
10662 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010663 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010664 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
10665 final WindowState oldFocus = mCurrentFocus;
10666 mCurrentFocus = newFocus;
10667 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -070010668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010669 final WindowState imWindow = mInputMethodWindow;
10670 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010671 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010672 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010673 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
10674 mLayoutNeeded = true;
10675 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010676 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -080010677 performLayoutLockedInner(true);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010678 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
10679 // Client will do the layout, but we need to assign layers
10680 // for handleNewWindowLocked() below.
10681 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010682 }
10683 }
Jeff Brown349703e2010-06-22 01:27:15 -070010684
10685 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
10686 // If we defer assigning layers, then the caller is responsible for
10687 // doing this part.
10688 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010689 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010690 return true;
10691 }
10692 return false;
10693 }
Jeff Brown349703e2010-06-22 01:27:15 -070010694
10695 private void finishUpdateFocusedWindowAfterAssignLayersLocked() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010696 mInputMonitor.setInputFocusLw(mCurrentFocus);
Jeff Brown349703e2010-06-22 01:27:15 -070010697 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010698
10699 private WindowState computeFocusedWindowLocked() {
10700 WindowState result = null;
10701 WindowState win;
10702
10703 int i = mWindows.size() - 1;
10704 int nextAppIndex = mAppTokens.size()-1;
10705 WindowToken nextApp = nextAppIndex >= 0
10706 ? mAppTokens.get(nextAppIndex) : null;
10707
10708 while (i >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -070010709 win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010710
Joe Onorato8a9b2202010-02-26 18:56:32 -080010711 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010712 TAG, "Looking for focus: " + i
10713 + " = " + win
10714 + ", flags=" + win.mAttrs.flags
10715 + ", canReceive=" + win.canReceiveKeys());
10716
10717 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070010718
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010719 // If this window's application has been removed, just skip it.
10720 if (thisApp != null && thisApp.removed) {
10721 i--;
10722 continue;
10723 }
Romain Guy06882f82009-06-10 13:36:04 -070010724
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010725 // If there is a focused app, don't allow focus to go to any
10726 // windows below it. If this is an application window, step
10727 // through the app tokens until we find its app.
10728 if (thisApp != null && nextApp != null && thisApp != nextApp
10729 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
10730 int origAppIndex = nextAppIndex;
10731 while (nextAppIndex > 0) {
10732 if (nextApp == mFocusedApp) {
10733 // Whoops, we are below the focused app... no focus
10734 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080010735 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010736 TAG, "Reached focused app: " + mFocusedApp);
10737 return null;
10738 }
10739 nextAppIndex--;
10740 nextApp = mAppTokens.get(nextAppIndex);
10741 if (nextApp == thisApp) {
10742 break;
10743 }
10744 }
10745 if (thisApp != nextApp) {
10746 // Uh oh, the app token doesn't exist! This shouldn't
10747 // happen, but if it does we can get totally hosed...
10748 // so restart at the original app.
10749 nextAppIndex = origAppIndex;
10750 nextApp = mAppTokens.get(nextAppIndex);
10751 }
10752 }
10753
10754 // Dispatch to this window if it is wants key events.
10755 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010756 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010757 TAG, "Found focus @ " + i + " = " + win);
10758 result = win;
10759 break;
10760 }
10761
10762 i--;
10763 }
10764
10765 return result;
10766 }
10767
10768 private void startFreezingDisplayLocked() {
10769 if (mDisplayFrozen) {
10770 return;
10771 }
Romain Guy06882f82009-06-10 13:36:04 -070010772
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010773 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070010774
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010775 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010776 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010777 if (mFreezeGcPending != 0) {
10778 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010779 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010780 mH.removeMessages(H.FORCE_GC);
10781 Runtime.getRuntime().gc();
10782 mFreezeGcPending = now;
10783 }
10784 } else {
10785 mFreezeGcPending = now;
10786 }
Romain Guy06882f82009-06-10 13:36:04 -070010787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010788 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -070010789
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010790 mInputMonitor.freezeInputDispatchingLw();
Jeff Brown349703e2010-06-22 01:27:15 -070010791
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010792 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
10793 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010794 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010795 mAppTransitionReady = true;
10796 }
Romain Guy06882f82009-06-10 13:36:04 -070010797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010798 if (PROFILE_ORIENTATION) {
10799 File file = new File("/data/system/frozen");
10800 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
10801 }
10802 Surface.freezeDisplay(0);
10803 }
Romain Guy06882f82009-06-10 13:36:04 -070010804
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010805 private void stopFreezingDisplayLocked() {
10806 if (!mDisplayFrozen) {
10807 return;
10808 }
Romain Guy06882f82009-06-10 13:36:04 -070010809
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010810 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
10811 return;
10812 }
10813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010814 mDisplayFrozen = false;
10815 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
10816 if (PROFILE_ORIENTATION) {
10817 Debug.stopMethodTracing();
10818 }
10819 Surface.unfreezeDisplay(0);
Romain Guy06882f82009-06-10 13:36:04 -070010820
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010821 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010822
Christopher Tateb696aee2010-04-02 19:08:30 -070010823 // While the display is frozen we don't re-compute the orientation
10824 // to avoid inconsistent states. However, something interesting
10825 // could have actually changed during that time so re-evaluate it
10826 // now to catch that.
10827 if (updateOrientationFromAppTokensLocked()) {
10828 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
10829 }
10830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010831 // A little kludge: a lot could have happened while the
10832 // display was frozen, so now that we are coming back we
10833 // do a gc so that any remote references the system
10834 // processes holds on others can be released if they are
10835 // no longer needed.
10836 mH.removeMessages(H.FORCE_GC);
10837 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
10838 2000);
Romain Guy06882f82009-06-10 13:36:04 -070010839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010840 mScreenFrozenLock.release();
10841 }
Romain Guy06882f82009-06-10 13:36:04 -070010842
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010843 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
10844 DisplayMetrics dm) {
10845 if (index < tokens.length) {
10846 String str = tokens[index];
10847 if (str != null && str.length() > 0) {
10848 try {
10849 int val = Integer.parseInt(str);
10850 return val;
10851 } catch (Exception e) {
10852 }
10853 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010854 }
10855 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
10856 return defDps;
10857 }
10858 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
10859 return val;
10860 }
10861
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070010862 static class Watermark {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010863 final String[] mTokens;
10864 final String mText;
10865 final Paint mTextPaint;
10866 final int mTextWidth;
10867 final int mTextHeight;
10868 final int mTextAscent;
10869 final int mTextDescent;
10870 final int mDeltaX;
10871 final int mDeltaY;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010872
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010873 Surface mSurface;
10874 int mLastDW;
10875 int mLastDH;
10876 boolean mDrawNeeded;
10877
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070010878 Watermark(Display display, SurfaceSession session, String[] tokens) {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010879 final DisplayMetrics dm = new DisplayMetrics();
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070010880 display.getMetrics(dm);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010881
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010882 if (false) {
10883 Log.i(TAG, "*********************** WATERMARK");
10884 for (int i=0; i<tokens.length; i++) {
10885 Log.i(TAG, " TOKEN #" + i + ": " + tokens[i]);
10886 }
10887 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010888
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010889 mTokens = tokens;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010890
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010891 StringBuilder builder = new StringBuilder(32);
10892 int len = mTokens[0].length();
10893 len = len & ~1;
10894 for (int i=0; i<len; i+=2) {
10895 int c1 = mTokens[0].charAt(i);
10896 int c2 = mTokens[0].charAt(i+1);
10897 if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10;
10898 else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10;
10899 else c1 -= '0';
10900 if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10;
10901 else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10;
10902 else c2 -= '0';
10903 builder.append((char)(255-((c1*16)+c2)));
10904 }
10905 mText = builder.toString();
10906 if (false) {
10907 Log.i(TAG, "Final text: " + mText);
10908 }
10909
10910 int fontSize = getPropertyInt(tokens, 1,
10911 TypedValue.COMPLEX_UNIT_DIP, 20, dm);
10912
10913 mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
10914 mTextPaint.setTextSize(fontSize);
10915 mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
10916
10917 FontMetricsInt fm = mTextPaint.getFontMetricsInt();
10918 mTextWidth = (int)mTextPaint.measureText(mText);
10919 mTextAscent = fm.ascent;
10920 mTextDescent = fm.descent;
10921 mTextHeight = fm.descent - fm.ascent;
10922
10923 mDeltaX = getPropertyInt(tokens, 2,
10924 TypedValue.COMPLEX_UNIT_PX, mTextWidth*2, dm);
10925 mDeltaY = getPropertyInt(tokens, 3,
10926 TypedValue.COMPLEX_UNIT_PX, mTextHeight*3, dm);
10927 int shadowColor = getPropertyInt(tokens, 4,
10928 TypedValue.COMPLEX_UNIT_PX, 0xb0000000, dm);
10929 int color = getPropertyInt(tokens, 5,
10930 TypedValue.COMPLEX_UNIT_PX, 0x60ffffff, dm);
10931 int shadowRadius = getPropertyInt(tokens, 6,
10932 TypedValue.COMPLEX_UNIT_PX, 7, dm);
10933 int shadowDx = getPropertyInt(tokens, 8,
10934 TypedValue.COMPLEX_UNIT_PX, 0, dm);
10935 int shadowDy = getPropertyInt(tokens, 9,
10936 TypedValue.COMPLEX_UNIT_PX, 0, dm);
10937
10938 mTextPaint.setColor(color);
10939 mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010940
10941 try {
10942 mSurface = new Surface(session, 0,
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010943 "WatermarkSurface", -1, 1, 1, PixelFormat.TRANSLUCENT, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010944 mSurface.setLayer(TYPE_LAYER_MULTIPLIER*100);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010945 mSurface.setPosition(0, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010946 mSurface.show();
10947 } catch (OutOfResourcesException e) {
10948 }
10949 }
10950
10951 void positionSurface(int dw, int dh) {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010952 if (mLastDW != dw || mLastDH != dh) {
10953 mLastDW = dw;
10954 mLastDH = dh;
10955 mSurface.setSize(dw, dh);
10956 mDrawNeeded = true;
10957 }
10958 }
10959
10960 void drawIfNeeded() {
10961 if (mDrawNeeded) {
10962 final int dw = mLastDW;
10963 final int dh = mLastDH;
10964
10965 mDrawNeeded = false;
10966 Rect dirty = new Rect(0, 0, dw, dh);
10967 Canvas c = null;
10968 try {
10969 c = mSurface.lockCanvas(dirty);
10970 } catch (IllegalArgumentException e) {
10971 } catch (OutOfResourcesException e) {
10972 }
10973 if (c != null) {
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070010974 c.drawColor(0, PorterDuff.Mode.CLEAR);
10975
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010976 int deltaX = mDeltaX;
10977 int deltaY = mDeltaY;
10978
10979 // deltaX shouldn't be close to a round fraction of our
10980 // x step, or else things will line up too much.
10981 int div = (dw+mTextWidth)/deltaX;
10982 int rem = (dw+mTextWidth) - (div*deltaX);
10983 int qdelta = deltaX/4;
10984 if (rem < qdelta || rem > (deltaX-qdelta)) {
10985 deltaX += deltaX/3;
10986 }
10987
10988 int y = -mTextHeight;
10989 int x = -mTextWidth;
10990 while (y < (dh+mTextHeight)) {
10991 c.drawText(mText, x, y, mTextPaint);
10992 x += deltaX;
10993 if (x >= dw) {
10994 x -= (dw+mTextWidth);
10995 y += deltaY;
10996 }
10997 }
10998 mSurface.unlockCanvasAndPost(c);
10999 }
11000 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011001 }
11002 }
11003
11004 void createWatermark() {
11005 if (mWatermark != null) {
11006 return;
11007 }
11008
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011009 File file = new File("/system/etc/setup.conf");
11010 FileInputStream in = null;
11011 try {
11012 in = new FileInputStream(file);
11013 DataInputStream ind = new DataInputStream(in);
11014 String line = ind.readLine();
11015 if (line != null) {
11016 String[] toks = line.split("%");
11017 if (toks != null && toks.length > 0) {
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011018 mWatermark = new Watermark(mDisplay, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011019 }
11020 }
11021 } catch (FileNotFoundException e) {
11022 } catch (IOException e) {
11023 } finally {
11024 if (in != null) {
11025 try {
11026 in.close();
11027 } catch (IOException e) {
11028 }
11029 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011030 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011031 }
11032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011033 @Override
11034 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11035 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
11036 != PackageManager.PERMISSION_GRANTED) {
11037 pw.println("Permission Denial: can't dump WindowManager from from pid="
11038 + Binder.getCallingPid()
11039 + ", uid=" + Binder.getCallingUid());
11040 return;
11041 }
Romain Guy06882f82009-06-10 13:36:04 -070011042
Jeff Brown00fa7bd2010-07-02 15:37:36 -070011043 mInputManager.dump(pw);
Dianne Hackborna2e92262010-03-02 17:19:29 -080011044 pw.println(" ");
11045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011046 synchronized(mWindowMap) {
11047 pw.println("Current Window Manager state:");
11048 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070011049 WindowState w = mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011050 pw.print(" Window #"); pw.print(i); pw.print(' ');
11051 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011052 w.dump(pw, " ");
11053 }
11054 if (mInputMethodDialogs.size() > 0) {
11055 pw.println(" ");
11056 pw.println(" Input method dialogs:");
11057 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
11058 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011059 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011060 }
11061 }
11062 if (mPendingRemove.size() > 0) {
11063 pw.println(" ");
11064 pw.println(" Remove pending for:");
11065 for (int i=mPendingRemove.size()-1; i>=0; i--) {
11066 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011067 pw.print(" Remove #"); pw.print(i); pw.print(' ');
11068 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011069 w.dump(pw, " ");
11070 }
11071 }
11072 if (mForceRemoves != null && mForceRemoves.size() > 0) {
11073 pw.println(" ");
11074 pw.println(" Windows force removing:");
11075 for (int i=mForceRemoves.size()-1; i>=0; i--) {
11076 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011077 pw.print(" Removing #"); pw.print(i); pw.print(' ');
11078 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011079 w.dump(pw, " ");
11080 }
11081 }
11082 if (mDestroySurface.size() > 0) {
11083 pw.println(" ");
11084 pw.println(" Windows waiting to destroy their surface:");
11085 for (int i=mDestroySurface.size()-1; i>=0; i--) {
11086 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011087 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
11088 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011089 w.dump(pw, " ");
11090 }
11091 }
11092 if (mLosingFocus.size() > 0) {
11093 pw.println(" ");
11094 pw.println(" Windows losing focus:");
11095 for (int i=mLosingFocus.size()-1; i>=0; i--) {
11096 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011097 pw.print(" Losing #"); pw.print(i); pw.print(' ');
11098 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011099 w.dump(pw, " ");
11100 }
11101 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011102 if (mResizingWindows.size() > 0) {
11103 pw.println(" ");
11104 pw.println(" Windows waiting to resize:");
11105 for (int i=mResizingWindows.size()-1; i>=0; i--) {
11106 WindowState w = mResizingWindows.get(i);
11107 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
11108 pw.print(w); pw.println(":");
11109 w.dump(pw, " ");
11110 }
11111 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011112 if (mSessions.size() > 0) {
11113 pw.println(" ");
11114 pw.println(" All active sessions:");
11115 Iterator<Session> it = mSessions.iterator();
11116 while (it.hasNext()) {
11117 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011118 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011119 s.dump(pw, " ");
11120 }
11121 }
11122 if (mTokenMap.size() > 0) {
11123 pw.println(" ");
11124 pw.println(" All tokens:");
11125 Iterator<WindowToken> it = mTokenMap.values().iterator();
11126 while (it.hasNext()) {
11127 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011128 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011129 token.dump(pw, " ");
11130 }
11131 }
11132 if (mTokenList.size() > 0) {
11133 pw.println(" ");
11134 pw.println(" Window token list:");
11135 for (int i=0; i<mTokenList.size(); i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011136 pw.print(" #"); pw.print(i); pw.print(": ");
11137 pw.println(mTokenList.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011138 }
11139 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070011140 if (mWallpaperTokens.size() > 0) {
11141 pw.println(" ");
11142 pw.println(" Wallpaper tokens:");
11143 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
11144 WindowToken token = mWallpaperTokens.get(i);
11145 pw.print(" Wallpaper #"); pw.print(i);
11146 pw.print(' '); pw.print(token); pw.println(':');
11147 token.dump(pw, " ");
11148 }
11149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011150 if (mAppTokens.size() > 0) {
11151 pw.println(" ");
11152 pw.println(" Application tokens in Z order:");
11153 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011154 pw.print(" App #"); pw.print(i); pw.print(": ");
11155 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011156 }
11157 }
11158 if (mFinishedStarting.size() > 0) {
11159 pw.println(" ");
11160 pw.println(" Finishing start of application tokens:");
11161 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
11162 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011163 pw.print(" Finished Starting #"); pw.print(i);
11164 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011165 token.dump(pw, " ");
11166 }
11167 }
11168 if (mExitingTokens.size() > 0) {
11169 pw.println(" ");
11170 pw.println(" Exiting tokens:");
11171 for (int i=mExitingTokens.size()-1; i>=0; i--) {
11172 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011173 pw.print(" Exiting #"); pw.print(i);
11174 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011175 token.dump(pw, " ");
11176 }
11177 }
11178 if (mExitingAppTokens.size() > 0) {
11179 pw.println(" ");
11180 pw.println(" Exiting application tokens:");
11181 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
11182 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011183 pw.print(" Exiting App #"); pw.print(i);
11184 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011185 token.dump(pw, " ");
11186 }
11187 }
11188 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011189 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
11190 pw.print(" mLastFocus="); pw.println(mLastFocus);
11191 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
11192 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
11193 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070011194 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011195 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
11196 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
11197 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
11198 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -080011199 if (mWindowDetachedWallpaper != null) {
11200 pw.print(" mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper);
11201 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011202 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
11203 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
11204 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011205 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
11206 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
11207 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
11208 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011209 if (mDimAnimator != null) {
11210 mDimAnimator.printTo(pw);
11211 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080011212 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011213 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011214 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070011215 pw.print(mInputMethodAnimLayerAdjustment);
11216 pw.print(" mWallpaperAnimLayerAdjustment=");
11217 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011218 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
11219 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011220 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
11221 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011222 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
11223 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011224 pw.print(" mRotation="); pw.print(mRotation);
11225 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
11226 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
11227 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
11228 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
11229 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
11230 pw.print(" mNextAppTransition=0x");
11231 pw.print(Integer.toHexString(mNextAppTransition));
11232 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070011233 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011234 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011235 if (mNextAppTransitionPackage != null) {
11236 pw.print(" mNextAppTransitionPackage=");
11237 pw.print(mNextAppTransitionPackage);
11238 pw.print(", mNextAppTransitionEnter=0x");
11239 pw.print(Integer.toHexString(mNextAppTransitionEnter));
11240 pw.print(", mNextAppTransitionExit=0x");
11241 pw.print(Integer.toHexString(mNextAppTransitionExit));
11242 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011243 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
11244 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011245 if (mLastEnterAnimToken != null || mLastEnterAnimToken != null) {
11246 pw.print(" mLastEnterAnimToken="); pw.print(mLastEnterAnimToken);
11247 pw.print(", mLastEnterAnimParams="); pw.println(mLastEnterAnimParams);
11248 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011249 if (mOpeningApps.size() > 0) {
11250 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
11251 }
11252 if (mClosingApps.size() > 0) {
11253 pw.print(" mClosingApps="); pw.println(mClosingApps);
11254 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011255 if (mToTopApps.size() > 0) {
11256 pw.print(" mToTopApps="); pw.println(mToTopApps);
11257 }
11258 if (mToBottomApps.size() > 0) {
11259 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
11260 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011261 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
11262 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011263 }
11264 }
11265
Jeff Brown349703e2010-06-22 01:27:15 -070011266 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011267 public void monitor() {
11268 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050011269 synchronized (mKeyguardTokenWatcher) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070011270 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011271
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011272 /**
11273 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011274 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011275 */
11276 private static class DimAnimator {
11277 Surface mDimSurface;
11278 boolean mDimShown = false;
11279 float mDimCurrentAlpha;
11280 float mDimTargetAlpha;
11281 float mDimDeltaPerMs;
11282 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011283
11284 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011285
11286 DimAnimator (SurfaceSession session) {
11287 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011288 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011289 + mDimSurface + ": CREATE");
11290 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011291 mDimSurface = new Surface(session, 0,
11292 "DimSurface",
11293 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011294 Surface.FX_SURFACE_DIM);
Maciej Białka9ee5c222010-03-24 10:25:40 +010011295 mDimSurface.setAlpha(0.0f);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011296 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011297 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011298 }
11299 }
11300 }
11301
11302 /**
11303 * Show the dim surface.
11304 */
11305 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011306 if (!mDimShown) {
11307 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
11308 dw + "x" + dh + ")");
11309 mDimShown = true;
11310 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011311 mLastDimWidth = dw;
11312 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070011313 mDimSurface.setPosition(0, 0);
11314 mDimSurface.setSize(dw, dh);
11315 mDimSurface.show();
11316 } catch (RuntimeException e) {
11317 Slog.w(TAG, "Failure showing dim surface", e);
11318 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011319 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
11320 mLastDimWidth = dw;
11321 mLastDimHeight = dh;
11322 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011323 }
11324 }
11325
11326 /**
11327 * Set's the dim surface's layer and update dim parameters that will be used in
11328 * {@link updateSurface} after all windows are examined.
11329 */
11330 void updateParameters(WindowState w, long currentTime) {
11331 mDimSurface.setLayer(w.mAnimLayer-1);
11332
11333 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011334 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011335 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011336 if (mDimTargetAlpha != target) {
11337 // If the desired dim level has changed, then
11338 // start an animation to it.
11339 mLastDimAnimTime = currentTime;
11340 long duration = (w.mAnimating && w.mAnimation != null)
11341 ? w.mAnimation.computeDurationHint()
11342 : DEFAULT_DIM_DURATION;
11343 if (target > mDimTargetAlpha) {
11344 // This is happening behind the activity UI,
11345 // so we can make it run a little longer to
11346 // give a stronger impression without disrupting
11347 // the user.
11348 duration *= DIM_DURATION_MULTIPLIER;
11349 }
11350 if (duration < 1) {
11351 // Don't divide by zero
11352 duration = 1;
11353 }
11354 mDimTargetAlpha = target;
11355 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
11356 }
11357 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011358
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011359 /**
11360 * Updating the surface's alpha. Returns true if the animation continues, or returns
11361 * false when the animation is finished and the dim surface is hidden.
11362 */
11363 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
11364 if (!dimming) {
11365 if (mDimTargetAlpha != 0) {
11366 mLastDimAnimTime = currentTime;
11367 mDimTargetAlpha = 0;
11368 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
11369 }
11370 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011371
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011372 boolean animating = false;
11373 if (mLastDimAnimTime != 0) {
11374 mDimCurrentAlpha += mDimDeltaPerMs
11375 * (currentTime-mLastDimAnimTime);
11376 boolean more = true;
11377 if (displayFrozen) {
11378 // If the display is frozen, there is no reason to animate.
11379 more = false;
11380 } else if (mDimDeltaPerMs > 0) {
11381 if (mDimCurrentAlpha > mDimTargetAlpha) {
11382 more = false;
11383 }
11384 } else if (mDimDeltaPerMs < 0) {
11385 if (mDimCurrentAlpha < mDimTargetAlpha) {
11386 more = false;
11387 }
11388 } else {
11389 more = false;
11390 }
11391
11392 // Do we need to continue animating?
11393 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011394 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011395 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
11396 mLastDimAnimTime = currentTime;
11397 mDimSurface.setAlpha(mDimCurrentAlpha);
11398 animating = true;
11399 } else {
11400 mDimCurrentAlpha = mDimTargetAlpha;
11401 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011402 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011403 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
11404 mDimSurface.setAlpha(mDimCurrentAlpha);
11405 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011406 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011407 + ": HIDE");
11408 try {
11409 mDimSurface.hide();
11410 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011411 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011412 }
11413 mDimShown = false;
11414 }
11415 }
11416 }
11417 return animating;
11418 }
11419
11420 public void printTo(PrintWriter pw) {
11421 pw.print(" mDimShown="); pw.print(mDimShown);
11422 pw.print(" current="); pw.print(mDimCurrentAlpha);
11423 pw.print(" target="); pw.print(mDimTargetAlpha);
11424 pw.print(" delta="); pw.print(mDimDeltaPerMs);
11425 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
11426 }
11427 }
11428
11429 /**
11430 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
11431 * This is used for opening/closing transition for apps in compatible mode.
11432 */
11433 private static class FadeInOutAnimation extends Animation {
11434 int mWidth;
11435 boolean mFadeIn;
11436
11437 public FadeInOutAnimation(boolean fadeIn) {
11438 setInterpolator(new AccelerateInterpolator());
11439 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
11440 mFadeIn = fadeIn;
11441 }
11442
11443 @Override
11444 protected void applyTransformation(float interpolatedTime, Transformation t) {
11445 float x = interpolatedTime;
11446 if (!mFadeIn) {
11447 x = 1.0f - x; // reverse the interpolation for fade out
11448 }
11449 if (x < 0.5) {
11450 // move the window out of the screen.
11451 t.getMatrix().setTranslate(mWidth, 0);
11452 } else {
11453 t.getMatrix().setTranslate(0, 0);// show
11454 t.setAlpha((x - 0.5f) * 2);
11455 }
11456 }
11457
11458 @Override
11459 public void initialize(int width, int height, int parentWidth, int parentHeight) {
11460 // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
11461 mWidth = width;
11462 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011463
11464 @Override
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -070011465 public int getZAdjustment() {
11466 return Animation.ZORDER_TOP;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011467 }
11468 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011469}