blob: a788ceeb0d01f76f2009135819c0a6717fc28a44 [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 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
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070059 // If this is a universe background window, this is the transformation
60 // it is applying to the rest of the universe.
61 final Transformation mUniverseTransform = new Transformation();
62
Craig Mautnera2c77052012-03-26 12:14:43 -070063 // Currently running animation.
64 boolean mAnimating;
65 boolean mLocalAnimating;
66 Animation mAnimation;
67 boolean mAnimationIsEntrance;
68 boolean mHasTransformation;
69 boolean mHasLocalTransformation;
70 final Transformation mTransformation = new Transformation();
71 boolean mWasAnimating; // Were we animating going into the most recent animation step?
Craig Mautnerc2f9be02012-03-27 17:32:29 -070072 int mAnimLayer;
73 int mLastLayer;
74
75 Surface mSurface;
76 Surface mPendingDestroySurface;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070077
78 /**
79 * Set when we have changed the size of the surface, to know that
80 * we must tell them application to resize (and thus redraw itself).
81 */
82 boolean mSurfaceResized;
83
84 /**
85 * Set if the client has asked that the destroy of its surface be delayed
86 * until it explicitly says it is okay.
87 */
88 boolean mSurfaceDestroyDeferred;
89
Craig Mautner7d8df392012-04-06 15:26:23 -070090 float mShownAlpha = 0;
91 float mAlpha = 0;
92 float mLastAlpha = 0;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070093
94 // Used to save animation distances between the time they are calculated and when they are
95 // used.
96 int mAnimDw;
97 int mAnimDh;
98 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
99 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
100
101 boolean mHaveMatrix;
102
103 // For debugging, this is the last information given to the surface flinger.
104 boolean mSurfaceShown;
105 float mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
106 int mSurfaceLayer;
107 float mSurfaceAlpha;
108
109 // Set to true if, when the window gets displayed, it should perform
110 // an enter animation.
111 boolean mEnterAnimationPending;
Craig Mautnera2c77052012-03-26 12:14:43 -0700112
Craig Mautner749a7bb2012-04-02 13:49:53 -0700113 /** This is set when there is no Surface */
114 static final int NO_SURFACE = 0;
115 /** This is set after the Surface has been created but before the window has been drawn. During
116 * this time the surface is hidden. */
117 static final int DRAW_PENDING = 1;
118 /** This is set after the window has finished drawing for the first time but before its surface
119 * is shown. The surface will be displayed when the next layout is run. */
120 static final int COMMIT_DRAW_PENDING = 2;
121 /** This is set during the time after the window's drawing has been committed, and before its
122 * surface is actually shown. It is used to delay showing the surface until all windows in a
123 * token are ready to be shown. */
124 static final int READY_TO_SHOW = 3;
125 /** Set when the window has been shown in the screen the first time. */
126 static final int HAS_DRAWN = 4;
Craig Mautner6fbda632012-07-03 09:26:39 -0700127 static String drawStateToString(int state) {
128 switch (state) {
129 case NO_SURFACE: return "NO_SURFACE";
130 case DRAW_PENDING: return "DRAW_PENDING";
131 case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING";
132 case READY_TO_SHOW: return "READY_TO_SHOW";
133 case HAS_DRAWN: return "HAS_DRAWN";
134 default: return Integer.toString(state);
135 }
136 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700137 int mDrawState;
Craig Mautnera608b882012-03-30 13:03:49 -0700138
Craig Mautner749a7bb2012-04-02 13:49:53 -0700139 /** Was this window last hidden? */
140 boolean mLastHidden;
Craig Mautnera608b882012-03-30 13:03:49 -0700141
Craig Mautnerbec53f72012-04-05 11:49:05 -0700142 int mAttrFlags;
143 int mAttrType;
144
Craig Mautnera2c77052012-03-26 12:14:43 -0700145 public WindowStateAnimator(final WindowManagerService service, final WindowState win,
146 final WindowState attachedWindow) {
147 mService = service;
148 mWin = win;
149 mAttachedWindow = attachedWindow;
Craig Mautnere7ae2502012-03-26 17:11:19 -0700150 mAnimator = mService.mAnimator;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700151 mSession = win.mSession;
152 mPolicy = mService.mPolicy;
153 mContext = mService.mContext;
Craig Mautnerbec53f72012-04-05 11:49:05 -0700154 mAttrFlags = win.mAttrs.flags;
155 mAttrType = win.mAttrs.type;
Craig Mautner9aa69582012-05-09 17:41:13 -0700156 mAnimDw = service.mAppDisplayWidth;
157 mAnimDh = service.mAppDisplayHeight;
Craig Mautnera2c77052012-03-26 12:14:43 -0700158 }
159
160 public void setAnimation(Animation anim) {
Craig Mautnerbec53f72012-04-05 11:49:05 -0700161 if (localLOGV) Slog.v(TAG, "Setting animation in " + this + ": " + anim);
Craig Mautnera2c77052012-03-26 12:14:43 -0700162 mAnimating = false;
163 mLocalAnimating = false;
164 mAnimation = anim;
165 mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
166 mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale);
167 // Start out animation gone if window is gone, or visible if window is visible.
168 mTransformation.clear();
Craig Mautner749a7bb2012-04-02 13:49:53 -0700169 mTransformation.setAlpha(mLastHidden ? 0 : 1);
Craig Mautnera2c77052012-03-26 12:14:43 -0700170 mHasLocalTransformation = true;
171 }
172
173 public void clearAnimation() {
174 if (mAnimation != null) {
175 mAnimating = true;
176 mLocalAnimating = false;
177 mAnimation.cancel();
178 mAnimation = null;
179 }
180 }
181
182 /** Is the window or its container currently animating? */
183 boolean isAnimating() {
184 final WindowState attached = mAttachedWindow;
185 final AppWindowToken atoken = mWin.mAppToken;
186 return mAnimation != null
187 || (attached != null && attached.mWinAnimator.mAnimation != null)
188 || (atoken != null &&
Craig Mautner59431632012-04-04 11:56:44 -0700189 (atoken.mAppAnimator.animation != null
Craig Mautnera2c77052012-03-26 12:14:43 -0700190 || atoken.inPendingTransaction));
191 }
192
Craig Mautner0afddcb2012-05-08 15:38:00 -0700193 /** Is the window animating the DummyAnimation? */
194 boolean isDummyAnimation() {
195 final AppWindowToken atoken = mWin.mAppToken;
196 return atoken != null
197 && atoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation;
198 }
199
Craig Mautnera2c77052012-03-26 12:14:43 -0700200 /** Is this window currently animating? */
201 boolean isWindowAnimating() {
202 return mAnimation != null;
203 }
204
Craig Mautnera2c77052012-03-26 12:14:43 -0700205 void cancelExitAnimationForNextAnimationLocked() {
Craig Mautnera2c77052012-03-26 12:14:43 -0700206 if (mAnimation != null) {
207 mAnimation.cancel();
208 mAnimation = null;
Craig Mautner4d7349b2012-04-20 14:52:47 -0700209 mLocalAnimating = false;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700210 destroySurfaceLocked();
Craig Mautnera2c77052012-03-26 12:14:43 -0700211 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700212 }
213
214 private boolean stepAnimation(long currentTime) {
215 if ((mAnimation == null) || !mLocalAnimating) {
216 return false;
217 }
218 mTransformation.clear();
219 final boolean more = mAnimation.getTransformation(currentTime, mTransformation);
Craig Mautner9e809442012-06-22 17:13:04 -0700220 if (false && DEBUG_ANIM) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700221 TAG, "Stepped animation in " + this +
Craig Mautnera2c77052012-03-26 12:14:43 -0700222 ": more=" + more + ", xform=" + mTransformation);
223 return more;
224 }
225
226 // This must be called while inside a transaction. Returns true if
227 // there is more animation to run.
228 boolean stepAnimationLocked(long currentTime) {
229 // Save the animation state as it was before this step so WindowManagerService can tell if
230 // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
231 mWasAnimating = mAnimating;
232 if (mService.okToDisplay()) {
233 // We will run animations as long as the display isn't frozen.
234
235 if (mWin.isDrawnLw() && mAnimation != null) {
236 mHasTransformation = true;
237 mHasLocalTransformation = true;
238 if (!mLocalAnimating) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700239 if (DEBUG_ANIM) Slog.v(
240 TAG, "Starting animation in " + this +
Craig Mautnera2c77052012-03-26 12:14:43 -0700241 " @ " + currentTime + ": ww=" + mWin.mFrame.width() +
242 " wh=" + mWin.mFrame.height() +
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700243 " dw=" + mAnimDw + " dh=" + mAnimDh +
Craig Mautnera2c77052012-03-26 12:14:43 -0700244 " scale=" + mService.mWindowAnimationScale);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700245 mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
246 mAnimDw, mAnimDh);
Craig Mautner9aa69582012-05-09 17:41:13 -0700247 mAnimDw = mService.mAppDisplayWidth;
248 mAnimDh = mService.mAppDisplayHeight;
Craig Mautnera2c77052012-03-26 12:14:43 -0700249 mAnimation.setStartTime(currentTime);
250 mLocalAnimating = true;
251 mAnimating = true;
252 }
253 if ((mAnimation != null) && mLocalAnimating) {
254 if (stepAnimation(currentTime)) {
255 return true;
256 }
257 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700258 if (DEBUG_ANIM) Slog.v(
259 TAG, "Finished animation in " + this +
Craig Mautnera2c77052012-03-26 12:14:43 -0700260 " @ " + currentTime);
261 //WindowManagerService.this.dump();
262 }
263 mHasLocalTransformation = false;
264 if ((!mLocalAnimating || mAnimationIsEntrance) && mWin.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -0700265 && mWin.mAppToken.mAppAnimator.animation != null) {
Craig Mautnera2c77052012-03-26 12:14:43 -0700266 // When our app token is animating, we kind-of pretend like
267 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
268 // part of this check means that we will only do this if
269 // our window is not currently exiting, or it is not
270 // locally animating itself. The idea being that one that
271 // is exiting and doing a local animation should be removed
272 // once that animation is done.
273 mAnimating = true;
274 mHasTransformation = true;
275 mTransformation.clear();
276 return false;
277 } else if (mHasTransformation) {
278 // Little trick to get through the path below to act like
279 // we have finished an animation.
280 mAnimating = true;
281 } else if (isAnimating()) {
282 mAnimating = true;
283 }
284 } else if (mAnimation != null) {
285 // If the display is frozen, and there is a pending animation,
286 // clear it and make sure we run the cleanup code.
287 mAnimating = true;
Craig Mautnera2c77052012-03-26 12:14:43 -0700288 }
289
290 if (!mAnimating && !mLocalAnimating) {
291 return false;
292 }
293
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700294 // Done animating, clean up.
295 if (DEBUG_ANIM) Slog.v(
296 TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting
Craig Mautnera2c77052012-03-26 12:14:43 -0700297 + ", reportedVisible="
298 + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
299
300 mAnimating = false;
301 mLocalAnimating = false;
302 if (mAnimation != null) {
303 mAnimation.cancel();
304 mAnimation = null;
305 }
Craig Mautnere7ae2502012-03-26 17:11:19 -0700306 if (mAnimator.mWindowDetachedWallpaper == mWin) {
307 mAnimator.mWindowDetachedWallpaper = null;
Craig Mautnera2c77052012-03-26 12:14:43 -0700308 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700309 mAnimLayer = mWin.mLayer;
Craig Mautnera2c77052012-03-26 12:14:43 -0700310 if (mWin.mIsImWindow) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700311 mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
Craig Mautnera2c77052012-03-26 12:14:43 -0700312 } else if (mWin.mIsWallpaper) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700313 mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
Craig Mautnera2c77052012-03-26 12:14:43 -0700314 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700315 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
316 + " anim layer: " + mAnimLayer);
Craig Mautnera2c77052012-03-26 12:14:43 -0700317 mHasTransformation = false;
318 mHasLocalTransformation = false;
319 if (mWin.mPolicyVisibility != mWin.mPolicyVisibilityAfterAnim) {
320 if (WindowState.DEBUG_VISIBILITY) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700321 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
Craig Mautnera2c77052012-03-26 12:14:43 -0700322 + mWin.mPolicyVisibilityAfterAnim);
323 }
324 mWin.mPolicyVisibility = mWin.mPolicyVisibilityAfterAnim;
325 mService.mLayoutNeeded = true;
326 if (!mWin.mPolicyVisibility) {
327 if (mService.mCurrentFocus == mWin) {
328 mService.mFocusMayChange = true;
329 }
330 // Window is no longer visible -- make sure if we were waiting
331 // for it to be displayed before enabling the display, that
332 // we allow the display to be enabled now.
333 mService.enableScreenIfNeededLocked();
334 }
335 }
336 mTransformation.clear();
Craig Mautner749a7bb2012-04-02 13:49:53 -0700337 if (mDrawState == HAS_DRAWN
Craig Mautnera2c77052012-03-26 12:14:43 -0700338 && mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
339 && mWin.mAppToken != null
340 && mWin.mAppToken.firstWindowDrawn
341 && mWin.mAppToken.startingData != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700342 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
Craig Mautnera2c77052012-03-26 12:14:43 -0700343 + mWin.mToken + ": first real window done animating");
344 mService.mFinishedStarting.add(mWin.mAppToken);
345 mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
346 }
347
348 finishExit();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700349 mAnimator.mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
350 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats(
351 "WindowStateAnimator", mAnimator.mPendingLayoutChanges);
Craig Mautnera2c77052012-03-26 12:14:43 -0700352
353 if (mWin.mAppToken != null) {
354 mWin.mAppToken.updateReportedVisibilityLocked();
355 }
356
357 return false;
358 }
359
360 void finishExit() {
361 if (WindowManagerService.DEBUG_ANIM) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700362 TAG, "finishExit in " + this
Craig Mautnera2c77052012-03-26 12:14:43 -0700363 + ": exiting=" + mWin.mExiting
364 + " remove=" + mWin.mRemoveOnExit
365 + " windowAnimating=" + isWindowAnimating());
366
367 final int N = mWin.mChildWindows.size();
368 for (int i=0; i<N; i++) {
369 mWin.mChildWindows.get(i).mWinAnimator.finishExit();
370 }
371
372 if (!mWin.mExiting) {
373 return;
374 }
375
376 if (isWindowAnimating()) {
377 return;
378 }
379
380 if (WindowManagerService.localLOGV) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700381 TAG, "Exit animation finished in " + this
Craig Mautnera2c77052012-03-26 12:14:43 -0700382 + ": remove=" + mWin.mRemoveOnExit);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700383 if (mSurface != null) {
Craig Mautnera2c77052012-03-26 12:14:43 -0700384 mService.mDestroySurface.add(mWin);
385 mWin.mDestroying = true;
386 if (WindowState.SHOW_TRANSACTIONS) WindowManagerService.logSurface(
387 mWin, "HIDE (finishExit)", null);
Craig Mautner0afddcb2012-05-08 15:38:00 -0700388 hide();
Craig Mautnera2c77052012-03-26 12:14:43 -0700389 }
390 mWin.mExiting = false;
391 if (mWin.mRemoveOnExit) {
392 mService.mPendingRemove.add(mWin);
393 mWin.mRemoveOnExit = false;
394 }
Craig Mautnerb9836b92012-06-11 11:40:09 -0700395 mAnimator.hideWallpapersLocked(mWin);
Craig Mautner0afddcb2012-05-08 15:38:00 -0700396 }
397
398 void hide() {
399 if (!mLastHidden) {
400 //dump();
401 mLastHidden = true;
402 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
403 "HIDE (performLayout)", null);
404 if (mSurface != null) {
405 mSurfaceShown = false;
406 try {
407 mSurface.hide();
408 } catch (RuntimeException e) {
409 Slog.w(TAG, "Exception hiding surface in " + mWin);
410 }
411 }
412 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700413 }
414
Craig Mautnera608b882012-03-30 13:03:49 -0700415 boolean finishDrawingLocked() {
Craig Mautner6fbda632012-07-03 09:26:39 -0700416 if (DEBUG_STARTING_WINDOW &&
417 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
418 Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
419 + drawStateToString(mDrawState));
420 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700421 if (mDrawState == DRAW_PENDING) {
Craig Mautneref25d7a2012-05-15 23:01:47 -0700422 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
423 Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + this + " in "
Craig Mautner83339b42012-05-01 22:13:23 -0700424 + mSurface);
Craig Mautner6fbda632012-07-03 09:26:39 -0700425 if (DEBUG_STARTING_WINDOW &&
426 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
427 Slog.v(TAG, "Draw state now committed in " + mWin);
428 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700429 mDrawState = COMMIT_DRAW_PENDING;
Craig Mautnera608b882012-03-30 13:03:49 -0700430 return true;
431 }
432 return false;
433 }
434
435 // This must be called while inside a transaction.
436 boolean commitFinishDrawingLocked(long currentTime) {
Craig Mautner6fbda632012-07-03 09:26:39 -0700437 if (DEBUG_STARTING_WINDOW &&
438 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
439 Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
440 + drawStateToString(mDrawState));
441 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700442 if (mDrawState != COMMIT_DRAW_PENDING) {
Craig Mautnera608b882012-03-30 13:03:49 -0700443 return false;
444 }
Craig Mautner6fbda632012-07-03 09:26:39 -0700445 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) {
Craig Mautner83339b42012-05-01 22:13:23 -0700446 Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurface);
Craig Mautner6fbda632012-07-03 09:26:39 -0700447 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700448 mDrawState = READY_TO_SHOW;
Craig Mautnera608b882012-03-30 13:03:49 -0700449 final boolean starting = mWin.mAttrs.type == TYPE_APPLICATION_STARTING;
450 final AppWindowToken atoken = mWin.mAppToken;
451 if (atoken == null || atoken.allDrawn || starting) {
452 performShowLocked();
453 }
454 return true;
455 }
456
Craig Mautner7d8df392012-04-06 15:26:23 -0700457 static class SurfaceTrace extends Surface {
458 private final static String SURFACE_TAG = "SurfaceTrace";
459 final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
Craig Mautner7358fbf2012-04-12 21:06:33 -0700460
Craig Mautner7d8df392012-04-06 15:26:23 -0700461 private float mSurfaceTraceAlpha = 0;
Craig Mautner7358fbf2012-04-12 21:06:33 -0700462 private int mLayer;
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700463 private final PointF mPosition = new PointF();
464 private final Point mSize = new Point();
465 private final Rect mWindowCrop = new Rect();
Craig Mautner7358fbf2012-04-12 21:06:33 -0700466 private boolean mShown = false;
467 private String mName = "Not named";
468
Craig Mautner7d8df392012-04-06 15:26:23 -0700469 public SurfaceTrace(SurfaceSession s,
Craig Mautner7358fbf2012-04-12 21:06:33 -0700470 int pid, int display, int w, int h, int format, int flags) throws
471 OutOfResourcesException {
472 super(s, pid, display, w, h, format, flags);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700473 mSize.set(w, h);
Craig Mautner7d8df392012-04-06 15:26:23 -0700474 Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700475 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700476 }
477
Craig Mautner7d8df392012-04-06 15:26:23 -0700478 public SurfaceTrace(SurfaceSession s,
Craig Mautner7358fbf2012-04-12 21:06:33 -0700479 int pid, String name, int display, int w, int h, int format, int flags)
480 throws OutOfResourcesException {
481 super(s, pid, name, display, w, h, format, flags);
482 mName = name;
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700483 mSize.set(w, h);
Craig Mautner7d8df392012-04-06 15:26:23 -0700484 Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700485 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700486 }
487
488 @Override
489 public void setAlpha(float alpha) {
490 super.setAlpha(alpha);
Craig Mautner7d8df392012-04-06 15:26:23 -0700491 mSurfaceTraceAlpha = alpha;
492 Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700493 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700494 }
495
496 @Override
497 public void setLayer(int zorder) {
498 super.setLayer(zorder);
499 mLayer = zorder;
Craig Mautner7d8df392012-04-06 15:26:23 -0700500 Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700501 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700502
503 sSurfaces.remove(this);
504 int i;
505 for (i = sSurfaces.size() - 1; i >= 0; i--) {
Craig Mautner7d8df392012-04-06 15:26:23 -0700506 SurfaceTrace s = sSurfaces.get(i);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700507 if (s.mLayer < zorder) {
508 break;
509 }
510 }
511 sSurfaces.add(i + 1, this);
512 }
513
514 @Override
515 public void setPosition(float x, float y) {
516 super.setPosition(x, y);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700517 mPosition.set(x, y);
Craig Mautner7d8df392012-04-06 15:26:23 -0700518 Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700519 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700520 }
521
522 @Override
523 public void setSize(int w, int h) {
524 super.setSize(w, h);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700525 mSize.set(w, h);
Craig Mautner7d8df392012-04-06 15:26:23 -0700526 Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700527 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700528 }
529
530 @Override
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700531 public void setWindowCrop(Rect crop) {
532 super.setWindowCrop(crop);
Craig Mautneref25d7a2012-05-15 23:01:47 -0700533 if (crop != null) {
534 mWindowCrop.set(crop);
535 }
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700536 Slog.v(SURFACE_TAG, "setWindowCrop: " + this + ". Called by "
537 + Debug.getCallers(3));
538 }
539
540 @Override
Craig Mautner7358fbf2012-04-12 21:06:33 -0700541 public void hide() {
542 super.hide();
543 mShown = false;
Craig Mautner7d8df392012-04-06 15:26:23 -0700544 Slog.v(SURFACE_TAG, "hide: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700545 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700546 }
547 @Override
548 public void show() {
549 super.show();
550 mShown = true;
Craig Mautner7d8df392012-04-06 15:26:23 -0700551 Slog.v(SURFACE_TAG, "show: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700552 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700553 }
554
555 @Override
556 public void destroy() {
557 super.destroy();
Craig Mautner7d8df392012-04-06 15:26:23 -0700558 Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700559 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700560 sSurfaces.remove(this);
561 }
562
Craig Mautneracaf9cc2012-04-17 11:45:25 -0700563 @Override
564 public void release() {
565 super.release();
566 Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700567 + Debug.getCallers(3));
Craig Mautneracaf9cc2012-04-17 11:45:25 -0700568 sSurfaces.remove(this);
569 }
570
Craig Mautner7358fbf2012-04-12 21:06:33 -0700571 static void dumpAllSurfaces() {
572 final int N = sSurfaces.size();
573 for (int i = 0; i < N; i++) {
574 Slog.i(TAG, "SurfaceDump: " + sSurfaces.get(i));
575 }
576 }
577
578 @Override
579 public String toString() {
Craig Mautnerfbf378c2012-04-23 17:24:21 -0700580 return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
581 + mName + ": shown=" + mShown + " layer=" + mLayer
Craig Mautner7d8df392012-04-06 15:26:23 -0700582 + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700583 + " " + mSize.x + "x" + mSize.y
584 + " crop=" + mWindowCrop.toShortString();
Craig Mautner7358fbf2012-04-12 21:06:33 -0700585 }
586 }
587
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700588 Surface createSurfaceLocked() {
589 if (mSurface == null) {
Craig Mautner83339b42012-05-01 22:13:23 -0700590 if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
591 "createSurface " + this + ": mDrawState=DRAW_PENDING");
Craig Mautner749a7bb2012-04-02 13:49:53 -0700592 mDrawState = DRAW_PENDING;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700593 if (mWin.mAppToken != null) {
594 mWin.mAppToken.allDrawn = false;
595 }
596
597 mService.makeWindowFreezingScreenIfNeededLocked(mWin);
598
599 int flags = 0;
600 final WindowManager.LayoutParams attrs = mWin.mAttrs;
601
602 if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
603 flags |= Surface.SECURE;
604 }
605 if (WindowState.DEBUG_VISIBILITY) Slog.v(
606 TAG, "Creating surface in session "
607 + mSession.mSurfaceSession + " window " + this
608 + " w=" + mWin.mCompatFrame.width()
609 + " h=" + mWin.mCompatFrame.height() + " format="
610 + attrs.format + " flags=" + flags);
611
612 int w = mWin.mCompatFrame.width();
613 int h = mWin.mCompatFrame.height();
614 if ((attrs.flags & LayoutParams.FLAG_SCALED) != 0) {
615 // for a scaled surface, we always want the requested
616 // size.
617 w = mWin.mRequestedWidth;
618 h = mWin.mRequestedHeight;
619 }
620
621 // Something is wrong and SurfaceFlinger will not like this,
622 // try to revert to sane values
623 if (w <= 0) w = 1;
624 if (h <= 0) h = 1;
625
626 mSurfaceShown = false;
627 mSurfaceLayer = 0;
Craig Mautner7d8df392012-04-06 15:26:23 -0700628 mSurfaceAlpha = 0;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700629 mSurfaceX = 0;
630 mSurfaceY = 0;
631 mSurfaceW = w;
632 mSurfaceH = h;
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700633 mWin.mLastSystemDecorRect.set(0, 0, 0, 0);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700634 try {
635 final boolean isHwAccelerated = (attrs.flags &
636 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
637 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
638 if (!PixelFormat.formatHasAlpha(attrs.format)) {
639 flags |= Surface.OPAQUE;
640 }
Craig Mautner7358fbf2012-04-12 21:06:33 -0700641 if (DEBUG_SURFACE_TRACE) {
Craig Mautner7d8df392012-04-06 15:26:23 -0700642 mSurface = new SurfaceTrace(
Craig Mautner7358fbf2012-04-12 21:06:33 -0700643 mSession.mSurfaceSession, mSession.mPid,
644 attrs.getTitle().toString(),
645 0, w, h, format, flags);
646 } else {
647 mSurface = new Surface(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700648 mSession.mSurfaceSession, mSession.mPid,
649 attrs.getTitle().toString(),
650 0, w, h, format, flags);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700651 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700652 mWin.mHasSurface = true;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700653 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG,
654 " CREATE SURFACE "
655 + mSurface + " IN SESSION "
656 + mSession.mSurfaceSession
657 + ": pid=" + mSession.mPid + " format="
658 + attrs.format + " flags=0x"
659 + Integer.toHexString(flags)
660 + " / " + this);
661 } catch (Surface.OutOfResourcesException e) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700662 mWin.mHasSurface = false;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700663 Slog.w(TAG, "OutOfResourcesException creating surface");
664 mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
Craig Mautner749a7bb2012-04-02 13:49:53 -0700665 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700666 return null;
667 } catch (Exception e) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700668 mWin.mHasSurface = false;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700669 Slog.e(TAG, "Exception creating surface", e);
Craig Mautner749a7bb2012-04-02 13:49:53 -0700670 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700671 return null;
672 }
673
674 if (WindowManagerService.localLOGV) Slog.v(
675 TAG, "Got surface: " + mSurface
676 + ", set left=" + mWin.mFrame.left + " top=" + mWin.mFrame.top
677 + ", animLayer=" + mAnimLayer);
678 if (SHOW_LIGHT_TRANSACTIONS) {
679 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
680 WindowManagerService.logSurface(mWin, "CREATE pos=("
681 + mWin.mFrame.left + "," + mWin.mFrame.top + ") ("
682 + mWin.mCompatFrame.width() + "x" + mWin.mCompatFrame.height()
683 + "), layer=" + mAnimLayer + " HIDE", null);
684 }
685 Surface.openTransaction();
686 try {
687 try {
688 mSurfaceX = mWin.mFrame.left + mWin.mXOffset;
689 mSurfaceY = mWin.mFrame.top + mWin.mYOffset;
690 mSurface.setPosition(mSurfaceX, mSurfaceY);
691 mSurfaceLayer = mAnimLayer;
692 mSurface.setLayer(mAnimLayer);
Craig Mautner7d8df392012-04-06 15:26:23 -0700693 mSurface.setAlpha(0);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700694 mSurfaceShown = false;
695 mSurface.hide();
696 if ((mWin.mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
697 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "DITHER", null);
698 mSurface.setFlags(Surface.SURFACE_DITHER, Surface.SURFACE_DITHER);
699 }
700 } catch (RuntimeException e) {
701 Slog.w(TAG, "Error creating surface in " + w, e);
702 mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
703 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700704 mLastHidden = true;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700705 } finally {
706 Surface.closeTransaction();
707 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
708 "<<< CLOSE TRANSACTION createSurfaceLocked");
709 }
710 if (WindowManagerService.localLOGV) Slog.v(
711 TAG, "Created surface " + this);
712 }
713 return mSurface;
714 }
715
716 void destroySurfaceLocked() {
717 if (mWin.mAppToken != null && mWin == mWin.mAppToken.startingWindow) {
718 mWin.mAppToken.startingDisplayed = false;
719 }
720
721 if (mSurface != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700722
723 int i = mWin.mChildWindows.size();
724 while (i > 0) {
725 i--;
726 WindowState c = mWin.mChildWindows.get(i);
727 c.mAttachedHidden = true;
728 }
729
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700730 try {
731 if (DEBUG_VISIBILITY) {
732 RuntimeException e = null;
733 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
734 e = new RuntimeException();
735 e.fillInStackTrace();
736 }
737 Slog.w(TAG, "Window " + this + " destroying surface "
738 + mSurface + ", session " + mSession, e);
739 }
740 if (mSurfaceDestroyDeferred) {
741 if (mSurface != null && mPendingDestroySurface != mSurface) {
742 if (mPendingDestroySurface != null) {
743 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
744 RuntimeException e = null;
745 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
746 e = new RuntimeException();
747 e.fillInStackTrace();
748 }
749 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
750 }
751 mPendingDestroySurface.destroy();
752 }
753 mPendingDestroySurface = mSurface;
754 }
755 } else {
756 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
757 RuntimeException e = null;
758 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
759 e = new RuntimeException();
760 e.fillInStackTrace();
761 }
762 WindowManagerService.logSurface(mWin, "DESTROY", e);
763 }
764 mSurface.destroy();
765 }
Craig Mautnerb9836b92012-06-11 11:40:09 -0700766 mAnimator.hideWallpapersLocked(mWin);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700767 } catch (RuntimeException e) {
768 Slog.w(TAG, "Exception thrown when destroying Window " + this
769 + " surface " + mSurface + " session " + mSession
770 + ": " + e.toString());
771 }
772
773 mSurfaceShown = false;
774 mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700775 mWin.mHasSurface =false;
Craig Mautnerbf08af32012-05-16 19:43:42 -0700776 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700777 }
778 }
779
780 void destroyDeferredSurfaceLocked() {
781 try {
782 if (mPendingDestroySurface != null) {
783 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
784 RuntimeException e = null;
785 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
786 e = new RuntimeException();
787 e.fillInStackTrace();
788 }
789 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
790 }
791 mPendingDestroySurface.destroy();
Craig Mautnerb9836b92012-06-11 11:40:09 -0700792 mAnimator.hideWallpapersLocked(mWin);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700793 }
794 } catch (RuntimeException e) {
Craig Mautnerd87946b2012-03-29 18:00:19 -0700795 Slog.w(TAG, "Exception thrown when destroying Window "
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700796 + this + " surface " + mPendingDestroySurface
797 + " session " + mSession + ": " + e.toString());
798 }
799 mSurfaceDestroyDeferred = false;
800 mPendingDestroySurface = null;
801 }
802
803 void computeShownFrameLocked() {
804 final boolean selfTransformation = mHasLocalTransformation;
805 Transformation attachedTransformation =
806 (mAttachedWindow != null && mAttachedWindow.mWinAnimator.mHasLocalTransformation)
807 ? mAttachedWindow.mWinAnimator.mTransformation : null;
Craig Mautner59431632012-04-04 11:56:44 -0700808 final AppWindowAnimator appAnimator =
809 mWin.mAppToken == null ? null : mWin.mAppToken.mAppAnimator;
810 Transformation appTransformation = (appAnimator != null && appAnimator.hasTransformation)
811 ? appAnimator.transformation : null;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700812
813 // Wallpapers are animated based on the "real" window they
814 // are currently targeting.
815 if (mWin.mAttrs.type == TYPE_WALLPAPER && mService.mLowerWallpaperTarget == null
816 && mService.mWallpaperTarget != null) {
817 if (mService.mWallpaperTarget.mWinAnimator.mHasLocalTransformation &&
818 mService.mWallpaperTarget.mWinAnimator.mAnimation != null &&
819 !mService.mWallpaperTarget.mWinAnimator.mAnimation.getDetachWallpaper()) {
820 attachedTransformation = mService.mWallpaperTarget.mWinAnimator.mTransformation;
821 if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
822 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
823 }
824 }
Craig Mautner59431632012-04-04 11:56:44 -0700825 final AppWindowAnimator wpAppAnimator = mService.mWallpaperTarget.mAppToken == null
826 ? null : mService.mWallpaperTarget.mAppToken.mAppAnimator;
827 if (wpAppAnimator != null &&
828 wpAppAnimator.hasTransformation &&
829 wpAppAnimator.animation != null &&
830 !wpAppAnimator.animation.getDetachWallpaper()) {
831 appTransformation = wpAppAnimator.transformation;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700832 if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
833 Slog.v(TAG, "WP target app xform: " + appTransformation);
834 }
835 }
836 }
837
838 final boolean screenAnimation = mService.mAnimator.mScreenRotationAnimation != null
839 && mService.mAnimator.mScreenRotationAnimation.isAnimating();
840 if (selfTransformation || attachedTransformation != null
841 || appTransformation != null || screenAnimation) {
842 // cache often used attributes locally
843 final Rect frame = mWin.mFrame;
844 final float tmpFloats[] = mService.mTmpFloats;
845 final Matrix tmpMatrix = mWin.mTmpMatrix;
846
847 // Compute the desired transformation.
848 if (screenAnimation) {
849 // If we are doing a screen animation, the global rotation
850 // applied to windows can result in windows that are carefully
851 // aligned with each other to slightly separate, allowing you
852 // to see what is behind them. An unsightly mess. This...
853 // thing... magically makes it call good: scale each window
854 // slightly (two pixels larger in each dimension, from the
855 // window's center).
856 final float w = frame.width();
857 final float h = frame.height();
858 if (w>=1 && h>=1) {
859 tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
860 } else {
861 tmpMatrix.reset();
862 }
863 } else {
864 tmpMatrix.reset();
865 }
866 tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
867 if (selfTransformation) {
868 tmpMatrix.postConcat(mTransformation.getMatrix());
869 }
870 tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
871 if (attachedTransformation != null) {
872 tmpMatrix.postConcat(attachedTransformation.getMatrix());
873 }
874 if (appTransformation != null) {
875 tmpMatrix.postConcat(appTransformation.getMatrix());
876 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700877 if (mAnimator.mUniverseBackground != null) {
878 tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix());
879 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700880 if (screenAnimation) {
881 tmpMatrix.postConcat(
882 mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getMatrix());
883 }
884
885 // "convert" it into SurfaceFlinger's format
886 // (a 2x2 matrix + an offset)
887 // Here we must not transform the position of the surface
888 // since it is already included in the transformation.
889 //Slog.i(TAG, "Transform: " + matrix);
890
891 mHaveMatrix = true;
892 tmpMatrix.getValues(tmpFloats);
893 mDsDx = tmpFloats[Matrix.MSCALE_X];
894 mDtDx = tmpFloats[Matrix.MSKEW_Y];
895 mDsDy = tmpFloats[Matrix.MSKEW_X];
896 mDtDy = tmpFloats[Matrix.MSCALE_Y];
897 float x = tmpFloats[Matrix.MTRANS_X];
898 float y = tmpFloats[Matrix.MTRANS_Y];
899 int w = frame.width();
900 int h = frame.height();
901 mWin.mShownFrame.set(x, y, x+w, y+h);
902
903 // Now set the alpha... but because our current hardware
904 // can't do alpha transformation on a non-opaque surface,
905 // turn it off if we are running an animation that is also
906 // transforming since it is more important to have that
907 // animation be smooth.
908 mShownAlpha = mAlpha;
909 if (!mService.mLimitedAlphaCompositing
910 || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
911 || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
912 && x == frame.left && y == frame.top))) {
913 //Slog.i(TAG, "Applying alpha transform");
914 if (selfTransformation) {
915 mShownAlpha *= mTransformation.getAlpha();
916 }
917 if (attachedTransformation != null) {
918 mShownAlpha *= attachedTransformation.getAlpha();
919 }
920 if (appTransformation != null) {
921 mShownAlpha *= appTransformation.getAlpha();
922 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700923 if (mAnimator.mUniverseBackground != null) {
924 mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
925 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700926 if (screenAnimation) {
927 mShownAlpha *=
928 mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha();
929 }
930 } else {
931 //Slog.i(TAG, "Not applying alpha transform");
932 }
933
Craig Mautner9e809442012-06-22 17:13:04 -0700934 if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV) && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700935 TAG, "computeShownFrameLocked: Animating " + this +
Craig Mautnerf4120952012-06-21 18:25:39 -0700936 " mAlpha=" + mAlpha +
937 " self=" + (selfTransformation ? mTransformation.getAlpha() : "null") +
938 " attached=" + (attachedTransformation == null ? "null" : attachedTransformation.getAlpha()) +
939 " app=" + (appTransformation == null ? "null" : appTransformation.getAlpha()) +
940 " screen=" + (screenAnimation ? mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha()
941 : "null"));
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700942 return;
Craig Mautner4d7349b2012-04-20 14:52:47 -0700943 } else if (mWin.mIsWallpaper &&
944 (mAnimator.mPendingActions & WindowAnimator.WALLPAPER_ACTION_PENDING) != 0) {
945 return;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700946 }
947
948 if (WindowManagerService.localLOGV) Slog.v(
Craig Mautner4d7349b2012-04-20 14:52:47 -0700949 TAG, "computeShownFrameLocked: " + this +
950 " not attached, mAlpha=" + mAlpha);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700951 if (mAnimator.mUniverseBackground != null &&
952 mWin.mAttrs.type != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND
953 && mWin.mBaseLayer < mAnimator.mAboveUniverseLayer) {
954 final Rect frame = mWin.mFrame;
955 final float tmpFloats[] = mService.mTmpFloats;
956 final Matrix tmpMatrix = mWin.mTmpMatrix;
957 tmpMatrix.setScale(mWin.mGlobalScale, mWin.mGlobalScale);
958 tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
959 tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix());
960 tmpMatrix.getValues(tmpFloats);
961 mHaveMatrix = true;
962 mDsDx = tmpFloats[Matrix.MSCALE_X];
963 mDtDx = tmpFloats[Matrix.MSKEW_Y];
964 mDsDy = tmpFloats[Matrix.MSKEW_X];
965 mDtDy = tmpFloats[Matrix.MSCALE_Y];
966 float x = tmpFloats[Matrix.MTRANS_X];
967 float y = tmpFloats[Matrix.MTRANS_Y];
968 int w = frame.width();
969 int h = frame.height();
970 mWin.mShownFrame.set(x, y, x+w, y+h);
971 mShownAlpha = mAlpha * mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
972 } else {
973 mWin.mShownFrame.set(mWin.mFrame);
974 if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
975 mWin.mShownFrame.offset(mWin.mXOffset, mWin.mYOffset);
976 }
977 mShownAlpha = mAlpha;
978 mHaveMatrix = false;
979 mDsDx = mWin.mGlobalScale;
980 mDtDx = 0;
981 mDsDy = 0;
982 mDtDy = mWin.mGlobalScale;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700983 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700984 }
985
986 void applyDecorRect(final Rect decorRect) {
987 final WindowState w = mWin;
988 // Compute the offset of the window in relation to the decor rect.
989 final int offX = w.mXOffset + w.mFrame.left;
990 final int offY = w.mYOffset + w.mFrame.top;
991 // Initialize the decor rect to the entire frame.
992 w.mSystemDecorRect.set(0, 0, w.mFrame.width(), w.mFrame.height());
993 // Intersect with the decor rect, offsetted by window position.
994 w.mSystemDecorRect.intersect(decorRect.left-offX, decorRect.top-offY,
995 decorRect.right-offX, decorRect.bottom-offY);
996 // If size compatibility is being applied to the window, the
997 // surface is scaled relative to the screen. Also apply this
998 // scaling to the crop rect. We aren't using the standard rect
999 // scale function because we want to round things to make the crop
1000 // always round to a larger rect to ensure we don't crop too
1001 // much and hide part of the window that should be seen.
1002 if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
1003 final float scale = w.mInvGlobalScale;
1004 w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
1005 w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
1006 w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
1007 w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
1008 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001009 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001010
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001011 void updateSurfaceWindowCrop(final boolean recoveringMemory) {
1012 final WindowState w = mWin;
1013
1014 // Need to recompute a new system decor rect each time.
1015 if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
1016 // Currently can't do this cropping for scaled windows. We'll
1017 // just keep the crop rect the same as the source surface.
1018 w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight);
1019 } else if (w.mLayer >= mService.mSystemDecorLayer) {
1020 // Above the decor layer is easy, just use the entire window.
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07001021 // Unless we have a universe background... in which case all the
1022 // windows need to be cropped by the screen, so they don't cover
1023 // the universe background.
1024 if (mAnimator.mUniverseBackground == null) {
1025 w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(),
1026 w.mCompatFrame.height());
1027 } else {
1028 applyDecorRect(mService.mScreenRect);
1029 }
1030 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND) {
1031 // The universe background isn't cropped.
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001032 w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(),
1033 w.mCompatFrame.height());
1034 } else {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07001035 applyDecorRect(mService.mSystemDecorRect);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001036 }
1037
1038 if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) {
1039 w.mLastSystemDecorRect.set(w.mSystemDecorRect);
1040 try {
1041 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1042 "CROP " + w.mSystemDecorRect.toShortString(), null);
1043 mSurface.setWindowCrop(w.mSystemDecorRect);
1044 } catch (RuntimeException e) {
1045 Slog.w(TAG, "Error setting crop surface of " + w
1046 + " crop=" + w.mSystemDecorRect.toShortString(), e);
1047 if (!recoveringMemory) {
1048 mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
1049 }
1050 }
1051 }
1052 }
1053
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001054 void setSurfaceBoundaries(final boolean recoveringMemory) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001055 final WindowState w = mWin;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001056 int width, height;
1057 if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
1058 // for a scaled surface, we just want to use
1059 // the requested size.
1060 width = w.mRequestedWidth;
1061 height = w.mRequestedHeight;
1062 } else {
1063 width = w.mCompatFrame.width();
1064 height = w.mCompatFrame.height();
1065 }
1066
1067 if (width < 1) {
1068 width = 1;
1069 }
1070 if (height < 1) {
1071 height = 1;
1072 }
1073 final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height;
1074 if (surfaceResized) {
1075 mSurfaceW = width;
1076 mSurfaceH = height;
1077 }
1078
Craig Mautner4d7349b2012-04-20 14:52:47 -07001079 final float left = w.mShownFrame.left;
1080 final float top = w.mShownFrame.top;
1081 if (mSurfaceX != left || mSurfaceY != top) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001082 try {
1083 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
Craig Mautner4d7349b2012-04-20 14:52:47 -07001084 "POS " + left + ", " + top, null);
1085 mSurfaceX = left;
1086 mSurfaceY = top;
1087 mSurface.setPosition(left, top);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001088 } catch (RuntimeException e) {
1089 Slog.w(TAG, "Error positioning surface of " + w
Craig Mautner4d7349b2012-04-20 14:52:47 -07001090 + " pos=(" + left
1091 + "," + top + ")", e);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001092 if (!recoveringMemory) {
1093 mService.reclaimSomeSurfaceMemoryLocked(this, "position", true);
1094 }
1095 }
1096 }
1097
1098 if (surfaceResized) {
1099 try {
1100 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1101 "SIZE " + width + "x" + height, null);
1102 mSurfaceResized = true;
1103 mSurface.setSize(width, height);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001104 mAnimator.mPendingLayoutChanges |=
1105 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Craig Mautner3a67f352012-05-07 11:21:33 -07001106 if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
1107 mAnimator.startDimming(this, w.mExiting ? 0 : w.mAttrs.dimAmount,
1108 mService.mAppDisplayWidth, mService.mAppDisplayHeight);
1109 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001110 } catch (RuntimeException e) {
1111 // If something goes wrong with the surface (such
1112 // as running out of memory), don't take down the
1113 // entire system.
1114 Slog.e(TAG, "Error resizing surface of " + w
1115 + " size=(" + width + "x" + height + ")", e);
1116 if (!recoveringMemory) {
1117 mService.reclaimSomeSurfaceMemoryLocked(this, "size", true);
1118 }
1119 }
1120 }
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07001121
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001122 updateSurfaceWindowCrop(recoveringMemory);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001123 }
1124
1125 public void prepareSurfaceLocked(final boolean recoveringMemory) {
1126 final WindowState w = mWin;
1127 if (mSurface == null) {
1128 if (w.mOrientationChanging) {
1129 if (DEBUG_ORIENTATION) {
1130 Slog.v(TAG, "Orientation change skips hidden " + w);
1131 }
1132 w.mOrientationChanging = false;
1133 }
1134 return;
1135 }
1136
1137 boolean displayed = false;
1138
1139 computeShownFrameLocked();
1140
1141 setSurfaceBoundaries(recoveringMemory);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001142
Craig Mautner0fa77c12012-06-11 15:57:19 -07001143 if (mWin.mIsWallpaper && !mWin.mWallpaperVisible) {
1144 // Wallpaper is no longer visible and there is no wp target => hide it.
1145 hide();
1146 } else if (w.mAttachedHidden || !w.isReadyForDisplay()) {
Craig Mautner0afddcb2012-05-08 15:38:00 -07001147 hide();
Craig Mautnerb9836b92012-06-11 11:40:09 -07001148 mAnimator.hideWallpapersLocked(w);
1149
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001150 // If we are waiting for this window to handle an
1151 // orientation change, well, it is hidden, so
1152 // doesn't really matter. Note that this does
1153 // introduce a potential glitch if the window
1154 // becomes unhidden before it has drawn for the
1155 // new orientation.
1156 if (w.mOrientationChanging) {
1157 w.mOrientationChanging = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001158 if (DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001159 "Orientation change skips hidden " + w);
1160 }
1161 } else if (mLastLayer != mAnimLayer
1162 || mLastAlpha != mShownAlpha
1163 || mLastDsDx != mDsDx
1164 || mLastDtDx != mDtDx
1165 || mLastDsDy != mDsDy
1166 || mLastDtDy != mDtDy
1167 || w.mLastHScale != w.mHScale
1168 || w.mLastVScale != w.mVScale
Craig Mautner749a7bb2012-04-02 13:49:53 -07001169 || mLastHidden) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001170 displayed = true;
1171 mLastAlpha = mShownAlpha;
1172 mLastLayer = mAnimLayer;
1173 mLastDsDx = mDsDx;
1174 mLastDtDx = mDtDx;
1175 mLastDsDy = mDsDy;
1176 mLastDtDy = mDtDy;
1177 w.mLastHScale = w.mHScale;
1178 w.mLastVScale = w.mVScale;
1179 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1180 "alpha=" + mShownAlpha + " layer=" + mAnimLayer
1181 + " matrix=[" + (mDsDx*w.mHScale)
1182 + "," + (mDtDx*w.mVScale)
1183 + "][" + (mDsDy*w.mHScale)
1184 + "," + (mDtDy*w.mVScale) + "]", null);
1185 if (mSurface != null) {
1186 try {
1187 mSurfaceAlpha = mShownAlpha;
1188 mSurface.setAlpha(mShownAlpha);
Craig Mautnerad5725d2012-06-05 10:20:56 -07001189 mSurfaceLayer = mAnimLayer;
1190 mSurface.setLayer(mAnimLayer);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001191 mSurface.setMatrix(
1192 mDsDx*w.mHScale, mDtDx*w.mVScale,
1193 mDsDy*w.mHScale, mDtDy*w.mVScale);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001194
1195 if (mLastHidden && mDrawState == HAS_DRAWN) {
1196 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1197 "SHOW (performLayout)", null);
1198 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
1199 + " during relayout");
1200 if (showSurfaceRobustlyLocked()) {
1201 mLastHidden = false;
Craig Mautner507a2ee2012-06-13 08:39:38 -07001202 if (w.mIsWallpaper) {
1203 mService.dispatchWallpaperVisibility(w, true);
1204 }
Craig Mautner749a7bb2012-04-02 13:49:53 -07001205 } else {
1206 w.mOrientationChanging = false;
1207 }
1208 }
1209 if (mSurface != null) {
1210 w.mToken.hasVisible = true;
1211 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001212 } catch (RuntimeException e) {
1213 Slog.w(TAG, "Error updating surface in " + w, e);
1214 if (!recoveringMemory) {
1215 mService.reclaimSomeSurfaceMemoryLocked(this, "update", true);
1216 }
1217 }
1218 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001219 } else {
Craig Mautner9e809442012-06-22 17:13:04 -07001220 if (DEBUG_ANIM && isAnimating()) {
1221 Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
Craig Mautner83339b42012-05-01 22:13:23 -07001222 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001223 displayed = true;
1224 }
1225
1226 if (displayed) {
1227 if (w.mOrientationChanging) {
1228 if (!w.isDrawnLw()) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07001229 mAnimator.mBulkUpdateParams |= CLEAR_ORIENTATION_CHANGE_COMPLETE;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001230 if (DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001231 "Orientation continue waiting for draw in " + w);
1232 } else {
1233 w.mOrientationChanging = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001234 if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001235 }
1236 }
1237 w.mToken.hasVisible = true;
1238 }
1239 }
1240
Craig Mautner48ba1e72012-04-02 13:18:16 -07001241 void setTransparentRegionHint(final Region region) {
Craig Mautner1f4e0cc2012-04-10 14:24:38 -07001242 if (mSurface == null) {
1243 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
1244 return;
1245 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07001246 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1247 ">>> OPEN TRANSACTION setTransparentRegion");
1248 Surface.openTransaction();
1249 try {
1250 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
1251 "transparentRegionHint=" + region, null);
1252 mSurface.setTransparentRegionHint(region);
1253 } finally {
1254 Surface.closeTransaction();
1255 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1256 "<<< CLOSE TRANSACTION setTransparentRegion");
1257 }
1258 }
1259
1260 void setWallpaperOffset(int left, int top) {
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001261 mSurfaceX = left;
1262 mSurfaceY = top;
1263 if (mAnimating) {
1264 // If this window (or its app token) is animating, then the position
1265 // of the surface will be re-computed on the next animation frame.
1266 // We can't poke it directly here because it depends on whatever
1267 // transformation is being applied by the animation.
1268 return;
1269 }
1270 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1271 ">>> OPEN TRANSACTION setWallpaperOffset");
Craig Mautner48ba1e72012-04-02 13:18:16 -07001272 Surface.openTransaction();
1273 try {
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001274 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
1275 "POS " + left + ", " + top, null);
1276 mSurface.setPosition(mWin.mFrame.left + left, mWin.mFrame.top + top);
1277 updateSurfaceWindowCrop(false);
Craig Mautner48ba1e72012-04-02 13:18:16 -07001278 } catch (RuntimeException e) {
1279 Slog.w(TAG, "Error positioning surface of " + mWin
1280 + " pos=(" + left + "," + top + ")", e);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001281 } finally {
1282 Surface.closeTransaction();
1283 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1284 "<<< CLOSE TRANSACTION setWallpaperOffset");
Craig Mautner48ba1e72012-04-02 13:18:16 -07001285 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07001286 }
1287
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001288 // This must be called while inside a transaction.
1289 boolean performShowLocked() {
Craig Mautner6fbda632012-07-03 09:26:39 -07001290 if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
1291 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001292 RuntimeException e = null;
1293 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
1294 e = new RuntimeException();
1295 e.fillInStackTrace();
1296 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001297 Slog.v(TAG, "performShow on " + this
Craig Mautner749a7bb2012-04-02 13:49:53 -07001298 + ": mDrawState=" + mDrawState + " readyForDisplay="
Dianne Hackborn6e2281d2012-06-19 17:48:32 -07001299 + mWin.isReadyForDisplayIgnoringKeyguard()
Craig Mautner6fbda632012-07-03 09:26:39 -07001300 + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING)
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001301 + " during animation: policyVis=" + mWin.mPolicyVisibility
1302 + " attHidden=" + mWin.mAttachedHidden
1303 + " tok.hiddenRequested="
1304 + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
1305 + " tok.hidden="
1306 + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
1307 + " animating=" + mAnimating
1308 + " tok animating="
Craig Mautner6fbda632012-07-03 09:26:39 -07001309 + (mWin.mAppToken != null ? mWin.mAppToken.mAppAnimator.animating : false), e);
1310 }
1311 if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplayIgnoringKeyguard()) {
1312 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
1313 WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null);
1314 if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
1315 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
1316 Slog.v(TAG, "Showing " + this
1317 + " during animation: policyVis=" + mWin.mPolicyVisibility
1318 + " attHidden=" + mWin.mAttachedHidden
1319 + " tok.hiddenRequested="
1320 + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
1321 + " tok.hidden="
1322 + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
1323 + " animating=" + mAnimating
1324 + " tok animating="
1325 + (mWin.mAppToken != null ? mWin.mAppToken.mAppAnimator.animating : false));
1326 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001327
1328 mService.enableScreenIfNeededLocked();
1329
1330 applyEnterAnimationLocked();
1331
Craig Mautnerde6198e2012-04-19 09:59:31 -07001332 // Force the show in the next prepareSurfaceLocked() call.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001333 mLastAlpha = -1;
Craig Mautneref25d7a2012-05-15 23:01:47 -07001334 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM)
1335 Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN in " + this);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001336 mDrawState = HAS_DRAWN;
Craig Mautner711f90a2012-07-03 18:43:52 -07001337 mService.updateLayoutToAnimationLocked();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001338
1339 int i = mWin.mChildWindows.size();
1340 while (i > 0) {
1341 i--;
1342 WindowState c = mWin.mChildWindows.get(i);
1343 if (c.mAttachedHidden) {
1344 c.mAttachedHidden = false;
1345 if (c.mWinAnimator.mSurface != null) {
1346 c.mWinAnimator.performShowLocked();
1347 // It hadn't been shown, which means layout not
1348 // performed on it, so now we want to make sure to
1349 // do a layout. If called from within the transaction
1350 // loop, this will cause it to restart with a new
1351 // layout.
1352 mService.mLayoutNeeded = true;
1353 }
1354 }
1355 }
1356
1357 if (mWin.mAttrs.type != TYPE_APPLICATION_STARTING
1358 && mWin.mAppToken != null) {
1359 mWin.mAppToken.firstWindowDrawn = true;
1360
1361 if (mWin.mAppToken.startingData != null) {
1362 if (WindowManagerService.DEBUG_STARTING_WINDOW ||
Craig Mautnerd87946b2012-03-29 18:00:19 -07001363 WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001364 "Finish starting " + mWin.mToken
1365 + ": first real window is shown, no animation");
1366 // If this initial window is animating, stop it -- we
1367 // will do an animation to reveal it from behind the
1368 // starting window, so there is no need for it to also
1369 // be doing its own stuff.
Craig Mautner4d7349b2012-04-20 14:52:47 -07001370 clearAnimation();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001371 mService.mFinishedStarting.add(mWin.mAppToken);
1372 mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
1373 }
1374 mWin.mAppToken.updateReportedVisibilityLocked();
1375 }
1376
1377 return true;
1378 }
1379
1380 return false;
1381 }
1382
1383 /**
1384 * Have the surface flinger show a surface, robustly dealing with
1385 * error conditions. In particular, if there is not enough memory
1386 * to show the surface, then we will try to get rid of other surfaces
1387 * in order to succeed.
1388 *
1389 * @return Returns true if the surface was successfully shown.
1390 */
1391 boolean showSurfaceRobustlyLocked() {
1392 try {
1393 if (mSurface != null) {
1394 mSurfaceShown = true;
1395 mSurface.show();
1396 if (mWin.mTurnOnScreen) {
1397 if (DEBUG_VISIBILITY) Slog.v(TAG,
1398 "Show surface turning screen on: " + mWin);
1399 mWin.mTurnOnScreen = false;
Craig Mautner7d8df392012-04-06 15:26:23 -07001400 mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001401 }
1402 }
1403 return true;
1404 } catch (RuntimeException e) {
1405 Slog.w(TAG, "Failure showing surface " + mSurface + " in " + mWin, e);
1406 }
1407
1408 mService.reclaimSomeSurfaceMemoryLocked(this, "show", true);
1409
1410 return false;
1411 }
1412
1413 void applyEnterAnimationLocked() {
1414 final int transit;
1415 if (mEnterAnimationPending) {
1416 mEnterAnimationPending = false;
1417 transit = WindowManagerPolicy.TRANSIT_ENTER;
1418 } else {
1419 transit = WindowManagerPolicy.TRANSIT_SHOW;
1420 }
1421
1422 applyAnimationLocked(transit, true);
1423 }
1424
Craig Mautner48ba1e72012-04-02 13:18:16 -07001425 // TODO(cmautner): Move back to WindowState?
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001426 /**
1427 * Choose the correct animation and set it to the passed WindowState.
1428 * @param transit If WindowManagerPolicy.TRANSIT_PREVIEW_DONE and the app window has been drawn
1429 * then the animation will be app_starting_exit. Any other value loads the animation from
1430 * the switch statement below.
1431 * @param isEntrance The animation type the last time this was called. Used to keep from
1432 * loading the same animation twice.
1433 * @return true if an animation has been loaded.
1434 */
1435 boolean applyAnimationLocked(int transit, boolean isEntrance) {
1436 if (mLocalAnimating && mAnimationIsEntrance == isEntrance) {
1437 // If we are trying to apply an animation, but already running
1438 // an animation of the same type, then just leave that one alone.
1439 return true;
1440 }
1441
1442 // Only apply an animation if the display isn't frozen. If it is
1443 // frozen, there is no reason to animate and it can cause strange
1444 // artifacts when we unfreeze the display if some different animation
1445 // is running.
1446 if (mService.okToDisplay()) {
1447 int anim = mPolicy.selectAnimationLw(mWin, transit);
1448 int attr = -1;
1449 Animation a = null;
1450 if (anim != 0) {
1451 a = AnimationUtils.loadAnimation(mContext, anim);
1452 } else {
1453 switch (transit) {
1454 case WindowManagerPolicy.TRANSIT_ENTER:
1455 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
1456 break;
1457 case WindowManagerPolicy.TRANSIT_EXIT:
1458 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
1459 break;
1460 case WindowManagerPolicy.TRANSIT_SHOW:
1461 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
1462 break;
1463 case WindowManagerPolicy.TRANSIT_HIDE:
1464 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
1465 break;
1466 }
1467 if (attr >= 0) {
1468 a = mService.loadAnimation(mWin.mAttrs, attr);
1469 }
1470 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001471 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001472 "applyAnimation: win=" + this
1473 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
Craig Mautner4d7349b2012-04-20 14:52:47 -07001474 + " a=" + a
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001475 + " mAnimation=" + mAnimation
Craig Mautner83339b42012-05-01 22:13:23 -07001476 + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3));
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001477 if (a != null) {
1478 if (WindowManagerService.DEBUG_ANIM) {
1479 RuntimeException e = null;
1480 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
1481 e = new RuntimeException();
1482 e.fillInStackTrace();
1483 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001484 Slog.v(TAG, "Loaded animation " + a + " for " + this, e);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001485 }
1486 setAnimation(a);
1487 mAnimationIsEntrance = isEntrance;
1488 }
1489 } else {
1490 clearAnimation();
1491 }
1492
1493 return mAnimation != null;
1494 }
1495
Craig Mautnera2c77052012-03-26 12:14:43 -07001496 public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
1497 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
1498 || mAnimation != null) {
1499 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
1500 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
1501 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
1502 pw.print(" mAnimation="); pw.println(mAnimation);
1503 }
1504 if (mHasTransformation || mHasLocalTransformation) {
1505 pw.print(prefix); pw.print("XForm: has=");
1506 pw.print(mHasTransformation);
1507 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
1508 pw.print(" "); mTransformation.printShortString(pw);
1509 pw.println();
1510 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001511 if (mSurface != null) {
1512 if (dumpAll) {
1513 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Craig Mautner6fbda632012-07-03 09:26:39 -07001514 pw.print(prefix); pw.print("mDrawState=");
1515 pw.print(drawStateToString(mDrawState));
Craig Mautner749a7bb2012-04-02 13:49:53 -07001516 pw.print(" mLastHidden="); pw.println(mLastHidden);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001517 }
1518 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
1519 pw.print(" layer="); pw.print(mSurfaceLayer);
1520 pw.print(" alpha="); pw.print(mSurfaceAlpha);
1521 pw.print(" rect=("); pw.print(mSurfaceX);
1522 pw.print(","); pw.print(mSurfaceY);
1523 pw.print(") "); pw.print(mSurfaceW);
1524 pw.print(" x "); pw.println(mSurfaceH);
1525 }
1526 if (mPendingDestroySurface != null) {
1527 pw.print(prefix); pw.print("mPendingDestroySurface=");
1528 pw.println(mPendingDestroySurface);
1529 }
1530 if (mSurfaceResized || mSurfaceDestroyDeferred) {
1531 pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
1532 pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
1533 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07001534 if (mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND) {
1535 pw.print(prefix); pw.print("mUniverseTransform=");
1536 mUniverseTransform.printShortString(pw);
1537 pw.println();
1538 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001539 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
1540 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
1541 pw.print(" mAlpha="); pw.print(mAlpha);
1542 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
1543 }
1544 if (mHaveMatrix || mWin.mGlobalScale != 1) {
1545 pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale);
1546 pw.print(" mDsDx="); pw.print(mDsDx);
1547 pw.print(" mDtDx="); pw.print(mDtDx);
1548 pw.print(" mDsDy="); pw.print(mDsDy);
1549 pw.print(" mDtDy="); pw.println(mDtDy);
1550 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001551 }
1552
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001553 @Override
1554 public String toString() {
1555 StringBuffer sb = new StringBuffer("WindowStateAnimator (");
1556 sb.append(mWin.mLastTitle + "): ");
1557 sb.append("mSurface " + mSurface);
1558 sb.append(", mAnimation " + mAnimation);
1559 return sb.toString();
1560 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001561}