blob: 90b63a6a3c297f5f3e1eef8cc203399ae7d5f660 [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 Mautnerc2f9be02012-03-27 17:32:29 -070018import android.os.RemoteException;
Craig Mautnera2c77052012-03-26 12:14:43 -070019import android.util.Slog;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070020import android.view.Surface;
Craig Mautner7358fbf2012-04-12 21:06:33 -070021import android.view.SurfaceSession;
Craig Mautnera2c77052012-03-26 12:14:43 -070022import android.view.WindowManager;
23import android.view.WindowManagerPolicy;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070024import android.view.WindowManager.LayoutParams;
Craig Mautnera2c77052012-03-26 12:14:43 -070025import android.view.animation.Animation;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070026import android.view.animation.AnimationUtils;
Craig Mautnera2c77052012-03-26 12:14:43 -070027import android.view.animation.Transformation;
28
29import com.android.server.wm.WindowManagerService.H;
30
31import java.io.PrintWriter;
Craig Mautner7358fbf2012-04-12 21:06:33 -070032import java.util.ArrayList;
Craig Mautnera2c77052012-03-26 12:14:43 -070033
34/**
Craig Mautnerc2f9be02012-03-27 17:32:29 -070035 * Keep track of animations and surface operations for a single WindowState.
36 **/
Craig Mautnera2c77052012-03-26 12:14:43 -070037class WindowStateAnimator {
Craig Mautnerc2f9be02012-03-27 17:32:29 -070038 static final boolean DEBUG_VISIBILITY = WindowManagerService.DEBUG_VISIBILITY;
39 static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_ANIM;
40 static final boolean DEBUG_LAYERS = WindowManagerService.DEBUG_LAYERS;
41 static final boolean DEBUG_STARTING_WINDOW = WindowManagerService.DEBUG_STARTING_WINDOW;
42 static final boolean SHOW_TRANSACTIONS = WindowManagerService.SHOW_TRANSACTIONS;
43 static final boolean SHOW_LIGHT_TRANSACTIONS = WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
44 static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC;
45 static final boolean localLOGV = WindowManagerService.localLOGV;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -070046 static final boolean DEBUG_ORIENTATION = WindowManagerService.DEBUG_ORIENTATION;
Craig Mautner7358fbf2012-04-12 21:06:33 -070047 static final boolean DEBUG_SURFACE_TRACE = WindowManagerService.DEBUG_SURFACE_TRACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070048
49 static final String TAG = "WindowStateAnimator";
Craig Mautnera2c77052012-03-26 12:14:43 -070050
51 final WindowManagerService mService;
52 final WindowState mWin;
53 final WindowState mAttachedWindow;
Craig Mautnere7ae2502012-03-26 17:11:19 -070054 final WindowAnimator mAnimator;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070055 final Session mSession;
56 final WindowManagerPolicy mPolicy;
57 final Context mContext;
Craig Mautnera2c77052012-03-26 12:14:43 -070058
59 // Currently running animation.
60 boolean mAnimating;
61 boolean mLocalAnimating;
62 Animation mAnimation;
63 boolean mAnimationIsEntrance;
64 boolean mHasTransformation;
65 boolean mHasLocalTransformation;
66 final Transformation mTransformation = new Transformation();
67 boolean mWasAnimating; // Were we animating going into the most recent animation step?
Craig Mautnerc2f9be02012-03-27 17:32:29 -070068 int mAnimLayer;
69 int mLastLayer;
70
71 Surface mSurface;
72 Surface mPendingDestroySurface;
73 boolean mReportDestroySurface;
74 boolean mSurfacePendingDestroy;
75
76 /**
77 * Set when we have changed the size of the surface, to know that
78 * we must tell them application to resize (and thus redraw itself).
79 */
80 boolean mSurfaceResized;
81
82 /**
83 * Set if the client has asked that the destroy of its surface be delayed
84 * until it explicitly says it is okay.
85 */
86 boolean mSurfaceDestroyDeferred;
87
Craig Mautner7d8df392012-04-06 15:26:23 -070088 float mShownAlpha = 0;
89 float mAlpha = 0;
90 float mLastAlpha = 0;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070091
92 // Used to save animation distances between the time they are calculated and when they are
93 // used.
94 int mAnimDw;
95 int mAnimDh;
96 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
97 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
98
99 boolean mHaveMatrix;
100
101 // For debugging, this is the last information given to the surface flinger.
102 boolean mSurfaceShown;
103 float mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
104 int mSurfaceLayer;
105 float mSurfaceAlpha;
106
107 // Set to true if, when the window gets displayed, it should perform
108 // an enter animation.
109 boolean mEnterAnimationPending;
Craig Mautnera2c77052012-03-26 12:14:43 -0700110
Craig Mautner749a7bb2012-04-02 13:49:53 -0700111 /** This is set when there is no Surface */
112 static final int NO_SURFACE = 0;
113 /** This is set after the Surface has been created but before the window has been drawn. During
114 * this time the surface is hidden. */
115 static final int DRAW_PENDING = 1;
116 /** This is set after the window has finished drawing for the first time but before its surface
117 * is shown. The surface will be displayed when the next layout is run. */
118 static final int COMMIT_DRAW_PENDING = 2;
119 /** This is set during the time after the window's drawing has been committed, and before its
120 * surface is actually shown. It is used to delay showing the surface until all windows in a
121 * token are ready to be shown. */
122 static final int READY_TO_SHOW = 3;
123 /** Set when the window has been shown in the screen the first time. */
124 static final int HAS_DRAWN = 4;
125 int mDrawState;
Craig Mautnera608b882012-03-30 13:03:49 -0700126
Craig Mautner749a7bb2012-04-02 13:49:53 -0700127 /** Was this window last hidden? */
128 boolean mLastHidden;
Craig Mautnera608b882012-03-30 13:03:49 -0700129
Craig Mautnerbec53f72012-04-05 11:49:05 -0700130 int mAttrFlags;
131 int mAttrType;
132
Craig Mautnera2c77052012-03-26 12:14:43 -0700133 public WindowStateAnimator(final WindowManagerService service, final WindowState win,
134 final WindowState attachedWindow) {
135 mService = service;
136 mWin = win;
137 mAttachedWindow = attachedWindow;
Craig Mautnere7ae2502012-03-26 17:11:19 -0700138 mAnimator = mService.mAnimator;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700139 mSession = win.mSession;
140 mPolicy = mService.mPolicy;
141 mContext = mService.mContext;
Craig Mautnerbec53f72012-04-05 11:49:05 -0700142 mAttrFlags = win.mAttrs.flags;
143 mAttrType = win.mAttrs.type;
Craig Mautnera2c77052012-03-26 12:14:43 -0700144 }
145
146 public void setAnimation(Animation anim) {
Craig Mautnerbec53f72012-04-05 11:49:05 -0700147 if (localLOGV) Slog.v(TAG, "Setting animation in " + this + ": " + anim);
Craig Mautnera2c77052012-03-26 12:14:43 -0700148 mAnimating = false;
149 mLocalAnimating = false;
150 mAnimation = anim;
151 mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
152 mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale);
153 // Start out animation gone if window is gone, or visible if window is visible.
154 mTransformation.clear();
Craig Mautner749a7bb2012-04-02 13:49:53 -0700155 mTransformation.setAlpha(mLastHidden ? 0 : 1);
Craig Mautnera2c77052012-03-26 12:14:43 -0700156 mHasLocalTransformation = true;
157 }
158
159 public void clearAnimation() {
160 if (mAnimation != null) {
161 mAnimating = true;
162 mLocalAnimating = false;
163 mAnimation.cancel();
164 mAnimation = null;
165 }
166 }
167
168 /** Is the window or its container currently animating? */
169 boolean isAnimating() {
170 final WindowState attached = mAttachedWindow;
171 final AppWindowToken atoken = mWin.mAppToken;
172 return mAnimation != null
173 || (attached != null && attached.mWinAnimator.mAnimation != null)
174 || (atoken != null &&
Craig Mautner59431632012-04-04 11:56:44 -0700175 (atoken.mAppAnimator.animation != null
Craig Mautnera2c77052012-03-26 12:14:43 -0700176 || atoken.inPendingTransaction));
177 }
178
179 /** Is this window currently animating? */
180 boolean isWindowAnimating() {
181 return mAnimation != null;
182 }
183
Craig Mautnera2c77052012-03-26 12:14:43 -0700184 void cancelExitAnimationForNextAnimationLocked() {
Craig Mautnera2c77052012-03-26 12:14:43 -0700185 if (mAnimation != null) {
186 mAnimation.cancel();
187 mAnimation = null;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700188 destroySurfaceLocked();
Craig Mautnera2c77052012-03-26 12:14:43 -0700189 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700190 }
191
192 private boolean stepAnimation(long currentTime) {
193 if ((mAnimation == null) || !mLocalAnimating) {
194 return false;
195 }
196 mTransformation.clear();
197 final boolean more = mAnimation.getTransformation(currentTime, mTransformation);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700198 if (DEBUG_ANIM) Slog.v(
199 TAG, "Stepped animation in " + this +
Craig Mautnera2c77052012-03-26 12:14:43 -0700200 ": more=" + more + ", xform=" + mTransformation);
201 return more;
202 }
203
204 // This must be called while inside a transaction. Returns true if
205 // there is more animation to run.
206 boolean stepAnimationLocked(long currentTime) {
207 // Save the animation state as it was before this step so WindowManagerService can tell if
208 // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
209 mWasAnimating = mAnimating;
210 if (mService.okToDisplay()) {
211 // We will run animations as long as the display isn't frozen.
212
213 if (mWin.isDrawnLw() && mAnimation != null) {
214 mHasTransformation = true;
215 mHasLocalTransformation = true;
216 if (!mLocalAnimating) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700217 if (DEBUG_ANIM) Slog.v(
218 TAG, "Starting animation in " + this +
Craig Mautnera2c77052012-03-26 12:14:43 -0700219 " @ " + currentTime + ": ww=" + mWin.mFrame.width() +
220 " wh=" + mWin.mFrame.height() +
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700221 " dw=" + mAnimDw + " dh=" + mAnimDh +
Craig Mautnera2c77052012-03-26 12:14:43 -0700222 " scale=" + mService.mWindowAnimationScale);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700223 mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
224 mAnimDw, mAnimDh);
Craig Mautnera2c77052012-03-26 12:14:43 -0700225 mAnimation.setStartTime(currentTime);
226 mLocalAnimating = true;
227 mAnimating = true;
228 }
229 if ((mAnimation != null) && mLocalAnimating) {
230 if (stepAnimation(currentTime)) {
231 return true;
232 }
233 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700234 if (DEBUG_ANIM) Slog.v(
235 TAG, "Finished animation in " + this +
Craig Mautnera2c77052012-03-26 12:14:43 -0700236 " @ " + currentTime);
237 //WindowManagerService.this.dump();
238 }
239 mHasLocalTransformation = false;
240 if ((!mLocalAnimating || mAnimationIsEntrance) && mWin.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -0700241 && mWin.mAppToken.mAppAnimator.animation != null) {
Craig Mautnera2c77052012-03-26 12:14:43 -0700242 // When our app token is animating, we kind-of pretend like
243 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
244 // part of this check means that we will only do this if
245 // our window is not currently exiting, or it is not
246 // locally animating itself. The idea being that one that
247 // is exiting and doing a local animation should be removed
248 // once that animation is done.
249 mAnimating = true;
250 mHasTransformation = true;
251 mTransformation.clear();
252 return false;
253 } else if (mHasTransformation) {
254 // Little trick to get through the path below to act like
255 // we have finished an animation.
256 mAnimating = true;
257 } else if (isAnimating()) {
258 mAnimating = true;
259 }
260 } else if (mAnimation != null) {
261 // If the display is frozen, and there is a pending animation,
262 // clear it and make sure we run the cleanup code.
263 mAnimating = true;
264 mLocalAnimating = true;
265 mAnimation.cancel();
266 mAnimation = null;
267 }
268
269 if (!mAnimating && !mLocalAnimating) {
270 return false;
271 }
272
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700273 // Done animating, clean up.
274 if (DEBUG_ANIM) Slog.v(
275 TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting
Craig Mautnera2c77052012-03-26 12:14:43 -0700276 + ", reportedVisible="
277 + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
278
279 mAnimating = false;
280 mLocalAnimating = false;
281 if (mAnimation != null) {
282 mAnimation.cancel();
283 mAnimation = null;
284 }
Craig Mautnere7ae2502012-03-26 17:11:19 -0700285 if (mAnimator.mWindowDetachedWallpaper == mWin) {
286 mAnimator.mWindowDetachedWallpaper = null;
Craig Mautnera2c77052012-03-26 12:14:43 -0700287 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700288 mAnimLayer = mWin.mLayer;
Craig Mautnera2c77052012-03-26 12:14:43 -0700289 if (mWin.mIsImWindow) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700290 mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
Craig Mautnera2c77052012-03-26 12:14:43 -0700291 } else if (mWin.mIsWallpaper) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700292 mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
Craig Mautnera2c77052012-03-26 12:14:43 -0700293 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700294 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
295 + " anim layer: " + mAnimLayer);
Craig Mautnera2c77052012-03-26 12:14:43 -0700296 mHasTransformation = false;
297 mHasLocalTransformation = false;
298 if (mWin.mPolicyVisibility != mWin.mPolicyVisibilityAfterAnim) {
299 if (WindowState.DEBUG_VISIBILITY) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700300 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
Craig Mautnera2c77052012-03-26 12:14:43 -0700301 + mWin.mPolicyVisibilityAfterAnim);
302 }
303 mWin.mPolicyVisibility = mWin.mPolicyVisibilityAfterAnim;
304 mService.mLayoutNeeded = true;
305 if (!mWin.mPolicyVisibility) {
306 if (mService.mCurrentFocus == mWin) {
307 mService.mFocusMayChange = true;
308 }
309 // Window is no longer visible -- make sure if we were waiting
310 // for it to be displayed before enabling the display, that
311 // we allow the display to be enabled now.
312 mService.enableScreenIfNeededLocked();
313 }
314 }
315 mTransformation.clear();
Craig Mautner749a7bb2012-04-02 13:49:53 -0700316 if (mDrawState == HAS_DRAWN
Craig Mautnera2c77052012-03-26 12:14:43 -0700317 && mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
318 && mWin.mAppToken != null
319 && mWin.mAppToken.firstWindowDrawn
320 && mWin.mAppToken.startingData != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700321 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
Craig Mautnera2c77052012-03-26 12:14:43 -0700322 + mWin.mToken + ": first real window done animating");
323 mService.mFinishedStarting.add(mWin.mAppToken);
324 mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
325 }
326
327 finishExit();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700328 mAnimator.mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
329 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats(
330 "WindowStateAnimator", mAnimator.mPendingLayoutChanges);
Craig Mautnera2c77052012-03-26 12:14:43 -0700331
332 if (mWin.mAppToken != null) {
333 mWin.mAppToken.updateReportedVisibilityLocked();
334 }
335
336 return false;
337 }
338
339 void finishExit() {
340 if (WindowManagerService.DEBUG_ANIM) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700341 TAG, "finishExit in " + this
Craig Mautnera2c77052012-03-26 12:14:43 -0700342 + ": exiting=" + mWin.mExiting
343 + " remove=" + mWin.mRemoveOnExit
344 + " windowAnimating=" + isWindowAnimating());
345
346 final int N = mWin.mChildWindows.size();
347 for (int i=0; i<N; i++) {
348 mWin.mChildWindows.get(i).mWinAnimator.finishExit();
349 }
350
351 if (!mWin.mExiting) {
352 return;
353 }
354
355 if (isWindowAnimating()) {
356 return;
357 }
358
359 if (WindowManagerService.localLOGV) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700360 TAG, "Exit animation finished in " + this
Craig Mautnera2c77052012-03-26 12:14:43 -0700361 + ": remove=" + mWin.mRemoveOnExit);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700362 if (mSurface != null) {
Craig Mautnera2c77052012-03-26 12:14:43 -0700363 mService.mDestroySurface.add(mWin);
364 mWin.mDestroying = true;
365 if (WindowState.SHOW_TRANSACTIONS) WindowManagerService.logSurface(
366 mWin, "HIDE (finishExit)", null);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700367 mSurfaceShown = false;
Craig Mautnera2c77052012-03-26 12:14:43 -0700368 try {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700369 mSurface.hide();
Craig Mautnera2c77052012-03-26 12:14:43 -0700370 } catch (RuntimeException e) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700371 Slog.w(TAG, "Error hiding surface in " + this, e);
Craig Mautnera2c77052012-03-26 12:14:43 -0700372 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700373 mLastHidden = true;
Craig Mautnera2c77052012-03-26 12:14:43 -0700374 }
375 mWin.mExiting = false;
376 if (mWin.mRemoveOnExit) {
377 mService.mPendingRemove.add(mWin);
378 mWin.mRemoveOnExit = false;
379 }
380 }
381
Craig Mautnera608b882012-03-30 13:03:49 -0700382 boolean finishDrawingLocked() {
Craig Mautner749a7bb2012-04-02 13:49:53 -0700383 if (mDrawState == DRAW_PENDING) {
Craig Mautner48ba1e72012-04-02 13:18:16 -0700384 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
Craig Mautnera608b882012-03-30 13:03:49 -0700385 TAG, "finishDrawingLocked: " + this + " in " + mSurface);
Craig Mautner749a7bb2012-04-02 13:49:53 -0700386 mDrawState = COMMIT_DRAW_PENDING;
Craig Mautnera608b882012-03-30 13:03:49 -0700387 return true;
388 }
389 return false;
390 }
391
392 // This must be called while inside a transaction.
393 boolean commitFinishDrawingLocked(long currentTime) {
394 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
Craig Mautner749a7bb2012-04-02 13:49:53 -0700395 if (mDrawState != COMMIT_DRAW_PENDING) {
Craig Mautnera608b882012-03-30 13:03:49 -0700396 return false;
397 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700398 mDrawState = READY_TO_SHOW;
Craig Mautnera608b882012-03-30 13:03:49 -0700399 final boolean starting = mWin.mAttrs.type == TYPE_APPLICATION_STARTING;
400 final AppWindowToken atoken = mWin.mAppToken;
401 if (atoken == null || atoken.allDrawn || starting) {
402 performShowLocked();
403 }
404 return true;
405 }
406
Craig Mautner7d8df392012-04-06 15:26:23 -0700407 static class SurfaceTrace extends Surface {
408 private final static String SURFACE_TAG = "SurfaceTrace";
409 final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
Craig Mautner7358fbf2012-04-12 21:06:33 -0700410
Craig Mautner7d8df392012-04-06 15:26:23 -0700411 private float mSurfaceTraceAlpha = 0;
Craig Mautner7358fbf2012-04-12 21:06:33 -0700412 private int mLayer;
413 private PointF mPosition = new PointF();
Craig Mautner7d8df392012-04-06 15:26:23 -0700414 private Point mSize;
Craig Mautner7358fbf2012-04-12 21:06:33 -0700415 private boolean mShown = false;
416 private String mName = "Not named";
417
Craig Mautner7d8df392012-04-06 15:26:23 -0700418 public SurfaceTrace(SurfaceSession s,
Craig Mautner7358fbf2012-04-12 21:06:33 -0700419 int pid, int display, int w, int h, int format, int flags) throws
420 OutOfResourcesException {
421 super(s, pid, display, w, h, format, flags);
422 mSize = new Point(w, h);
Craig Mautner7d8df392012-04-06 15:26:23 -0700423 Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
424 + WindowManagerService.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700425 }
426
Craig Mautner7d8df392012-04-06 15:26:23 -0700427 public SurfaceTrace(SurfaceSession s,
Craig Mautner7358fbf2012-04-12 21:06:33 -0700428 int pid, String name, int display, int w, int h, int format, int flags)
429 throws OutOfResourcesException {
430 super(s, pid, name, display, w, h, format, flags);
431 mName = name;
432 mSize = new Point(w, h);
Craig Mautner7d8df392012-04-06 15:26:23 -0700433 Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
434 + WindowManagerService.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700435 }
436
437 @Override
438 public void setAlpha(float alpha) {
439 super.setAlpha(alpha);
Craig Mautner7d8df392012-04-06 15:26:23 -0700440 mSurfaceTraceAlpha = alpha;
441 Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by "
442 + WindowManagerService.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700443 }
444
445 @Override
446 public void setLayer(int zorder) {
447 super.setLayer(zorder);
448 mLayer = zorder;
Craig Mautner7d8df392012-04-06 15:26:23 -0700449 Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by "
450 + WindowManagerService.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700451
452 sSurfaces.remove(this);
453 int i;
454 for (i = sSurfaces.size() - 1; i >= 0; i--) {
Craig Mautner7d8df392012-04-06 15:26:23 -0700455 SurfaceTrace s = sSurfaces.get(i);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700456 if (s.mLayer < zorder) {
457 break;
458 }
459 }
460 sSurfaces.add(i + 1, this);
461 }
462
463 @Override
464 public void setPosition(float x, float y) {
465 super.setPosition(x, y);
466 mPosition = new PointF(x, y);
Craig Mautner7d8df392012-04-06 15:26:23 -0700467 Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by "
468 + WindowManagerService.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700469 }
470
471 @Override
472 public void setSize(int w, int h) {
473 super.setSize(w, h);
474 mSize = new Point(w, h);
Craig Mautner7d8df392012-04-06 15:26:23 -0700475 Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by "
476 + WindowManagerService.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700477 }
478
479 @Override
480 public void hide() {
481 super.hide();
482 mShown = false;
Craig Mautner7d8df392012-04-06 15:26:23 -0700483 Slog.v(SURFACE_TAG, "hide: " + this + ". Called by "
484 + WindowManagerService.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700485 }
486 @Override
487 public void show() {
488 super.show();
489 mShown = true;
Craig Mautner7d8df392012-04-06 15:26:23 -0700490 Slog.v(SURFACE_TAG, "show: " + this + ". Called by "
491 + WindowManagerService.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700492 }
493
494 @Override
495 public void destroy() {
496 super.destroy();
Craig Mautner7d8df392012-04-06 15:26:23 -0700497 Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
498 + WindowManagerService.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700499 sSurfaces.remove(this);
500 }
501
502 static void dumpAllSurfaces() {
503 final int N = sSurfaces.size();
504 for (int i = 0; i < N; i++) {
505 Slog.i(TAG, "SurfaceDump: " + sSurfaces.get(i));
506 }
507 }
508
509 @Override
510 public String toString() {
511 return "Surface " + mName + ": shown=" + mShown + " layer=" + mLayer
Craig Mautner7d8df392012-04-06 15:26:23 -0700512 + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
Craig Mautner7358fbf2012-04-12 21:06:33 -0700513 + " " + mSize.x + "x" + mSize.y;
514 }
515 }
516
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700517 Surface createSurfaceLocked() {
518 if (mSurface == null) {
519 mReportDestroySurface = false;
520 mSurfacePendingDestroy = false;
Craig Mautner48ba1e72012-04-02 13:18:16 -0700521 if (DEBUG_ORIENTATION) Slog.i(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700522 "createSurface " + this + ": DRAW NOW PENDING");
Craig Mautner749a7bb2012-04-02 13:49:53 -0700523 mDrawState = DRAW_PENDING;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700524 if (mWin.mAppToken != null) {
525 mWin.mAppToken.allDrawn = false;
526 }
527
528 mService.makeWindowFreezingScreenIfNeededLocked(mWin);
529
530 int flags = 0;
531 final WindowManager.LayoutParams attrs = mWin.mAttrs;
532
533 if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
534 flags |= Surface.SECURE;
535 }
536 if (WindowState.DEBUG_VISIBILITY) Slog.v(
537 TAG, "Creating surface in session "
538 + mSession.mSurfaceSession + " window " + this
539 + " w=" + mWin.mCompatFrame.width()
540 + " h=" + mWin.mCompatFrame.height() + " format="
541 + attrs.format + " flags=" + flags);
542
543 int w = mWin.mCompatFrame.width();
544 int h = mWin.mCompatFrame.height();
545 if ((attrs.flags & LayoutParams.FLAG_SCALED) != 0) {
546 // for a scaled surface, we always want the requested
547 // size.
548 w = mWin.mRequestedWidth;
549 h = mWin.mRequestedHeight;
550 }
551
552 // Something is wrong and SurfaceFlinger will not like this,
553 // try to revert to sane values
554 if (w <= 0) w = 1;
555 if (h <= 0) h = 1;
556
557 mSurfaceShown = false;
558 mSurfaceLayer = 0;
Craig Mautner7d8df392012-04-06 15:26:23 -0700559 mSurfaceAlpha = 0;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700560 mSurfaceX = 0;
561 mSurfaceY = 0;
562 mSurfaceW = w;
563 mSurfaceH = h;
564 try {
565 final boolean isHwAccelerated = (attrs.flags &
566 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
567 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
568 if (!PixelFormat.formatHasAlpha(attrs.format)) {
569 flags |= Surface.OPAQUE;
570 }
Craig Mautner7358fbf2012-04-12 21:06:33 -0700571 if (DEBUG_SURFACE_TRACE) {
Craig Mautner7d8df392012-04-06 15:26:23 -0700572 mSurface = new SurfaceTrace(
Craig Mautner7358fbf2012-04-12 21:06:33 -0700573 mSession.mSurfaceSession, mSession.mPid,
574 attrs.getTitle().toString(),
575 0, w, h, format, flags);
576 } else {
577 mSurface = new Surface(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700578 mSession.mSurfaceSession, mSession.mPid,
579 attrs.getTitle().toString(),
580 0, w, h, format, flags);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700581 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700582 mWin.mHasSurface = true;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700583 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG,
584 " CREATE SURFACE "
585 + mSurface + " IN SESSION "
586 + mSession.mSurfaceSession
587 + ": pid=" + mSession.mPid + " format="
588 + attrs.format + " flags=0x"
589 + Integer.toHexString(flags)
590 + " / " + this);
591 } catch (Surface.OutOfResourcesException e) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700592 mWin.mHasSurface = false;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700593 Slog.w(TAG, "OutOfResourcesException creating surface");
594 mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
Craig Mautner749a7bb2012-04-02 13:49:53 -0700595 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700596 return null;
597 } catch (Exception e) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700598 mWin.mHasSurface = false;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700599 Slog.e(TAG, "Exception creating surface", e);
Craig Mautner749a7bb2012-04-02 13:49:53 -0700600 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700601 return null;
602 }
603
604 if (WindowManagerService.localLOGV) Slog.v(
605 TAG, "Got surface: " + mSurface
606 + ", set left=" + mWin.mFrame.left + " top=" + mWin.mFrame.top
607 + ", animLayer=" + mAnimLayer);
608 if (SHOW_LIGHT_TRANSACTIONS) {
609 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
610 WindowManagerService.logSurface(mWin, "CREATE pos=("
611 + mWin.mFrame.left + "," + mWin.mFrame.top + ") ("
612 + mWin.mCompatFrame.width() + "x" + mWin.mCompatFrame.height()
613 + "), layer=" + mAnimLayer + " HIDE", null);
614 }
615 Surface.openTransaction();
616 try {
617 try {
618 mSurfaceX = mWin.mFrame.left + mWin.mXOffset;
619 mSurfaceY = mWin.mFrame.top + mWin.mYOffset;
620 mSurface.setPosition(mSurfaceX, mSurfaceY);
621 mSurfaceLayer = mAnimLayer;
622 mSurface.setLayer(mAnimLayer);
Craig Mautner7d8df392012-04-06 15:26:23 -0700623 mSurface.setAlpha(0);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700624 mSurfaceShown = false;
625 mSurface.hide();
626 if ((mWin.mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
627 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "DITHER", null);
628 mSurface.setFlags(Surface.SURFACE_DITHER, Surface.SURFACE_DITHER);
629 }
630 } catch (RuntimeException e) {
631 Slog.w(TAG, "Error creating surface in " + w, e);
632 mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
633 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700634 mLastHidden = true;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700635 } finally {
636 Surface.closeTransaction();
637 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
638 "<<< CLOSE TRANSACTION createSurfaceLocked");
639 }
640 if (WindowManagerService.localLOGV) Slog.v(
641 TAG, "Created surface " + this);
642 }
643 return mSurface;
644 }
645
646 void destroySurfaceLocked() {
647 if (mWin.mAppToken != null && mWin == mWin.mAppToken.startingWindow) {
648 mWin.mAppToken.startingDisplayed = false;
649 }
650
Craig Mautner749a7bb2012-04-02 13:49:53 -0700651 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700652 if (mSurface != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700653
654 int i = mWin.mChildWindows.size();
655 while (i > 0) {
656 i--;
657 WindowState c = mWin.mChildWindows.get(i);
658 c.mAttachedHidden = true;
659 }
660
661 if (mReportDestroySurface) {
662 mReportDestroySurface = false;
663 mSurfacePendingDestroy = true;
664 try {
665 mWin.mClient.dispatchGetNewSurface();
666 // We'll really destroy on the next time around.
667 return;
668 } catch (RemoteException e) {
669 }
670 }
671
672 try {
673 if (DEBUG_VISIBILITY) {
674 RuntimeException e = null;
675 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
676 e = new RuntimeException();
677 e.fillInStackTrace();
678 }
679 Slog.w(TAG, "Window " + this + " destroying surface "
680 + mSurface + ", session " + mSession, e);
681 }
682 if (mSurfaceDestroyDeferred) {
683 if (mSurface != null && mPendingDestroySurface != mSurface) {
684 if (mPendingDestroySurface != null) {
685 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
686 RuntimeException e = null;
687 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
688 e = new RuntimeException();
689 e.fillInStackTrace();
690 }
691 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
692 }
693 mPendingDestroySurface.destroy();
694 }
695 mPendingDestroySurface = mSurface;
696 }
697 } else {
698 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
699 RuntimeException e = null;
700 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
701 e = new RuntimeException();
702 e.fillInStackTrace();
703 }
704 WindowManagerService.logSurface(mWin, "DESTROY", e);
705 }
706 mSurface.destroy();
707 }
708 } catch (RuntimeException e) {
709 Slog.w(TAG, "Exception thrown when destroying Window " + this
710 + " surface " + mSurface + " session " + mSession
711 + ": " + e.toString());
712 }
713
714 mSurfaceShown = false;
715 mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700716 mWin.mHasSurface =false;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700717 }
718 }
719
720 void destroyDeferredSurfaceLocked() {
721 try {
722 if (mPendingDestroySurface != null) {
723 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
724 RuntimeException e = null;
725 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
726 e = new RuntimeException();
727 e.fillInStackTrace();
728 }
729 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
730 }
731 mPendingDestroySurface.destroy();
732 }
733 } catch (RuntimeException e) {
Craig Mautnerd87946b2012-03-29 18:00:19 -0700734 Slog.w(TAG, "Exception thrown when destroying Window "
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700735 + this + " surface " + mPendingDestroySurface
736 + " session " + mSession + ": " + e.toString());
737 }
738 mSurfaceDestroyDeferred = false;
739 mPendingDestroySurface = null;
740 }
741
742 void computeShownFrameLocked() {
743 final boolean selfTransformation = mHasLocalTransformation;
744 Transformation attachedTransformation =
745 (mAttachedWindow != null && mAttachedWindow.mWinAnimator.mHasLocalTransformation)
746 ? mAttachedWindow.mWinAnimator.mTransformation : null;
Craig Mautner59431632012-04-04 11:56:44 -0700747 final AppWindowAnimator appAnimator =
748 mWin.mAppToken == null ? null : mWin.mAppToken.mAppAnimator;
749 Transformation appTransformation = (appAnimator != null && appAnimator.hasTransformation)
750 ? appAnimator.transformation : null;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700751
752 // Wallpapers are animated based on the "real" window they
753 // are currently targeting.
754 if (mWin.mAttrs.type == TYPE_WALLPAPER && mService.mLowerWallpaperTarget == null
755 && mService.mWallpaperTarget != null) {
756 if (mService.mWallpaperTarget.mWinAnimator.mHasLocalTransformation &&
757 mService.mWallpaperTarget.mWinAnimator.mAnimation != null &&
758 !mService.mWallpaperTarget.mWinAnimator.mAnimation.getDetachWallpaper()) {
759 attachedTransformation = mService.mWallpaperTarget.mWinAnimator.mTransformation;
760 if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
761 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
762 }
763 }
Craig Mautner59431632012-04-04 11:56:44 -0700764 final AppWindowAnimator wpAppAnimator = mService.mWallpaperTarget.mAppToken == null
765 ? null : mService.mWallpaperTarget.mAppToken.mAppAnimator;
766 if (wpAppAnimator != null &&
767 wpAppAnimator.hasTransformation &&
768 wpAppAnimator.animation != null &&
769 !wpAppAnimator.animation.getDetachWallpaper()) {
770 appTransformation = wpAppAnimator.transformation;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700771 if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
772 Slog.v(TAG, "WP target app xform: " + appTransformation);
773 }
774 }
775 }
776
777 final boolean screenAnimation = mService.mAnimator.mScreenRotationAnimation != null
778 && mService.mAnimator.mScreenRotationAnimation.isAnimating();
779 if (selfTransformation || attachedTransformation != null
780 || appTransformation != null || screenAnimation) {
781 // cache often used attributes locally
782 final Rect frame = mWin.mFrame;
783 final float tmpFloats[] = mService.mTmpFloats;
784 final Matrix tmpMatrix = mWin.mTmpMatrix;
785
786 // Compute the desired transformation.
787 if (screenAnimation) {
788 // If we are doing a screen animation, the global rotation
789 // applied to windows can result in windows that are carefully
790 // aligned with each other to slightly separate, allowing you
791 // to see what is behind them. An unsightly mess. This...
792 // thing... magically makes it call good: scale each window
793 // slightly (two pixels larger in each dimension, from the
794 // window's center).
795 final float w = frame.width();
796 final float h = frame.height();
797 if (w>=1 && h>=1) {
798 tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
799 } else {
800 tmpMatrix.reset();
801 }
802 } else {
803 tmpMatrix.reset();
804 }
805 tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
806 if (selfTransformation) {
807 tmpMatrix.postConcat(mTransformation.getMatrix());
808 }
809 tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
810 if (attachedTransformation != null) {
811 tmpMatrix.postConcat(attachedTransformation.getMatrix());
812 }
813 if (appTransformation != null) {
814 tmpMatrix.postConcat(appTransformation.getMatrix());
815 }
816 if (screenAnimation) {
817 tmpMatrix.postConcat(
818 mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getMatrix());
819 }
820
821 // "convert" it into SurfaceFlinger's format
822 // (a 2x2 matrix + an offset)
823 // Here we must not transform the position of the surface
824 // since it is already included in the transformation.
825 //Slog.i(TAG, "Transform: " + matrix);
826
827 mHaveMatrix = true;
828 tmpMatrix.getValues(tmpFloats);
829 mDsDx = tmpFloats[Matrix.MSCALE_X];
830 mDtDx = tmpFloats[Matrix.MSKEW_Y];
831 mDsDy = tmpFloats[Matrix.MSKEW_X];
832 mDtDy = tmpFloats[Matrix.MSCALE_Y];
833 float x = tmpFloats[Matrix.MTRANS_X];
834 float y = tmpFloats[Matrix.MTRANS_Y];
835 int w = frame.width();
836 int h = frame.height();
837 mWin.mShownFrame.set(x, y, x+w, y+h);
838
839 // Now set the alpha... but because our current hardware
840 // can't do alpha transformation on a non-opaque surface,
841 // turn it off if we are running an animation that is also
842 // transforming since it is more important to have that
843 // animation be smooth.
844 mShownAlpha = mAlpha;
845 if (!mService.mLimitedAlphaCompositing
846 || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
847 || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
848 && x == frame.left && y == frame.top))) {
849 //Slog.i(TAG, "Applying alpha transform");
850 if (selfTransformation) {
851 mShownAlpha *= mTransformation.getAlpha();
852 }
853 if (attachedTransformation != null) {
854 mShownAlpha *= attachedTransformation.getAlpha();
855 }
856 if (appTransformation != null) {
857 mShownAlpha *= appTransformation.getAlpha();
858 }
859 if (screenAnimation) {
860 mShownAlpha *=
861 mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha();
862 }
863 } else {
864 //Slog.i(TAG, "Not applying alpha transform");
865 }
866
867 if (WindowManagerService.localLOGV) Slog.v(
868 TAG, "computeShownFrameLocked: Animating " + this +
869 ": " + mWin.mShownFrame +
870 ", alpha=" + mTransformation.getAlpha() + ", mShownAlpha=" + mShownAlpha);
871 return;
872 }
873
874 if (WindowManagerService.localLOGV) Slog.v(
875 TAG, "computeShownFrameLocked: " + this +
876 " not attached, mAlpha=" + mAlpha);
877 mWin.mShownFrame.set(mWin.mFrame);
878 if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
879 mWin.mShownFrame.offset(mWin.mXOffset, mWin.mYOffset);
880 }
881 mShownAlpha = mAlpha;
882 mHaveMatrix = false;
883 mDsDx = mWin.mGlobalScale;
884 mDtDx = 0;
885 mDsDy = 0;
886 mDtDy = mWin.mGlobalScale;
887 }
Craig Mautnerd87946b2012-03-29 18:00:19 -0700888
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700889 public void prepareSurfaceLocked(final boolean recoveringMemory) {
890 final WindowState w = mWin;
891 if (mSurface == null) {
892 if (w.mOrientationChanging) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700893 if (DEBUG_ORIENTATION) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700894 Slog.v(TAG, "Orientation change skips hidden " + w);
895 }
896 w.mOrientationChanging = false;
897 }
898 return;
899 }
900
901 boolean displayed = false;
902
903 computeShownFrameLocked();
904
905 int width, height;
906 if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
907 // for a scaled surface, we just want to use
908 // the requested size.
909 width = w.mRequestedWidth;
910 height = w.mRequestedHeight;
911 } else {
912 width = w.mCompatFrame.width();
913 height = w.mCompatFrame.height();
914 }
915
916 if (width < 1) {
917 width = 1;
918 }
919 if (height < 1) {
920 height = 1;
921 }
922 final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height;
923 if (surfaceResized) {
924 mSurfaceW = width;
925 mSurfaceH = height;
926 }
927
928 if (mSurfaceX != w.mShownFrame.left
929 || mSurfaceY != w.mShownFrame.top) {
930 try {
931 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
932 "POS " + w.mShownFrame.left
933 + ", " + w.mShownFrame.top, null);
934 mSurfaceX = w.mShownFrame.left;
935 mSurfaceY = w.mShownFrame.top;
936 mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
937 } catch (RuntimeException e) {
938 Slog.w(TAG, "Error positioning surface of " + w
939 + " pos=(" + w.mShownFrame.left
940 + "," + w.mShownFrame.top + ")", e);
941 if (!recoveringMemory) {
942 mService.reclaimSomeSurfaceMemoryLocked(this, "position", true);
943 }
944 }
945 }
946
947 if (surfaceResized) {
948 try {
949 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
950 "SIZE " + width + "x" + height, null);
951 mSurfaceResized = true;
952 mSurface.setSize(width, height);
953 } catch (RuntimeException e) {
954 // If something goes wrong with the surface (such
955 // as running out of memory), don't take down the
956 // entire system.
957 Slog.e(TAG, "Error resizing surface of " + w
958 + " size=(" + width + "x" + height + ")", e);
959 if (!recoveringMemory) {
960 mService.reclaimSomeSurfaceMemoryLocked(this, "size", true);
961 }
962 }
963 }
964
965 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
Craig Mautner749a7bb2012-04-02 13:49:53 -0700966 if (!mLastHidden) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700967 //dump();
Craig Mautner749a7bb2012-04-02 13:49:53 -0700968 mLastHidden = true;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700969 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
970 "HIDE (performLayout)", null);
971 if (mSurface != null) {
972 mSurfaceShown = false;
973 try {
974 mSurface.hide();
975 } catch (RuntimeException e) {
976 Slog.w(TAG, "Exception hiding surface in " + w);
977 }
978 }
979 }
980 // If we are waiting for this window to handle an
981 // orientation change, well, it is hidden, so
982 // doesn't really matter. Note that this does
983 // introduce a potential glitch if the window
984 // becomes unhidden before it has drawn for the
985 // new orientation.
986 if (w.mOrientationChanging) {
987 w.mOrientationChanging = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700988 if (DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700989 "Orientation change skips hidden " + w);
990 }
991 } else if (mLastLayer != mAnimLayer
992 || mLastAlpha != mShownAlpha
993 || mLastDsDx != mDsDx
994 || mLastDtDx != mDtDx
995 || mLastDsDy != mDsDy
996 || mLastDtDy != mDtDy
997 || w.mLastHScale != w.mHScale
998 || w.mLastVScale != w.mVScale
Craig Mautner749a7bb2012-04-02 13:49:53 -0700999 || mLastHidden) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001000 displayed = true;
1001 mLastAlpha = mShownAlpha;
1002 mLastLayer = mAnimLayer;
1003 mLastDsDx = mDsDx;
1004 mLastDtDx = mDtDx;
1005 mLastDsDy = mDsDy;
1006 mLastDtDy = mDtDy;
1007 w.mLastHScale = w.mHScale;
1008 w.mLastVScale = w.mVScale;
1009 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1010 "alpha=" + mShownAlpha + " layer=" + mAnimLayer
1011 + " matrix=[" + (mDsDx*w.mHScale)
1012 + "," + (mDtDx*w.mVScale)
1013 + "][" + (mDsDy*w.mHScale)
1014 + "," + (mDtDy*w.mVScale) + "]", null);
1015 if (mSurface != null) {
1016 try {
1017 mSurfaceAlpha = mShownAlpha;
1018 mSurface.setAlpha(mShownAlpha);
1019 mSurfaceLayer = w.mWinAnimator.mAnimLayer;
1020 mSurface.setLayer(w.mWinAnimator.mAnimLayer);
1021 mSurface.setMatrix(
1022 mDsDx*w.mHScale, mDtDx*w.mVScale,
1023 mDsDy*w.mHScale, mDtDy*w.mVScale);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001024
1025 if (mLastHidden && mDrawState == HAS_DRAWN) {
1026 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1027 "SHOW (performLayout)", null);
1028 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
1029 + " during relayout");
1030 if (showSurfaceRobustlyLocked()) {
1031 mLastHidden = false;
1032 } else {
1033 w.mOrientationChanging = false;
1034 }
1035 }
1036 if (mSurface != null) {
1037 w.mToken.hasVisible = true;
1038 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001039 } catch (RuntimeException e) {
1040 Slog.w(TAG, "Error updating surface in " + w, e);
1041 if (!recoveringMemory) {
1042 mService.reclaimSomeSurfaceMemoryLocked(this, "update", true);
1043 }
1044 }
1045 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001046 } else {
1047 displayed = true;
1048 }
1049
1050 if (displayed) {
1051 if (w.mOrientationChanging) {
1052 if (!w.isDrawnLw()) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07001053 mAnimator.mBulkUpdateParams |= CLEAR_ORIENTATION_CHANGE_COMPLETE;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001054 if (DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001055 "Orientation continue waiting for draw in " + w);
1056 } else {
1057 w.mOrientationChanging = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001058 if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001059 }
1060 }
1061 w.mToken.hasVisible = true;
1062 }
1063 }
1064
Craig Mautner48ba1e72012-04-02 13:18:16 -07001065 void setTransparentRegionHint(final Region region) {
Craig Mautner1f4e0cc2012-04-10 14:24:38 -07001066 if (mSurface == null) {
1067 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
1068 return;
1069 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07001070 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1071 ">>> OPEN TRANSACTION setTransparentRegion");
1072 Surface.openTransaction();
1073 try {
1074 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
1075 "transparentRegionHint=" + region, null);
1076 mSurface.setTransparentRegionHint(region);
1077 } finally {
1078 Surface.closeTransaction();
1079 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1080 "<<< CLOSE TRANSACTION setTransparentRegion");
1081 }
1082 }
1083
1084 void setWallpaperOffset(int left, int top) {
1085 Surface.openTransaction();
1086 try {
1087 mSurfaceX = left;
1088 mSurfaceY = top;
1089 mSurface.setPosition(left, top);
1090 } catch (RuntimeException e) {
1091 Slog.w(TAG, "Error positioning surface of " + mWin
1092 + " pos=(" + left + "," + top + ")", e);
1093 }
1094 Surface.closeTransaction();
1095 }
1096
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001097 // This must be called while inside a transaction.
1098 boolean performShowLocked() {
1099 if (DEBUG_VISIBILITY) {
1100 RuntimeException e = null;
1101 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
1102 e = new RuntimeException();
1103 e.fillInStackTrace();
1104 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001105 Slog.v(TAG, "performShow on " + this
Craig Mautner749a7bb2012-04-02 13:49:53 -07001106 + ": mDrawState=" + mDrawState + " readyForDisplay="
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001107 + mWin.isReadyForDisplay()
1108 + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING), e);
1109 }
Craig Mautner749a7bb2012-04-02 13:49:53 -07001110 if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplay()) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001111 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001112 WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null);
Craig Mautnerd87946b2012-03-29 18:00:19 -07001113 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001114 + " during animation: policyVis=" + mWin.mPolicyVisibility
1115 + " attHidden=" + mWin.mAttachedHidden
1116 + " tok.hiddenRequested="
1117 + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
1118 + " tok.hidden="
1119 + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
1120 + " animating=" + mAnimating
1121 + " tok animating="
Craig Mautner59431632012-04-04 11:56:44 -07001122 + (mWin.mAppToken != null ? mWin.mAppToken.mAppAnimator.animating : false));
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001123 if (!showSurfaceRobustlyLocked()) {
1124 return false;
1125 }
1126
1127 mService.enableScreenIfNeededLocked();
1128
1129 applyEnterAnimationLocked();
1130
1131 mLastAlpha = -1;
Craig Mautner749a7bb2012-04-02 13:49:53 -07001132 mLastHidden = false;
1133 mDrawState = HAS_DRAWN;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001134
1135 int i = mWin.mChildWindows.size();
1136 while (i > 0) {
1137 i--;
1138 WindowState c = mWin.mChildWindows.get(i);
1139 if (c.mAttachedHidden) {
1140 c.mAttachedHidden = false;
1141 if (c.mWinAnimator.mSurface != null) {
1142 c.mWinAnimator.performShowLocked();
1143 // It hadn't been shown, which means layout not
1144 // performed on it, so now we want to make sure to
1145 // do a layout. If called from within the transaction
1146 // loop, this will cause it to restart with a new
1147 // layout.
1148 mService.mLayoutNeeded = true;
1149 }
1150 }
1151 }
1152
1153 if (mWin.mAttrs.type != TYPE_APPLICATION_STARTING
1154 && mWin.mAppToken != null) {
1155 mWin.mAppToken.firstWindowDrawn = true;
1156
1157 if (mWin.mAppToken.startingData != null) {
1158 if (WindowManagerService.DEBUG_STARTING_WINDOW ||
Craig Mautnerd87946b2012-03-29 18:00:19 -07001159 WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001160 "Finish starting " + mWin.mToken
1161 + ": first real window is shown, no animation");
1162 // If this initial window is animating, stop it -- we
1163 // will do an animation to reveal it from behind the
1164 // starting window, so there is no need for it to also
1165 // be doing its own stuff.
1166 if (mAnimation != null) {
1167 mAnimation.cancel();
1168 mAnimation = null;
1169 // Make sure we clean up the animation.
1170 mAnimating = true;
1171 }
1172 mService.mFinishedStarting.add(mWin.mAppToken);
1173 mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
1174 }
1175 mWin.mAppToken.updateReportedVisibilityLocked();
1176 }
1177
1178 return true;
1179 }
1180
1181 return false;
1182 }
1183
1184 /**
1185 * Have the surface flinger show a surface, robustly dealing with
1186 * error conditions. In particular, if there is not enough memory
1187 * to show the surface, then we will try to get rid of other surfaces
1188 * in order to succeed.
1189 *
1190 * @return Returns true if the surface was successfully shown.
1191 */
1192 boolean showSurfaceRobustlyLocked() {
1193 try {
1194 if (mSurface != null) {
1195 mSurfaceShown = true;
1196 mSurface.show();
1197 if (mWin.mTurnOnScreen) {
1198 if (DEBUG_VISIBILITY) Slog.v(TAG,
1199 "Show surface turning screen on: " + mWin);
1200 mWin.mTurnOnScreen = false;
Craig Mautner7d8df392012-04-06 15:26:23 -07001201 mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001202 }
1203 }
1204 return true;
1205 } catch (RuntimeException e) {
1206 Slog.w(TAG, "Failure showing surface " + mSurface + " in " + mWin, e);
1207 }
1208
1209 mService.reclaimSomeSurfaceMemoryLocked(this, "show", true);
1210
1211 return false;
1212 }
1213
1214 void applyEnterAnimationLocked() {
1215 final int transit;
1216 if (mEnterAnimationPending) {
1217 mEnterAnimationPending = false;
1218 transit = WindowManagerPolicy.TRANSIT_ENTER;
1219 } else {
1220 transit = WindowManagerPolicy.TRANSIT_SHOW;
1221 }
1222
1223 applyAnimationLocked(transit, true);
1224 }
1225
Craig Mautner48ba1e72012-04-02 13:18:16 -07001226 // TODO(cmautner): Move back to WindowState?
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001227 /**
1228 * Choose the correct animation and set it to the passed WindowState.
1229 * @param transit If WindowManagerPolicy.TRANSIT_PREVIEW_DONE and the app window has been drawn
1230 * then the animation will be app_starting_exit. Any other value loads the animation from
1231 * the switch statement below.
1232 * @param isEntrance The animation type the last time this was called. Used to keep from
1233 * loading the same animation twice.
1234 * @return true if an animation has been loaded.
1235 */
1236 boolean applyAnimationLocked(int transit, boolean isEntrance) {
1237 if (mLocalAnimating && mAnimationIsEntrance == isEntrance) {
1238 // If we are trying to apply an animation, but already running
1239 // an animation of the same type, then just leave that one alone.
1240 return true;
1241 }
1242
1243 // Only apply an animation if the display isn't frozen. If it is
1244 // frozen, there is no reason to animate and it can cause strange
1245 // artifacts when we unfreeze the display if some different animation
1246 // is running.
1247 if (mService.okToDisplay()) {
1248 int anim = mPolicy.selectAnimationLw(mWin, transit);
1249 int attr = -1;
1250 Animation a = null;
1251 if (anim != 0) {
1252 a = AnimationUtils.loadAnimation(mContext, anim);
1253 } else {
1254 switch (transit) {
1255 case WindowManagerPolicy.TRANSIT_ENTER:
1256 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
1257 break;
1258 case WindowManagerPolicy.TRANSIT_EXIT:
1259 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
1260 break;
1261 case WindowManagerPolicy.TRANSIT_SHOW:
1262 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
1263 break;
1264 case WindowManagerPolicy.TRANSIT_HIDE:
1265 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
1266 break;
1267 }
1268 if (attr >= 0) {
1269 a = mService.loadAnimation(mWin.mAttrs, attr);
1270 }
1271 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001272 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001273 "applyAnimation: win=" + this
1274 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
1275 + " mAnimation=" + mAnimation
1276 + " isEntrance=" + isEntrance);
1277 if (a != null) {
1278 if (WindowManagerService.DEBUG_ANIM) {
1279 RuntimeException e = null;
1280 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
1281 e = new RuntimeException();
1282 e.fillInStackTrace();
1283 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001284 Slog.v(TAG, "Loaded animation " + a + " for " + this, e);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001285 }
1286 setAnimation(a);
1287 mAnimationIsEntrance = isEntrance;
1288 }
1289 } else {
1290 clearAnimation();
1291 }
1292
1293 return mAnimation != null;
1294 }
1295
Craig Mautnera2c77052012-03-26 12:14:43 -07001296 public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
1297 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
1298 || mAnimation != null) {
1299 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
1300 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
1301 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
1302 pw.print(" mAnimation="); pw.println(mAnimation);
1303 }
1304 if (mHasTransformation || mHasLocalTransformation) {
1305 pw.print(prefix); pw.print("XForm: has=");
1306 pw.print(mHasTransformation);
1307 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
1308 pw.print(" "); mTransformation.printShortString(pw);
1309 pw.println();
1310 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001311 if (mSurface != null) {
1312 if (dumpAll) {
1313 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001314 pw.print(prefix); pw.print("mDrawState="); pw.print(mDrawState);
1315 pw.print(" mLastHidden="); pw.println(mLastHidden);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001316 }
1317 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
1318 pw.print(" layer="); pw.print(mSurfaceLayer);
1319 pw.print(" alpha="); pw.print(mSurfaceAlpha);
1320 pw.print(" rect=("); pw.print(mSurfaceX);
1321 pw.print(","); pw.print(mSurfaceY);
1322 pw.print(") "); pw.print(mSurfaceW);
1323 pw.print(" x "); pw.println(mSurfaceH);
1324 }
1325 if (mPendingDestroySurface != null) {
1326 pw.print(prefix); pw.print("mPendingDestroySurface=");
1327 pw.println(mPendingDestroySurface);
1328 }
1329 if (mSurfaceResized || mSurfaceDestroyDeferred) {
1330 pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
1331 pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
1332 }
1333 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
1334 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
1335 pw.print(" mAlpha="); pw.print(mAlpha);
1336 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
1337 }
1338 if (mHaveMatrix || mWin.mGlobalScale != 1) {
1339 pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale);
1340 pw.print(" mDsDx="); pw.print(mDsDx);
1341 pw.print(" mDtDx="); pw.print(mDtDx);
1342 pw.print(" mDsDy="); pw.print(mDsDy);
1343 pw.print(" mDtDy="); pw.println(mDtDy);
1344 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001345 }
1346
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001347 @Override
1348 public String toString() {
1349 StringBuffer sb = new StringBuffer("WindowStateAnimator (");
1350 sb.append(mWin.mLastTitle + "): ");
1351 sb.append("mSurface " + mSurface);
1352 sb.append(", mAnimation " + mAnimation);
1353 return sb.toString();
1354 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001355}