blob: 5516dea82067cbb875778f3e173f968fedacb159 [file] [log] [blame]
Craig Mautnera2c77052012-03-26 12:14:43 -07001// Copyright 2012 Google Inc. All Rights Reserved.
2
3package com.android.server.wm;
4
Craig Mautnerc2f9be02012-03-27 17:32:29 -07005import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
6import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
7
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008import static com.android.server.wm.WindowManagerService.LayoutFields.CLEAR_ORIENTATION_CHANGE_COMPLETE;
Craig Mautner7d8df392012-04-06 15:26:23 -07009import static com.android.server.wm.WindowManagerService.LayoutFields.SET_TURN_ON_SCREEN;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010
Craig Mautnerc2f9be02012-03-27 17:32:29 -070011import android.content.Context;
12import android.graphics.Matrix;
13import android.graphics.PixelFormat;
Craig Mautner7358fbf2012-04-12 21:06:33 -070014import android.graphics.Point;
15import android.graphics.PointF;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070016import android.graphics.Rect;
Craig Mautner48ba1e72012-04-02 13:18:16 -070017import android.graphics.Region;
Craig Mautnera51a9562012-04-17 17:05:26 -070018import android.os.Debug;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070019import android.os.RemoteException;
Craig Mautnera2c77052012-03-26 12:14:43 -070020import android.util.Slog;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070021import android.view.Surface;
Craig Mautner7358fbf2012-04-12 21:06:33 -070022import android.view.SurfaceSession;
Craig Mautnera2c77052012-03-26 12:14:43 -070023import android.view.WindowManager;
24import android.view.WindowManagerPolicy;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070025import android.view.WindowManager.LayoutParams;
Craig Mautnera2c77052012-03-26 12:14:43 -070026import android.view.animation.Animation;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070027import android.view.animation.AnimationUtils;
Craig Mautnera2c77052012-03-26 12:14:43 -070028import android.view.animation.Transformation;
29
30import com.android.server.wm.WindowManagerService.H;
31
32import java.io.PrintWriter;
Craig Mautner7358fbf2012-04-12 21:06:33 -070033import java.util.ArrayList;
Craig Mautnera2c77052012-03-26 12:14:43 -070034
35/**
Craig Mautnerc2f9be02012-03-27 17:32:29 -070036 * Keep track of animations and surface operations for a single WindowState.
37 **/
Craig Mautnera2c77052012-03-26 12:14:43 -070038class WindowStateAnimator {
Craig Mautnerc2f9be02012-03-27 17:32:29 -070039 static final boolean DEBUG_VISIBILITY = WindowManagerService.DEBUG_VISIBILITY;
40 static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_ANIM;
41 static final boolean DEBUG_LAYERS = WindowManagerService.DEBUG_LAYERS;
42 static final boolean DEBUG_STARTING_WINDOW = WindowManagerService.DEBUG_STARTING_WINDOW;
43 static final boolean SHOW_TRANSACTIONS = WindowManagerService.SHOW_TRANSACTIONS;
44 static final boolean SHOW_LIGHT_TRANSACTIONS = WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
45 static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC;
46 static final boolean localLOGV = WindowManagerService.localLOGV;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -070047 static final boolean DEBUG_ORIENTATION = WindowManagerService.DEBUG_ORIENTATION;
Craig Mautner7358fbf2012-04-12 21:06:33 -070048 static final boolean DEBUG_SURFACE_TRACE = WindowManagerService.DEBUG_SURFACE_TRACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070049
50 static final String TAG = "WindowStateAnimator";
Craig Mautnera2c77052012-03-26 12:14:43 -070051
52 final WindowManagerService mService;
53 final WindowState mWin;
54 final WindowState mAttachedWindow;
Craig Mautnere7ae2502012-03-26 17:11:19 -070055 final WindowAnimator mAnimator;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070056 final Session mSession;
57 final WindowManagerPolicy mPolicy;
58 final Context mContext;
Craig Mautnera2c77052012-03-26 12:14:43 -070059
60 // Currently running animation.
61 boolean mAnimating;
62 boolean mLocalAnimating;
63 Animation mAnimation;
64 boolean mAnimationIsEntrance;
65 boolean mHasTransformation;
66 boolean mHasLocalTransformation;
67 final Transformation mTransformation = new Transformation();
68 boolean mWasAnimating; // Were we animating going into the most recent animation step?
Craig Mautnerc2f9be02012-03-27 17:32:29 -070069 int mAnimLayer;
70 int mLastLayer;
71
72 Surface mSurface;
73 Surface mPendingDestroySurface;
74 boolean mReportDestroySurface;
75 boolean mSurfacePendingDestroy;
76
77 /**
78 * Set when we have changed the size of the surface, to know that
79 * we must tell them application to resize (and thus redraw itself).
80 */
81 boolean mSurfaceResized;
82
83 /**
84 * Set if the client has asked that the destroy of its surface be delayed
85 * until it explicitly says it is okay.
86 */
87 boolean mSurfaceDestroyDeferred;
88
Craig Mautner7d8df392012-04-06 15:26:23 -070089 float mShownAlpha = 0;
90 float mAlpha = 0;
91 float mLastAlpha = 0;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070092
93 // Used to save animation distances between the time they are calculated and when they are
94 // used.
95 int mAnimDw;
96 int mAnimDh;
97 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
98 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
99
100 boolean mHaveMatrix;
101
102 // For debugging, this is the last information given to the surface flinger.
103 boolean mSurfaceShown;
104 float mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
105 int mSurfaceLayer;
106 float mSurfaceAlpha;
107
108 // Set to true if, when the window gets displayed, it should perform
109 // an enter animation.
110 boolean mEnterAnimationPending;
Craig Mautnera2c77052012-03-26 12:14:43 -0700111
Craig Mautner749a7bb2012-04-02 13:49:53 -0700112 /** This is set when there is no Surface */
113 static final int NO_SURFACE = 0;
114 /** This is set after the Surface has been created but before the window has been drawn. During
115 * this time the surface is hidden. */
116 static final int DRAW_PENDING = 1;
117 /** This is set after the window has finished drawing for the first time but before its surface
118 * is shown. The surface will be displayed when the next layout is run. */
119 static final int COMMIT_DRAW_PENDING = 2;
120 /** This is set during the time after the window's drawing has been committed, and before its
121 * surface is actually shown. It is used to delay showing the surface until all windows in a
122 * token are ready to be shown. */
123 static final int READY_TO_SHOW = 3;
124 /** Set when the window has been shown in the screen the first time. */
125 static final int HAS_DRAWN = 4;
126 int mDrawState;
Craig Mautnera608b882012-03-30 13:03:49 -0700127
Craig Mautner749a7bb2012-04-02 13:49:53 -0700128 /** Was this window last hidden? */
129 boolean mLastHidden;
Craig Mautnera608b882012-03-30 13:03:49 -0700130
Craig Mautnerbec53f72012-04-05 11:49:05 -0700131 int mAttrFlags;
132 int mAttrType;
133
Craig Mautnera2c77052012-03-26 12:14:43 -0700134 public WindowStateAnimator(final WindowManagerService service, final WindowState win,
135 final WindowState attachedWindow) {
136 mService = service;
137 mWin = win;
138 mAttachedWindow = attachedWindow;
Craig Mautnere7ae2502012-03-26 17:11:19 -0700139 mAnimator = mService.mAnimator;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700140 mSession = win.mSession;
141 mPolicy = mService.mPolicy;
142 mContext = mService.mContext;
Craig Mautnerbec53f72012-04-05 11:49:05 -0700143 mAttrFlags = win.mAttrs.flags;
144 mAttrType = win.mAttrs.type;
Craig Mautner9aa69582012-05-09 17:41:13 -0700145 mAnimDw = service.mAppDisplayWidth;
146 mAnimDh = service.mAppDisplayHeight;
Craig Mautnera2c77052012-03-26 12:14:43 -0700147 }
148
149 public void setAnimation(Animation anim) {
Craig Mautnerbec53f72012-04-05 11:49:05 -0700150 if (localLOGV) Slog.v(TAG, "Setting animation in " + this + ": " + anim);
Craig Mautnera2c77052012-03-26 12:14:43 -0700151 mAnimating = false;
152 mLocalAnimating = false;
153 mAnimation = anim;
154 mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
155 mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale);
156 // Start out animation gone if window is gone, or visible if window is visible.
157 mTransformation.clear();
Craig Mautner749a7bb2012-04-02 13:49:53 -0700158 mTransformation.setAlpha(mLastHidden ? 0 : 1);
Craig Mautnera2c77052012-03-26 12:14:43 -0700159 mHasLocalTransformation = true;
160 }
161
162 public void clearAnimation() {
163 if (mAnimation != null) {
164 mAnimating = true;
165 mLocalAnimating = false;
166 mAnimation.cancel();
167 mAnimation = null;
168 }
169 }
170
171 /** Is the window or its container currently animating? */
172 boolean isAnimating() {
173 final WindowState attached = mAttachedWindow;
174 final AppWindowToken atoken = mWin.mAppToken;
175 return mAnimation != null
176 || (attached != null && attached.mWinAnimator.mAnimation != null)
177 || (atoken != null &&
Craig Mautner59431632012-04-04 11:56:44 -0700178 (atoken.mAppAnimator.animation != null
Craig Mautnera2c77052012-03-26 12:14:43 -0700179 || atoken.inPendingTransaction));
180 }
181
Craig Mautner0afddcb2012-05-08 15:38:00 -0700182 /** Is the window animating the DummyAnimation? */
183 boolean isDummyAnimation() {
184 final AppWindowToken atoken = mWin.mAppToken;
185 return atoken != null
186 && atoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation;
187 }
188
Craig Mautnera2c77052012-03-26 12:14:43 -0700189 /** Is this window currently animating? */
190 boolean isWindowAnimating() {
191 return mAnimation != null;
192 }
193
Craig Mautnera2c77052012-03-26 12:14:43 -0700194 void cancelExitAnimationForNextAnimationLocked() {
Craig Mautnera2c77052012-03-26 12:14:43 -0700195 if (mAnimation != null) {
196 mAnimation.cancel();
197 mAnimation = null;
Craig Mautner4d7349b2012-04-20 14:52:47 -0700198 mLocalAnimating = false;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700199 destroySurfaceLocked();
Craig Mautnera2c77052012-03-26 12:14:43 -0700200 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700201 }
202
203 private boolean stepAnimation(long currentTime) {
204 if ((mAnimation == null) || !mLocalAnimating) {
205 return false;
206 }
207 mTransformation.clear();
208 final boolean more = mAnimation.getTransformation(currentTime, mTransformation);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700209 if (DEBUG_ANIM) Slog.v(
210 TAG, "Stepped animation in " + this +
Craig Mautnera2c77052012-03-26 12:14:43 -0700211 ": more=" + more + ", xform=" + mTransformation);
212 return more;
213 }
214
215 // This must be called while inside a transaction. Returns true if
216 // there is more animation to run.
217 boolean stepAnimationLocked(long currentTime) {
218 // Save the animation state as it was before this step so WindowManagerService can tell if
219 // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
220 mWasAnimating = mAnimating;
221 if (mService.okToDisplay()) {
222 // We will run animations as long as the display isn't frozen.
223
224 if (mWin.isDrawnLw() && mAnimation != null) {
225 mHasTransformation = true;
226 mHasLocalTransformation = true;
227 if (!mLocalAnimating) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700228 if (DEBUG_ANIM) Slog.v(
229 TAG, "Starting animation in " + this +
Craig Mautnera2c77052012-03-26 12:14:43 -0700230 " @ " + currentTime + ": ww=" + mWin.mFrame.width() +
231 " wh=" + mWin.mFrame.height() +
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700232 " dw=" + mAnimDw + " dh=" + mAnimDh +
Craig Mautnera2c77052012-03-26 12:14:43 -0700233 " scale=" + mService.mWindowAnimationScale);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700234 mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
235 mAnimDw, mAnimDh);
Craig Mautner9aa69582012-05-09 17:41:13 -0700236 mAnimDw = mService.mAppDisplayWidth;
237 mAnimDh = mService.mAppDisplayHeight;
Craig Mautnera2c77052012-03-26 12:14:43 -0700238 mAnimation.setStartTime(currentTime);
239 mLocalAnimating = true;
240 mAnimating = true;
241 }
242 if ((mAnimation != null) && mLocalAnimating) {
243 if (stepAnimation(currentTime)) {
244 return true;
245 }
246 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700247 if (DEBUG_ANIM) Slog.v(
248 TAG, "Finished animation in " + this +
Craig Mautnera2c77052012-03-26 12:14:43 -0700249 " @ " + currentTime);
250 //WindowManagerService.this.dump();
251 }
252 mHasLocalTransformation = false;
253 if ((!mLocalAnimating || mAnimationIsEntrance) && mWin.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -0700254 && mWin.mAppToken.mAppAnimator.animation != null) {
Craig Mautnera2c77052012-03-26 12:14:43 -0700255 // When our app token is animating, we kind-of pretend like
256 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
257 // part of this check means that we will only do this if
258 // our window is not currently exiting, or it is not
259 // locally animating itself. The idea being that one that
260 // is exiting and doing a local animation should be removed
261 // once that animation is done.
262 mAnimating = true;
263 mHasTransformation = true;
264 mTransformation.clear();
265 return false;
266 } else if (mHasTransformation) {
267 // Little trick to get through the path below to act like
268 // we have finished an animation.
269 mAnimating = true;
270 } else if (isAnimating()) {
271 mAnimating = true;
272 }
273 } else if (mAnimation != null) {
274 // If the display is frozen, and there is a pending animation,
275 // clear it and make sure we run the cleanup code.
276 mAnimating = true;
Craig Mautnera2c77052012-03-26 12:14:43 -0700277 }
278
279 if (!mAnimating && !mLocalAnimating) {
280 return false;
281 }
282
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700283 // Done animating, clean up.
284 if (DEBUG_ANIM) Slog.v(
285 TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting
Craig Mautnera2c77052012-03-26 12:14:43 -0700286 + ", reportedVisible="
287 + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
288
289 mAnimating = false;
290 mLocalAnimating = false;
291 if (mAnimation != null) {
292 mAnimation.cancel();
293 mAnimation = null;
294 }
Craig Mautnere7ae2502012-03-26 17:11:19 -0700295 if (mAnimator.mWindowDetachedWallpaper == mWin) {
296 mAnimator.mWindowDetachedWallpaper = null;
Craig Mautnera2c77052012-03-26 12:14:43 -0700297 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700298 mAnimLayer = mWin.mLayer;
Craig Mautnera2c77052012-03-26 12:14:43 -0700299 if (mWin.mIsImWindow) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700300 mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
Craig Mautnera2c77052012-03-26 12:14:43 -0700301 } else if (mWin.mIsWallpaper) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700302 mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
Craig Mautnera2c77052012-03-26 12:14:43 -0700303 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700304 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
305 + " anim layer: " + mAnimLayer);
Craig Mautnera2c77052012-03-26 12:14:43 -0700306 mHasTransformation = false;
307 mHasLocalTransformation = false;
308 if (mWin.mPolicyVisibility != mWin.mPolicyVisibilityAfterAnim) {
309 if (WindowState.DEBUG_VISIBILITY) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700310 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
Craig Mautnera2c77052012-03-26 12:14:43 -0700311 + mWin.mPolicyVisibilityAfterAnim);
312 }
313 mWin.mPolicyVisibility = mWin.mPolicyVisibilityAfterAnim;
314 mService.mLayoutNeeded = true;
315 if (!mWin.mPolicyVisibility) {
316 if (mService.mCurrentFocus == mWin) {
317 mService.mFocusMayChange = true;
318 }
319 // Window is no longer visible -- make sure if we were waiting
320 // for it to be displayed before enabling the display, that
321 // we allow the display to be enabled now.
322 mService.enableScreenIfNeededLocked();
323 }
324 }
325 mTransformation.clear();
Craig Mautner749a7bb2012-04-02 13:49:53 -0700326 if (mDrawState == HAS_DRAWN
Craig Mautnera2c77052012-03-26 12:14:43 -0700327 && mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
328 && mWin.mAppToken != null
329 && mWin.mAppToken.firstWindowDrawn
330 && mWin.mAppToken.startingData != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700331 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
Craig Mautnera2c77052012-03-26 12:14:43 -0700332 + mWin.mToken + ": first real window done animating");
333 mService.mFinishedStarting.add(mWin.mAppToken);
334 mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
335 }
336
337 finishExit();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700338 mAnimator.mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
339 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats(
340 "WindowStateAnimator", mAnimator.mPendingLayoutChanges);
Craig Mautnera2c77052012-03-26 12:14:43 -0700341
342 if (mWin.mAppToken != null) {
343 mWin.mAppToken.updateReportedVisibilityLocked();
344 }
345
346 return false;
347 }
348
349 void finishExit() {
350 if (WindowManagerService.DEBUG_ANIM) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700351 TAG, "finishExit in " + this
Craig Mautnera2c77052012-03-26 12:14:43 -0700352 + ": exiting=" + mWin.mExiting
353 + " remove=" + mWin.mRemoveOnExit
354 + " windowAnimating=" + isWindowAnimating());
355
356 final int N = mWin.mChildWindows.size();
357 for (int i=0; i<N; i++) {
358 mWin.mChildWindows.get(i).mWinAnimator.finishExit();
359 }
360
361 if (!mWin.mExiting) {
362 return;
363 }
364
365 if (isWindowAnimating()) {
366 return;
367 }
368
369 if (WindowManagerService.localLOGV) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700370 TAG, "Exit animation finished in " + this
Craig Mautnera2c77052012-03-26 12:14:43 -0700371 + ": remove=" + mWin.mRemoveOnExit);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700372 if (mSurface != null) {
Craig Mautnera2c77052012-03-26 12:14:43 -0700373 mService.mDestroySurface.add(mWin);
374 mWin.mDestroying = true;
375 if (WindowState.SHOW_TRANSACTIONS) WindowManagerService.logSurface(
376 mWin, "HIDE (finishExit)", null);
Craig Mautner0afddcb2012-05-08 15:38:00 -0700377 hide();
Craig Mautnera2c77052012-03-26 12:14:43 -0700378 }
379 mWin.mExiting = false;
380 if (mWin.mRemoveOnExit) {
381 mService.mPendingRemove.add(mWin);
382 mWin.mRemoveOnExit = false;
383 }
Craig Mautner9aa69582012-05-09 17:41:13 -0700384 if (mService.mWallpaperTarget == mWin && mService.mLowerWallpaperTarget == null) {
Craig Mautner0afddcb2012-05-08 15:38:00 -0700385 mAnimator.hideWallpapersLocked();
386 }
387 }
388
389 void hide() {
390 if (!mLastHidden) {
391 //dump();
392 mLastHidden = true;
393 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
394 "HIDE (performLayout)", null);
395 if (mSurface != null) {
396 mSurfaceShown = false;
397 try {
398 mSurface.hide();
399 } catch (RuntimeException e) {
400 Slog.w(TAG, "Exception hiding surface in " + mWin);
401 }
402 }
403 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700404 }
405
Craig Mautnera608b882012-03-30 13:03:49 -0700406 boolean finishDrawingLocked() {
Craig Mautner749a7bb2012-04-02 13:49:53 -0700407 if (mDrawState == DRAW_PENDING) {
Craig Mautner83339b42012-05-01 22:13:23 -0700408 if (DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
409 TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + this + " in "
410 + mSurface);
Craig Mautner749a7bb2012-04-02 13:49:53 -0700411 mDrawState = COMMIT_DRAW_PENDING;
Craig Mautnera608b882012-03-30 13:03:49 -0700412 return true;
413 }
414 return false;
415 }
416
417 // This must be called while inside a transaction.
418 boolean commitFinishDrawingLocked(long currentTime) {
Craig Mautner749a7bb2012-04-02 13:49:53 -0700419 if (mDrawState != COMMIT_DRAW_PENDING) {
Craig Mautnera608b882012-03-30 13:03:49 -0700420 return false;
421 }
Craig Mautner83339b42012-05-01 22:13:23 -0700422 if (DEBUG_ANIM)
423 Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurface);
Craig Mautner749a7bb2012-04-02 13:49:53 -0700424 mDrawState = READY_TO_SHOW;
Craig Mautnera608b882012-03-30 13:03:49 -0700425 final boolean starting = mWin.mAttrs.type == TYPE_APPLICATION_STARTING;
426 final AppWindowToken atoken = mWin.mAppToken;
427 if (atoken == null || atoken.allDrawn || starting) {
428 performShowLocked();
429 }
430 return true;
431 }
432
Craig Mautner7d8df392012-04-06 15:26:23 -0700433 static class SurfaceTrace extends Surface {
434 private final static String SURFACE_TAG = "SurfaceTrace";
435 final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
Craig Mautner7358fbf2012-04-12 21:06:33 -0700436
Craig Mautner7d8df392012-04-06 15:26:23 -0700437 private float mSurfaceTraceAlpha = 0;
Craig Mautner7358fbf2012-04-12 21:06:33 -0700438 private int mLayer;
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700439 private final PointF mPosition = new PointF();
440 private final Point mSize = new Point();
441 private final Rect mWindowCrop = new Rect();
Craig Mautner7358fbf2012-04-12 21:06:33 -0700442 private boolean mShown = false;
443 private String mName = "Not named";
444
Craig Mautner7d8df392012-04-06 15:26:23 -0700445 public SurfaceTrace(SurfaceSession s,
Craig Mautner7358fbf2012-04-12 21:06:33 -0700446 int pid, int display, int w, int h, int format, int flags) throws
447 OutOfResourcesException {
448 super(s, pid, display, w, h, format, flags);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700449 mSize.set(w, h);
Craig Mautner7d8df392012-04-06 15:26:23 -0700450 Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700451 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700452 }
453
Craig Mautner7d8df392012-04-06 15:26:23 -0700454 public SurfaceTrace(SurfaceSession s,
Craig Mautner7358fbf2012-04-12 21:06:33 -0700455 int pid, String name, int display, int w, int h, int format, int flags)
456 throws OutOfResourcesException {
457 super(s, pid, name, display, w, h, format, flags);
458 mName = name;
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700459 mSize.set(w, h);
Craig Mautner7d8df392012-04-06 15:26:23 -0700460 Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700461 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700462 }
463
464 @Override
465 public void setAlpha(float alpha) {
466 super.setAlpha(alpha);
Craig Mautner7d8df392012-04-06 15:26:23 -0700467 mSurfaceTraceAlpha = alpha;
468 Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700469 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700470 }
471
472 @Override
473 public void setLayer(int zorder) {
474 super.setLayer(zorder);
475 mLayer = zorder;
Craig Mautner7d8df392012-04-06 15:26:23 -0700476 Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700477 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700478
479 sSurfaces.remove(this);
480 int i;
481 for (i = sSurfaces.size() - 1; i >= 0; i--) {
Craig Mautner7d8df392012-04-06 15:26:23 -0700482 SurfaceTrace s = sSurfaces.get(i);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700483 if (s.mLayer < zorder) {
484 break;
485 }
486 }
487 sSurfaces.add(i + 1, this);
488 }
489
490 @Override
491 public void setPosition(float x, float y) {
492 super.setPosition(x, y);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700493 mPosition.set(x, y);
Craig Mautner7d8df392012-04-06 15:26:23 -0700494 Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700495 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700496 }
497
498 @Override
499 public void setSize(int w, int h) {
500 super.setSize(w, h);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700501 mSize.set(w, h);
Craig Mautner7d8df392012-04-06 15:26:23 -0700502 Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700503 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700504 }
505
506 @Override
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700507 public void setWindowCrop(Rect crop) {
508 super.setWindowCrop(crop);
509 mWindowCrop.set(crop);
510 Slog.v(SURFACE_TAG, "setWindowCrop: " + this + ". Called by "
511 + Debug.getCallers(3));
512 }
513
514 @Override
Craig Mautner7358fbf2012-04-12 21:06:33 -0700515 public void hide() {
516 super.hide();
517 mShown = false;
Craig Mautner7d8df392012-04-06 15:26:23 -0700518 Slog.v(SURFACE_TAG, "hide: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700519 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700520 }
521 @Override
522 public void show() {
523 super.show();
524 mShown = true;
Craig Mautner7d8df392012-04-06 15:26:23 -0700525 Slog.v(SURFACE_TAG, "show: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700526 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700527 }
528
529 @Override
530 public void destroy() {
531 super.destroy();
Craig Mautner7d8df392012-04-06 15:26:23 -0700532 Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700533 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700534 sSurfaces.remove(this);
535 }
536
Craig Mautneracaf9cc2012-04-17 11:45:25 -0700537 @Override
538 public void release() {
539 super.release();
540 Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700541 + Debug.getCallers(3));
Craig Mautneracaf9cc2012-04-17 11:45:25 -0700542 sSurfaces.remove(this);
543 }
544
Craig Mautner7358fbf2012-04-12 21:06:33 -0700545 static void dumpAllSurfaces() {
546 final int N = sSurfaces.size();
547 for (int i = 0; i < N; i++) {
548 Slog.i(TAG, "SurfaceDump: " + sSurfaces.get(i));
549 }
550 }
551
552 @Override
553 public String toString() {
Craig Mautnerfbf378c2012-04-23 17:24:21 -0700554 return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
555 + mName + ": shown=" + mShown + " layer=" + mLayer
Craig Mautner7d8df392012-04-06 15:26:23 -0700556 + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700557 + " " + mSize.x + "x" + mSize.y
558 + " crop=" + mWindowCrop.toShortString();
Craig Mautner7358fbf2012-04-12 21:06:33 -0700559 }
560 }
561
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700562 Surface createSurfaceLocked() {
563 if (mSurface == null) {
564 mReportDestroySurface = false;
565 mSurfacePendingDestroy = false;
Craig Mautner83339b42012-05-01 22:13:23 -0700566 if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
567 "createSurface " + this + ": mDrawState=DRAW_PENDING");
Craig Mautner749a7bb2012-04-02 13:49:53 -0700568 mDrawState = DRAW_PENDING;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700569 if (mWin.mAppToken != null) {
570 mWin.mAppToken.allDrawn = false;
571 }
572
573 mService.makeWindowFreezingScreenIfNeededLocked(mWin);
574
575 int flags = 0;
576 final WindowManager.LayoutParams attrs = mWin.mAttrs;
577
578 if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
579 flags |= Surface.SECURE;
580 }
581 if (WindowState.DEBUG_VISIBILITY) Slog.v(
582 TAG, "Creating surface in session "
583 + mSession.mSurfaceSession + " window " + this
584 + " w=" + mWin.mCompatFrame.width()
585 + " h=" + mWin.mCompatFrame.height() + " format="
586 + attrs.format + " flags=" + flags);
587
588 int w = mWin.mCompatFrame.width();
589 int h = mWin.mCompatFrame.height();
590 if ((attrs.flags & LayoutParams.FLAG_SCALED) != 0) {
591 // for a scaled surface, we always want the requested
592 // size.
593 w = mWin.mRequestedWidth;
594 h = mWin.mRequestedHeight;
595 }
596
597 // Something is wrong and SurfaceFlinger will not like this,
598 // try to revert to sane values
599 if (w <= 0) w = 1;
600 if (h <= 0) h = 1;
601
602 mSurfaceShown = false;
603 mSurfaceLayer = 0;
Craig Mautner7d8df392012-04-06 15:26:23 -0700604 mSurfaceAlpha = 0;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700605 mSurfaceX = 0;
606 mSurfaceY = 0;
607 mSurfaceW = w;
608 mSurfaceH = h;
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700609 mWin.mLastSystemDecorRect.set(0, 0, 0, 0);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700610 try {
611 final boolean isHwAccelerated = (attrs.flags &
612 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
613 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
614 if (!PixelFormat.formatHasAlpha(attrs.format)) {
615 flags |= Surface.OPAQUE;
616 }
Craig Mautner7358fbf2012-04-12 21:06:33 -0700617 if (DEBUG_SURFACE_TRACE) {
Craig Mautner7d8df392012-04-06 15:26:23 -0700618 mSurface = new SurfaceTrace(
Craig Mautner7358fbf2012-04-12 21:06:33 -0700619 mSession.mSurfaceSession, mSession.mPid,
620 attrs.getTitle().toString(),
621 0, w, h, format, flags);
622 } else {
623 mSurface = new Surface(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700624 mSession.mSurfaceSession, mSession.mPid,
625 attrs.getTitle().toString(),
626 0, w, h, format, flags);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700627 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700628 mWin.mHasSurface = true;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700629 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG,
630 " CREATE SURFACE "
631 + mSurface + " IN SESSION "
632 + mSession.mSurfaceSession
633 + ": pid=" + mSession.mPid + " format="
634 + attrs.format + " flags=0x"
635 + Integer.toHexString(flags)
636 + " / " + this);
637 } catch (Surface.OutOfResourcesException e) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700638 mWin.mHasSurface = false;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700639 Slog.w(TAG, "OutOfResourcesException creating surface");
640 mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
Craig Mautner749a7bb2012-04-02 13:49:53 -0700641 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700642 return null;
643 } catch (Exception e) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700644 mWin.mHasSurface = false;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700645 Slog.e(TAG, "Exception creating surface", e);
Craig Mautner749a7bb2012-04-02 13:49:53 -0700646 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700647 return null;
648 }
649
650 if (WindowManagerService.localLOGV) Slog.v(
651 TAG, "Got surface: " + mSurface
652 + ", set left=" + mWin.mFrame.left + " top=" + mWin.mFrame.top
653 + ", animLayer=" + mAnimLayer);
654 if (SHOW_LIGHT_TRANSACTIONS) {
655 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
656 WindowManagerService.logSurface(mWin, "CREATE pos=("
657 + mWin.mFrame.left + "," + mWin.mFrame.top + ") ("
658 + mWin.mCompatFrame.width() + "x" + mWin.mCompatFrame.height()
659 + "), layer=" + mAnimLayer + " HIDE", null);
660 }
661 Surface.openTransaction();
662 try {
663 try {
664 mSurfaceX = mWin.mFrame.left + mWin.mXOffset;
665 mSurfaceY = mWin.mFrame.top + mWin.mYOffset;
666 mSurface.setPosition(mSurfaceX, mSurfaceY);
667 mSurfaceLayer = mAnimLayer;
668 mSurface.setLayer(mAnimLayer);
Craig Mautner7d8df392012-04-06 15:26:23 -0700669 mSurface.setAlpha(0);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700670 mSurfaceShown = false;
671 mSurface.hide();
672 if ((mWin.mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
673 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "DITHER", null);
674 mSurface.setFlags(Surface.SURFACE_DITHER, Surface.SURFACE_DITHER);
675 }
676 } catch (RuntimeException e) {
677 Slog.w(TAG, "Error creating surface in " + w, e);
678 mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
679 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700680 mLastHidden = true;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700681 } finally {
682 Surface.closeTransaction();
683 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
684 "<<< CLOSE TRANSACTION createSurfaceLocked");
685 }
686 if (WindowManagerService.localLOGV) Slog.v(
687 TAG, "Created surface " + this);
688 }
689 return mSurface;
690 }
691
692 void destroySurfaceLocked() {
693 if (mWin.mAppToken != null && mWin == mWin.mAppToken.startingWindow) {
694 mWin.mAppToken.startingDisplayed = false;
695 }
696
Craig Mautner749a7bb2012-04-02 13:49:53 -0700697 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700698 if (mSurface != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700699
700 int i = mWin.mChildWindows.size();
701 while (i > 0) {
702 i--;
703 WindowState c = mWin.mChildWindows.get(i);
704 c.mAttachedHidden = true;
705 }
706
707 if (mReportDestroySurface) {
708 mReportDestroySurface = false;
709 mSurfacePendingDestroy = true;
710 try {
711 mWin.mClient.dispatchGetNewSurface();
712 // We'll really destroy on the next time around.
713 return;
714 } catch (RemoteException e) {
715 }
716 }
717
718 try {
719 if (DEBUG_VISIBILITY) {
720 RuntimeException e = null;
721 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
722 e = new RuntimeException();
723 e.fillInStackTrace();
724 }
725 Slog.w(TAG, "Window " + this + " destroying surface "
726 + mSurface + ", session " + mSession, e);
727 }
728 if (mSurfaceDestroyDeferred) {
729 if (mSurface != null && mPendingDestroySurface != mSurface) {
730 if (mPendingDestroySurface != null) {
731 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
732 RuntimeException e = null;
733 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
734 e = new RuntimeException();
735 e.fillInStackTrace();
736 }
737 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
738 }
739 mPendingDestroySurface.destroy();
740 }
741 mPendingDestroySurface = mSurface;
742 }
743 } else {
744 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
745 RuntimeException e = null;
746 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
747 e = new RuntimeException();
748 e.fillInStackTrace();
749 }
750 WindowManagerService.logSurface(mWin, "DESTROY", e);
751 }
752 mSurface.destroy();
753 }
754 } catch (RuntimeException e) {
755 Slog.w(TAG, "Exception thrown when destroying Window " + this
756 + " surface " + mSurface + " session " + mSession
757 + ": " + e.toString());
758 }
759
760 mSurfaceShown = false;
761 mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700762 mWin.mHasSurface =false;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700763 }
764 }
765
766 void destroyDeferredSurfaceLocked() {
767 try {
768 if (mPendingDestroySurface != null) {
769 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
770 RuntimeException e = null;
771 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
772 e = new RuntimeException();
773 e.fillInStackTrace();
774 }
775 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
776 }
777 mPendingDestroySurface.destroy();
778 }
779 } catch (RuntimeException e) {
Craig Mautnerd87946b2012-03-29 18:00:19 -0700780 Slog.w(TAG, "Exception thrown when destroying Window "
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700781 + this + " surface " + mPendingDestroySurface
782 + " session " + mSession + ": " + e.toString());
783 }
784 mSurfaceDestroyDeferred = false;
785 mPendingDestroySurface = null;
786 }
787
788 void computeShownFrameLocked() {
789 final boolean selfTransformation = mHasLocalTransformation;
790 Transformation attachedTransformation =
791 (mAttachedWindow != null && mAttachedWindow.mWinAnimator.mHasLocalTransformation)
792 ? mAttachedWindow.mWinAnimator.mTransformation : null;
Craig Mautner59431632012-04-04 11:56:44 -0700793 final AppWindowAnimator appAnimator =
794 mWin.mAppToken == null ? null : mWin.mAppToken.mAppAnimator;
795 Transformation appTransformation = (appAnimator != null && appAnimator.hasTransformation)
796 ? appAnimator.transformation : null;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700797
798 // Wallpapers are animated based on the "real" window they
799 // are currently targeting.
800 if (mWin.mAttrs.type == TYPE_WALLPAPER && mService.mLowerWallpaperTarget == null
801 && mService.mWallpaperTarget != null) {
802 if (mService.mWallpaperTarget.mWinAnimator.mHasLocalTransformation &&
803 mService.mWallpaperTarget.mWinAnimator.mAnimation != null &&
804 !mService.mWallpaperTarget.mWinAnimator.mAnimation.getDetachWallpaper()) {
805 attachedTransformation = mService.mWallpaperTarget.mWinAnimator.mTransformation;
806 if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
807 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
808 }
809 }
Craig Mautner59431632012-04-04 11:56:44 -0700810 final AppWindowAnimator wpAppAnimator = mService.mWallpaperTarget.mAppToken == null
811 ? null : mService.mWallpaperTarget.mAppToken.mAppAnimator;
812 if (wpAppAnimator != null &&
813 wpAppAnimator.hasTransformation &&
814 wpAppAnimator.animation != null &&
815 !wpAppAnimator.animation.getDetachWallpaper()) {
816 appTransformation = wpAppAnimator.transformation;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700817 if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
818 Slog.v(TAG, "WP target app xform: " + appTransformation);
819 }
820 }
821 }
822
823 final boolean screenAnimation = mService.mAnimator.mScreenRotationAnimation != null
824 && mService.mAnimator.mScreenRotationAnimation.isAnimating();
825 if (selfTransformation || attachedTransformation != null
826 || appTransformation != null || screenAnimation) {
827 // cache often used attributes locally
828 final Rect frame = mWin.mFrame;
829 final float tmpFloats[] = mService.mTmpFloats;
830 final Matrix tmpMatrix = mWin.mTmpMatrix;
831
832 // Compute the desired transformation.
833 if (screenAnimation) {
834 // If we are doing a screen animation, the global rotation
835 // applied to windows can result in windows that are carefully
836 // aligned with each other to slightly separate, allowing you
837 // to see what is behind them. An unsightly mess. This...
838 // thing... magically makes it call good: scale each window
839 // slightly (two pixels larger in each dimension, from the
840 // window's center).
841 final float w = frame.width();
842 final float h = frame.height();
843 if (w>=1 && h>=1) {
844 tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
845 } else {
846 tmpMatrix.reset();
847 }
848 } else {
849 tmpMatrix.reset();
850 }
851 tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
852 if (selfTransformation) {
853 tmpMatrix.postConcat(mTransformation.getMatrix());
854 }
855 tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
856 if (attachedTransformation != null) {
857 tmpMatrix.postConcat(attachedTransformation.getMatrix());
858 }
859 if (appTransformation != null) {
860 tmpMatrix.postConcat(appTransformation.getMatrix());
861 }
862 if (screenAnimation) {
863 tmpMatrix.postConcat(
864 mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getMatrix());
865 }
866
867 // "convert" it into SurfaceFlinger's format
868 // (a 2x2 matrix + an offset)
869 // Here we must not transform the position of the surface
870 // since it is already included in the transformation.
871 //Slog.i(TAG, "Transform: " + matrix);
872
873 mHaveMatrix = true;
874 tmpMatrix.getValues(tmpFloats);
875 mDsDx = tmpFloats[Matrix.MSCALE_X];
876 mDtDx = tmpFloats[Matrix.MSKEW_Y];
877 mDsDy = tmpFloats[Matrix.MSKEW_X];
878 mDtDy = tmpFloats[Matrix.MSCALE_Y];
879 float x = tmpFloats[Matrix.MTRANS_X];
880 float y = tmpFloats[Matrix.MTRANS_Y];
881 int w = frame.width();
882 int h = frame.height();
883 mWin.mShownFrame.set(x, y, x+w, y+h);
884
885 // Now set the alpha... but because our current hardware
886 // can't do alpha transformation on a non-opaque surface,
887 // turn it off if we are running an animation that is also
888 // transforming since it is more important to have that
889 // animation be smooth.
890 mShownAlpha = mAlpha;
891 if (!mService.mLimitedAlphaCompositing
892 || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
893 || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
894 && x == frame.left && y == frame.top))) {
895 //Slog.i(TAG, "Applying alpha transform");
896 if (selfTransformation) {
897 mShownAlpha *= mTransformation.getAlpha();
898 }
899 if (attachedTransformation != null) {
900 mShownAlpha *= attachedTransformation.getAlpha();
901 }
902 if (appTransformation != null) {
903 mShownAlpha *= appTransformation.getAlpha();
904 }
905 if (screenAnimation) {
906 mShownAlpha *=
907 mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha();
908 }
909 } else {
910 //Slog.i(TAG, "Not applying alpha transform");
911 }
912
913 if (WindowManagerService.localLOGV) Slog.v(
914 TAG, "computeShownFrameLocked: Animating " + this +
915 ": " + mWin.mShownFrame +
916 ", alpha=" + mTransformation.getAlpha() + ", mShownAlpha=" + mShownAlpha);
917 return;
Craig Mautner4d7349b2012-04-20 14:52:47 -0700918 } else if (mWin.mIsWallpaper &&
919 (mAnimator.mPendingActions & WindowAnimator.WALLPAPER_ACTION_PENDING) != 0) {
920 return;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700921 }
922
923 if (WindowManagerService.localLOGV) Slog.v(
Craig Mautner4d7349b2012-04-20 14:52:47 -0700924 TAG, "computeShownFrameLocked: " + this +
925 " not attached, mAlpha=" + mAlpha);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700926 mWin.mShownFrame.set(mWin.mFrame);
927 if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
928 mWin.mShownFrame.offset(mWin.mXOffset, mWin.mYOffset);
929 }
930 mShownAlpha = mAlpha;
931 mHaveMatrix = false;
932 mDsDx = mWin.mGlobalScale;
933 mDtDx = 0;
934 mDsDy = 0;
935 mDtDy = mWin.mGlobalScale;
936 }
Craig Mautnerd87946b2012-03-29 18:00:19 -0700937
Dianne Hackborn3e52fc22012-05-15 17:58:02 -0700938 void updateSurfaceWindowCrop(final boolean recoveringMemory) {
939 final WindowState w = mWin;
940
941 // Need to recompute a new system decor rect each time.
942 if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
943 // Currently can't do this cropping for scaled windows. We'll
944 // just keep the crop rect the same as the source surface.
945 w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight);
946 } else if (w.mLayer >= mService.mSystemDecorLayer) {
947 // Above the decor layer is easy, just use the entire window.
948 w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(),
949 w.mCompatFrame.height());
950 } else {
951 final Rect decorRect = mService.mSystemDecorRect;
952 // Compute the offset of the window in relation to the decor rect.
953 final int offX = w.mXOffset + w.mFrame.left;
954 final int offY = w.mYOffset + w.mFrame.top;
955 // Initialize the decor rect to the entire frame.
956 w.mSystemDecorRect.set(0, 0, w.mFrame.width(), w.mFrame.height());
957 // Intersect with the decor rect, offsetted by window position.
958 w.mSystemDecorRect.intersect(decorRect.left-offX, decorRect.top-offY,
959 decorRect.right-offX, decorRect.bottom-offY);
960 // If size compatibility is being applied to the window, the
961 // surface is scaled relative to the screen. Also apply this
962 // scaling to the crop rect. We aren't using the standard rect
963 // scale function because we want to round things to make the crop
964 // always round to a larger rect to ensure we don't crop too
965 // much and hide part of the window that should be seen.
966 if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
967 final float scale = w.mInvGlobalScale;
968 w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
969 w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
970 w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
971 w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
972 }
973 }
974
975 if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) {
976 w.mLastSystemDecorRect.set(w.mSystemDecorRect);
977 try {
978 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
979 "CROP " + w.mSystemDecorRect.toShortString(), null);
980 mSurface.setWindowCrop(w.mSystemDecorRect);
981 } catch (RuntimeException e) {
982 Slog.w(TAG, "Error setting crop surface of " + w
983 + " crop=" + w.mSystemDecorRect.toShortString(), e);
984 if (!recoveringMemory) {
985 mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
986 }
987 }
988 }
989 }
990
Craig Mautneracaf9cc2012-04-17 11:45:25 -0700991 void setSurfaceBoundaries(final boolean recoveringMemory) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700992 final WindowState w = mWin;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700993 int width, height;
994 if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
995 // for a scaled surface, we just want to use
996 // the requested size.
997 width = w.mRequestedWidth;
998 height = w.mRequestedHeight;
999 } else {
1000 width = w.mCompatFrame.width();
1001 height = w.mCompatFrame.height();
1002 }
1003
1004 if (width < 1) {
1005 width = 1;
1006 }
1007 if (height < 1) {
1008 height = 1;
1009 }
1010 final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height;
1011 if (surfaceResized) {
1012 mSurfaceW = width;
1013 mSurfaceH = height;
1014 }
1015
Craig Mautner4d7349b2012-04-20 14:52:47 -07001016 final float left = w.mShownFrame.left;
1017 final float top = w.mShownFrame.top;
1018 if (mSurfaceX != left || mSurfaceY != top) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001019 try {
1020 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
Craig Mautner4d7349b2012-04-20 14:52:47 -07001021 "POS " + left + ", " + top, null);
1022 mSurfaceX = left;
1023 mSurfaceY = top;
1024 mSurface.setPosition(left, top);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001025 } catch (RuntimeException e) {
1026 Slog.w(TAG, "Error positioning surface of " + w
Craig Mautner4d7349b2012-04-20 14:52:47 -07001027 + " pos=(" + left
1028 + "," + top + ")", e);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001029 if (!recoveringMemory) {
1030 mService.reclaimSomeSurfaceMemoryLocked(this, "position", true);
1031 }
1032 }
1033 }
1034
1035 if (surfaceResized) {
1036 try {
1037 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1038 "SIZE " + width + "x" + height, null);
1039 mSurfaceResized = true;
1040 mSurface.setSize(width, height);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001041 mAnimator.mPendingLayoutChanges |=
1042 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Craig Mautner3a67f352012-05-07 11:21:33 -07001043 if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
1044 mAnimator.startDimming(this, w.mExiting ? 0 : w.mAttrs.dimAmount,
1045 mService.mAppDisplayWidth, mService.mAppDisplayHeight);
1046 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001047 } catch (RuntimeException e) {
1048 // If something goes wrong with the surface (such
1049 // as running out of memory), don't take down the
1050 // entire system.
1051 Slog.e(TAG, "Error resizing surface of " + w
1052 + " size=(" + width + "x" + height + ")", e);
1053 if (!recoveringMemory) {
1054 mService.reclaimSomeSurfaceMemoryLocked(this, "size", true);
1055 }
1056 }
1057 }
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07001058
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001059 updateSurfaceWindowCrop(recoveringMemory);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001060 }
1061
1062 public void prepareSurfaceLocked(final boolean recoveringMemory) {
1063 final WindowState w = mWin;
1064 if (mSurface == null) {
1065 if (w.mOrientationChanging) {
1066 if (DEBUG_ORIENTATION) {
1067 Slog.v(TAG, "Orientation change skips hidden " + w);
1068 }
1069 w.mOrientationChanging = false;
1070 }
1071 return;
1072 }
1073
1074 boolean displayed = false;
1075
1076 computeShownFrameLocked();
1077
1078 setSurfaceBoundaries(recoveringMemory);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001079
Craig Mautnerde6198e2012-04-19 09:59:31 -07001080 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
Craig Mautner0afddcb2012-05-08 15:38:00 -07001081 hide();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001082 // If we are waiting for this window to handle an
1083 // orientation change, well, it is hidden, so
1084 // doesn't really matter. Note that this does
1085 // introduce a potential glitch if the window
1086 // becomes unhidden before it has drawn for the
1087 // new orientation.
1088 if (w.mOrientationChanging) {
1089 w.mOrientationChanging = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001090 if (DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001091 "Orientation change skips hidden " + w);
1092 }
1093 } else if (mLastLayer != mAnimLayer
1094 || mLastAlpha != mShownAlpha
1095 || mLastDsDx != mDsDx
1096 || mLastDtDx != mDtDx
1097 || mLastDsDy != mDsDy
1098 || mLastDtDy != mDtDy
1099 || w.mLastHScale != w.mHScale
1100 || w.mLastVScale != w.mVScale
Craig Mautner749a7bb2012-04-02 13:49:53 -07001101 || mLastHidden) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001102 displayed = true;
1103 mLastAlpha = mShownAlpha;
1104 mLastLayer = mAnimLayer;
1105 mLastDsDx = mDsDx;
1106 mLastDtDx = mDtDx;
1107 mLastDsDy = mDsDy;
1108 mLastDtDy = mDtDy;
1109 w.mLastHScale = w.mHScale;
1110 w.mLastVScale = w.mVScale;
1111 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1112 "alpha=" + mShownAlpha + " layer=" + mAnimLayer
1113 + " matrix=[" + (mDsDx*w.mHScale)
1114 + "," + (mDtDx*w.mVScale)
1115 + "][" + (mDsDy*w.mHScale)
1116 + "," + (mDtDy*w.mVScale) + "]", null);
1117 if (mSurface != null) {
1118 try {
1119 mSurfaceAlpha = mShownAlpha;
1120 mSurface.setAlpha(mShownAlpha);
1121 mSurfaceLayer = w.mWinAnimator.mAnimLayer;
1122 mSurface.setLayer(w.mWinAnimator.mAnimLayer);
1123 mSurface.setMatrix(
1124 mDsDx*w.mHScale, mDtDx*w.mVScale,
1125 mDsDy*w.mHScale, mDtDy*w.mVScale);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001126
1127 if (mLastHidden && mDrawState == HAS_DRAWN) {
1128 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1129 "SHOW (performLayout)", null);
1130 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
1131 + " during relayout");
1132 if (showSurfaceRobustlyLocked()) {
1133 mLastHidden = false;
1134 } else {
1135 w.mOrientationChanging = false;
1136 }
1137 }
1138 if (mSurface != null) {
1139 w.mToken.hasVisible = true;
1140 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001141 } catch (RuntimeException e) {
1142 Slog.w(TAG, "Error updating surface in " + w, e);
1143 if (!recoveringMemory) {
1144 mService.reclaimSomeSurfaceMemoryLocked(this, "update", true);
1145 }
1146 }
1147 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001148 } else {
Craig Mautner83339b42012-05-01 22:13:23 -07001149 if (DEBUG_ANIM) {
1150 Slog.v(TAG, "prepareSurface: No changes in animation for " + mWin);
1151 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001152 displayed = true;
1153 }
1154
1155 if (displayed) {
1156 if (w.mOrientationChanging) {
1157 if (!w.isDrawnLw()) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07001158 mAnimator.mBulkUpdateParams |= CLEAR_ORIENTATION_CHANGE_COMPLETE;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001159 if (DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001160 "Orientation continue waiting for draw in " + w);
1161 } else {
1162 w.mOrientationChanging = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001163 if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001164 }
1165 }
1166 w.mToken.hasVisible = true;
1167 }
1168 }
1169
Craig Mautner48ba1e72012-04-02 13:18:16 -07001170 void setTransparentRegionHint(final Region region) {
Craig Mautner1f4e0cc2012-04-10 14:24:38 -07001171 if (mSurface == null) {
1172 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
1173 return;
1174 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07001175 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1176 ">>> OPEN TRANSACTION setTransparentRegion");
1177 Surface.openTransaction();
1178 try {
1179 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
1180 "transparentRegionHint=" + region, null);
1181 mSurface.setTransparentRegionHint(region);
1182 } finally {
1183 Surface.closeTransaction();
1184 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1185 "<<< CLOSE TRANSACTION setTransparentRegion");
1186 }
1187 }
1188
1189 void setWallpaperOffset(int left, int top) {
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001190 mSurfaceX = left;
1191 mSurfaceY = top;
1192 if (mAnimating) {
1193 // If this window (or its app token) is animating, then the position
1194 // of the surface will be re-computed on the next animation frame.
1195 // We can't poke it directly here because it depends on whatever
1196 // transformation is being applied by the animation.
1197 return;
1198 }
1199 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1200 ">>> OPEN TRANSACTION setWallpaperOffset");
Craig Mautner48ba1e72012-04-02 13:18:16 -07001201 Surface.openTransaction();
1202 try {
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001203 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
1204 "POS " + left + ", " + top, null);
1205 mSurface.setPosition(mWin.mFrame.left + left, mWin.mFrame.top + top);
1206 updateSurfaceWindowCrop(false);
Craig Mautner48ba1e72012-04-02 13:18:16 -07001207 } catch (RuntimeException e) {
1208 Slog.w(TAG, "Error positioning surface of " + mWin
1209 + " pos=(" + left + "," + top + ")", e);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001210 } finally {
1211 Surface.closeTransaction();
1212 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1213 "<<< CLOSE TRANSACTION setWallpaperOffset");
Craig Mautner48ba1e72012-04-02 13:18:16 -07001214 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07001215 }
1216
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001217 // This must be called while inside a transaction.
1218 boolean performShowLocked() {
1219 if (DEBUG_VISIBILITY) {
1220 RuntimeException e = null;
1221 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
1222 e = new RuntimeException();
1223 e.fillInStackTrace();
1224 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001225 Slog.v(TAG, "performShow on " + this
Craig Mautner749a7bb2012-04-02 13:49:53 -07001226 + ": mDrawState=" + mDrawState + " readyForDisplay="
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001227 + mWin.isReadyForDisplay()
1228 + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING), e);
1229 }
Craig Mautner749a7bb2012-04-02 13:49:53 -07001230 if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplay()) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001231 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001232 WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null);
Craig Mautnerd87946b2012-03-29 18:00:19 -07001233 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001234 + " during animation: policyVis=" + mWin.mPolicyVisibility
1235 + " attHidden=" + mWin.mAttachedHidden
1236 + " tok.hiddenRequested="
1237 + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
1238 + " tok.hidden="
1239 + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
1240 + " animating=" + mAnimating
1241 + " tok animating="
Craig Mautner59431632012-04-04 11:56:44 -07001242 + (mWin.mAppToken != null ? mWin.mAppToken.mAppAnimator.animating : false));
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001243
1244 mService.enableScreenIfNeededLocked();
1245
1246 applyEnterAnimationLocked();
1247
Craig Mautnerde6198e2012-04-19 09:59:31 -07001248 // Force the show in the next prepareSurfaceLocked() call.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001249 mLastAlpha = -1;
Craig Mautner83339b42012-05-01 22:13:23 -07001250 if (DEBUG_ANIM) Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN");
Craig Mautner749a7bb2012-04-02 13:49:53 -07001251 mDrawState = HAS_DRAWN;
Craig Mautnerde6198e2012-04-19 09:59:31 -07001252 mService.scheduleAnimationLocked();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001253
1254 int i = mWin.mChildWindows.size();
1255 while (i > 0) {
1256 i--;
1257 WindowState c = mWin.mChildWindows.get(i);
1258 if (c.mAttachedHidden) {
1259 c.mAttachedHidden = false;
1260 if (c.mWinAnimator.mSurface != null) {
1261 c.mWinAnimator.performShowLocked();
1262 // It hadn't been shown, which means layout not
1263 // performed on it, so now we want to make sure to
1264 // do a layout. If called from within the transaction
1265 // loop, this will cause it to restart with a new
1266 // layout.
1267 mService.mLayoutNeeded = true;
1268 }
1269 }
1270 }
1271
1272 if (mWin.mAttrs.type != TYPE_APPLICATION_STARTING
1273 && mWin.mAppToken != null) {
1274 mWin.mAppToken.firstWindowDrawn = true;
1275
1276 if (mWin.mAppToken.startingData != null) {
1277 if (WindowManagerService.DEBUG_STARTING_WINDOW ||
Craig Mautnerd87946b2012-03-29 18:00:19 -07001278 WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001279 "Finish starting " + mWin.mToken
1280 + ": first real window is shown, no animation");
1281 // If this initial window is animating, stop it -- we
1282 // will do an animation to reveal it from behind the
1283 // starting window, so there is no need for it to also
1284 // be doing its own stuff.
Craig Mautner4d7349b2012-04-20 14:52:47 -07001285 clearAnimation();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001286 mService.mFinishedStarting.add(mWin.mAppToken);
1287 mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
1288 }
1289 mWin.mAppToken.updateReportedVisibilityLocked();
1290 }
1291
1292 return true;
1293 }
1294
1295 return false;
1296 }
1297
1298 /**
1299 * Have the surface flinger show a surface, robustly dealing with
1300 * error conditions. In particular, if there is not enough memory
1301 * to show the surface, then we will try to get rid of other surfaces
1302 * in order to succeed.
1303 *
1304 * @return Returns true if the surface was successfully shown.
1305 */
1306 boolean showSurfaceRobustlyLocked() {
1307 try {
1308 if (mSurface != null) {
1309 mSurfaceShown = true;
1310 mSurface.show();
1311 if (mWin.mTurnOnScreen) {
1312 if (DEBUG_VISIBILITY) Slog.v(TAG,
1313 "Show surface turning screen on: " + mWin);
1314 mWin.mTurnOnScreen = false;
Craig Mautner7d8df392012-04-06 15:26:23 -07001315 mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001316 }
1317 }
1318 return true;
1319 } catch (RuntimeException e) {
1320 Slog.w(TAG, "Failure showing surface " + mSurface + " in " + mWin, e);
1321 }
1322
1323 mService.reclaimSomeSurfaceMemoryLocked(this, "show", true);
1324
1325 return false;
1326 }
1327
1328 void applyEnterAnimationLocked() {
1329 final int transit;
1330 if (mEnterAnimationPending) {
1331 mEnterAnimationPending = false;
1332 transit = WindowManagerPolicy.TRANSIT_ENTER;
1333 } else {
1334 transit = WindowManagerPolicy.TRANSIT_SHOW;
1335 }
1336
1337 applyAnimationLocked(transit, true);
1338 }
1339
Craig Mautner48ba1e72012-04-02 13:18:16 -07001340 // TODO(cmautner): Move back to WindowState?
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001341 /**
1342 * Choose the correct animation and set it to the passed WindowState.
1343 * @param transit If WindowManagerPolicy.TRANSIT_PREVIEW_DONE and the app window has been drawn
1344 * then the animation will be app_starting_exit. Any other value loads the animation from
1345 * the switch statement below.
1346 * @param isEntrance The animation type the last time this was called. Used to keep from
1347 * loading the same animation twice.
1348 * @return true if an animation has been loaded.
1349 */
1350 boolean applyAnimationLocked(int transit, boolean isEntrance) {
1351 if (mLocalAnimating && mAnimationIsEntrance == isEntrance) {
1352 // If we are trying to apply an animation, but already running
1353 // an animation of the same type, then just leave that one alone.
1354 return true;
1355 }
1356
1357 // Only apply an animation if the display isn't frozen. If it is
1358 // frozen, there is no reason to animate and it can cause strange
1359 // artifacts when we unfreeze the display if some different animation
1360 // is running.
1361 if (mService.okToDisplay()) {
1362 int anim = mPolicy.selectAnimationLw(mWin, transit);
1363 int attr = -1;
1364 Animation a = null;
1365 if (anim != 0) {
1366 a = AnimationUtils.loadAnimation(mContext, anim);
1367 } else {
1368 switch (transit) {
1369 case WindowManagerPolicy.TRANSIT_ENTER:
1370 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
1371 break;
1372 case WindowManagerPolicy.TRANSIT_EXIT:
1373 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
1374 break;
1375 case WindowManagerPolicy.TRANSIT_SHOW:
1376 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
1377 break;
1378 case WindowManagerPolicy.TRANSIT_HIDE:
1379 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
1380 break;
1381 }
1382 if (attr >= 0) {
1383 a = mService.loadAnimation(mWin.mAttrs, attr);
1384 }
1385 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001386 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001387 "applyAnimation: win=" + this
1388 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
Craig Mautner4d7349b2012-04-20 14:52:47 -07001389 + " a=" + a
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001390 + " mAnimation=" + mAnimation
Craig Mautner83339b42012-05-01 22:13:23 -07001391 + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3));
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001392 if (a != null) {
1393 if (WindowManagerService.DEBUG_ANIM) {
1394 RuntimeException e = null;
1395 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
1396 e = new RuntimeException();
1397 e.fillInStackTrace();
1398 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001399 Slog.v(TAG, "Loaded animation " + a + " for " + this, e);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001400 }
1401 setAnimation(a);
1402 mAnimationIsEntrance = isEntrance;
1403 }
1404 } else {
1405 clearAnimation();
1406 }
1407
1408 return mAnimation != null;
1409 }
1410
Craig Mautnera2c77052012-03-26 12:14:43 -07001411 public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
1412 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
1413 || mAnimation != null) {
1414 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
1415 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
1416 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
1417 pw.print(" mAnimation="); pw.println(mAnimation);
1418 }
1419 if (mHasTransformation || mHasLocalTransformation) {
1420 pw.print(prefix); pw.print("XForm: has=");
1421 pw.print(mHasTransformation);
1422 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
1423 pw.print(" "); mTransformation.printShortString(pw);
1424 pw.println();
1425 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001426 if (mSurface != null) {
1427 if (dumpAll) {
1428 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001429 pw.print(prefix); pw.print("mDrawState="); pw.print(mDrawState);
1430 pw.print(" mLastHidden="); pw.println(mLastHidden);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001431 }
1432 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
1433 pw.print(" layer="); pw.print(mSurfaceLayer);
1434 pw.print(" alpha="); pw.print(mSurfaceAlpha);
1435 pw.print(" rect=("); pw.print(mSurfaceX);
1436 pw.print(","); pw.print(mSurfaceY);
1437 pw.print(") "); pw.print(mSurfaceW);
1438 pw.print(" x "); pw.println(mSurfaceH);
1439 }
1440 if (mPendingDestroySurface != null) {
1441 pw.print(prefix); pw.print("mPendingDestroySurface=");
1442 pw.println(mPendingDestroySurface);
1443 }
1444 if (mSurfaceResized || mSurfaceDestroyDeferred) {
1445 pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
1446 pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
1447 }
1448 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
1449 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
1450 pw.print(" mAlpha="); pw.print(mAlpha);
1451 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
1452 }
1453 if (mHaveMatrix || mWin.mGlobalScale != 1) {
1454 pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale);
1455 pw.print(" mDsDx="); pw.print(mDsDx);
1456 pw.print(" mDtDx="); pw.print(mDtDx);
1457 pw.print(" mDsDy="); pw.print(mDsDy);
1458 pw.print(" mDtDy="); pw.println(mDtDy);
1459 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001460 }
1461
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001462 @Override
1463 public String toString() {
1464 StringBuffer sb = new StringBuffer("WindowStateAnimator (");
1465 sb.append(mWin.mLastTitle + "): ");
1466 sb.append("mSurface " + mSurface);
1467 sb.append(", mAnimation " + mAnimation);
1468 return sb.toString();
1469 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001470}