blob: 2c9f7f3a4275c1be688d7af4fea668d25134b9a4 [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;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07006
Craig Mautner2639da52012-07-09 09:39:06 -07007import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
Craig Mautner7d8df392012-04-06 15:26:23 -07008import static com.android.server.wm.WindowManagerService.LayoutFields.SET_TURN_ON_SCREEN;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009
Craig Mautnerc2f9be02012-03-27 17:32:29 -070010import android.content.Context;
11import android.graphics.Matrix;
12import android.graphics.PixelFormat;
Craig Mautner7358fbf2012-04-12 21:06:33 -070013import android.graphics.Point;
14import android.graphics.PointF;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070015import android.graphics.Rect;
Craig Mautner48ba1e72012-04-02 13:18:16 -070016import android.graphics.Region;
Craig Mautnera51a9562012-04-17 17:05:26 -070017import android.os.Debug;
Craig Mautnera2c77052012-03-26 12:14:43 -070018import android.util.Slog;
Craig Mautner59c00972012-07-30 12:10:24 -070019import android.view.DisplayInfo;
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
Craig Mautner59c00972012-07-30 12:10:24 -070034class WinAnimatorList extends ArrayList<WindowStateAnimator> {
35}
36
Craig Mautnera2c77052012-03-26 12:14:43 -070037/**
Craig Mautnerc2f9be02012-03-27 17:32:29 -070038 * Keep track of animations and surface operations for a single WindowState.
39 **/
Craig Mautnera2c77052012-03-26 12:14:43 -070040class WindowStateAnimator {
Craig Mautnerc2f9be02012-03-27 17:32:29 -070041 static final boolean DEBUG_VISIBILITY = WindowManagerService.DEBUG_VISIBILITY;
42 static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_ANIM;
43 static final boolean DEBUG_LAYERS = WindowManagerService.DEBUG_LAYERS;
44 static final boolean DEBUG_STARTING_WINDOW = WindowManagerService.DEBUG_STARTING_WINDOW;
45 static final boolean SHOW_TRANSACTIONS = WindowManagerService.SHOW_TRANSACTIONS;
46 static final boolean SHOW_LIGHT_TRANSACTIONS = WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
47 static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC;
48 static final boolean localLOGV = WindowManagerService.localLOGV;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -070049 static final boolean DEBUG_ORIENTATION = WindowManagerService.DEBUG_ORIENTATION;
Craig Mautner7358fbf2012-04-12 21:06:33 -070050 static final boolean DEBUG_SURFACE_TRACE = WindowManagerService.DEBUG_SURFACE_TRACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070051
52 static final String TAG = "WindowStateAnimator";
Craig Mautnera2c77052012-03-26 12:14:43 -070053
Craig Mautner918b53b2012-07-09 14:15:54 -070054 // Unchanging local convenience fields.
Craig Mautnera2c77052012-03-26 12:14:43 -070055 final WindowManagerService mService;
56 final WindowState mWin;
Craig Mautner322e4032012-07-13 13:35:20 -070057 final WindowStateAnimator mAttachedWinAnimator;
Craig Mautnere7ae2502012-03-26 17:11:19 -070058 final WindowAnimator mAnimator;
Craig Mautner322e4032012-07-13 13:35:20 -070059 final AppWindowAnimator mAppAnimator;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070060 final Session mSession;
61 final WindowManagerPolicy mPolicy;
62 final Context mContext;
Craig Mautner918b53b2012-07-09 14:15:54 -070063 final boolean mIsWallpaper;
Craig Mautnera2c77052012-03-26 12:14:43 -070064
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070065 // If this is a universe background window, this is the transformation
66 // it is applying to the rest of the universe.
67 final Transformation mUniverseTransform = new Transformation();
68
Craig Mautnera2c77052012-03-26 12:14:43 -070069 // Currently running animation.
70 boolean mAnimating;
71 boolean mLocalAnimating;
72 Animation mAnimation;
73 boolean mAnimationIsEntrance;
74 boolean mHasTransformation;
75 boolean mHasLocalTransformation;
76 final Transformation mTransformation = new Transformation();
77 boolean mWasAnimating; // Were we animating going into the most recent animation step?
Craig Mautnerc2f9be02012-03-27 17:32:29 -070078 int mAnimLayer;
79 int mLastLayer;
80
81 Surface mSurface;
82 Surface mPendingDestroySurface;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070083
84 /**
85 * Set when we have changed the size of the surface, to know that
86 * we must tell them application to resize (and thus redraw itself).
87 */
88 boolean mSurfaceResized;
89
90 /**
91 * Set if the client has asked that the destroy of its surface be delayed
92 * until it explicitly says it is okay.
93 */
94 boolean mSurfaceDestroyDeferred;
95
Craig Mautner7d8df392012-04-06 15:26:23 -070096 float mShownAlpha = 0;
97 float mAlpha = 0;
98 float mLastAlpha = 0;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070099
100 // Used to save animation distances between the time they are calculated and when they are
101 // used.
102 int mAnimDw;
103 int mAnimDh;
104 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
105 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
106
107 boolean mHaveMatrix;
108
109 // For debugging, this is the last information given to the surface flinger.
110 boolean mSurfaceShown;
111 float mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
112 int mSurfaceLayer;
113 float mSurfaceAlpha;
114
115 // Set to true if, when the window gets displayed, it should perform
116 // an enter animation.
117 boolean mEnterAnimationPending;
Craig Mautnera2c77052012-03-26 12:14:43 -0700118
Craig Mautner749a7bb2012-04-02 13:49:53 -0700119 /** This is set when there is no Surface */
120 static final int NO_SURFACE = 0;
121 /** This is set after the Surface has been created but before the window has been drawn. During
122 * this time the surface is hidden. */
123 static final int DRAW_PENDING = 1;
124 /** This is set after the window has finished drawing for the first time but before its surface
125 * is shown. The surface will be displayed when the next layout is run. */
126 static final int COMMIT_DRAW_PENDING = 2;
127 /** This is set during the time after the window's drawing has been committed, and before its
128 * surface is actually shown. It is used to delay showing the surface until all windows in a
129 * token are ready to be shown. */
130 static final int READY_TO_SHOW = 3;
131 /** Set when the window has been shown in the screen the first time. */
132 static final int HAS_DRAWN = 4;
Craig Mautner6fbda632012-07-03 09:26:39 -0700133 static String drawStateToString(int state) {
134 switch (state) {
135 case NO_SURFACE: return "NO_SURFACE";
136 case DRAW_PENDING: return "DRAW_PENDING";
137 case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING";
138 case READY_TO_SHOW: return "READY_TO_SHOW";
139 case HAS_DRAWN: return "HAS_DRAWN";
140 default: return Integer.toString(state);
141 }
142 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700143 int mDrawState;
Craig Mautnera608b882012-03-30 13:03:49 -0700144
Craig Mautner749a7bb2012-04-02 13:49:53 -0700145 /** Was this window last hidden? */
146 boolean mLastHidden;
Craig Mautnera608b882012-03-30 13:03:49 -0700147
Craig Mautnerbec53f72012-04-05 11:49:05 -0700148 int mAttrFlags;
149 int mAttrType;
150
Craig Mautner918b53b2012-07-09 14:15:54 -0700151 public WindowStateAnimator(final WindowState win) {
152 final WindowManagerService service = win.mService;
153
Craig Mautnera2c77052012-03-26 12:14:43 -0700154 mService = service;
Craig Mautner918b53b2012-07-09 14:15:54 -0700155 mAnimator = service.mAnimator;
156 mPolicy = service.mPolicy;
157 mContext = service.mContext;
Craig Mautner59c00972012-07-30 12:10:24 -0700158 final DisplayInfo displayInfo = win.mDisplayContent.getDisplayInfo();
159 mAnimDw = displayInfo.appWidth;
160 mAnimDh = displayInfo.appHeight;
Craig Mautner918b53b2012-07-09 14:15:54 -0700161
162 mWin = win;
Craig Mautner322e4032012-07-13 13:35:20 -0700163 mAttachedWinAnimator = win.mAttachedWindow == null
164 ? null : win.mAttachedWindow.mWinAnimator;
165 mAppAnimator = win.mAppToken == null ? null : win.mAppToken.mAppAnimator;
Craig Mautner918b53b2012-07-09 14:15:54 -0700166 mSession = win.mSession;
167 mAttrFlags = win.mAttrs.flags;
168 mAttrType = win.mAttrs.type;
169 mIsWallpaper = win.mIsWallpaper;
Craig Mautnera2c77052012-03-26 12:14:43 -0700170 }
171
172 public void setAnimation(Animation anim) {
Craig Mautnerbec53f72012-04-05 11:49:05 -0700173 if (localLOGV) Slog.v(TAG, "Setting animation in " + this + ": " + anim);
Craig Mautnera2c77052012-03-26 12:14:43 -0700174 mAnimating = false;
175 mLocalAnimating = false;
176 mAnimation = anim;
177 mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
178 mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale);
179 // Start out animation gone if window is gone, or visible if window is visible.
180 mTransformation.clear();
Craig Mautner749a7bb2012-04-02 13:49:53 -0700181 mTransformation.setAlpha(mLastHidden ? 0 : 1);
Craig Mautnera2c77052012-03-26 12:14:43 -0700182 mHasLocalTransformation = true;
183 }
184
185 public void clearAnimation() {
186 if (mAnimation != null) {
187 mAnimating = true;
188 mLocalAnimating = false;
189 mAnimation.cancel();
190 mAnimation = null;
191 }
192 }
193
194 /** Is the window or its container currently animating? */
195 boolean isAnimating() {
Craig Mautnera2c77052012-03-26 12:14:43 -0700196 return mAnimation != null
Craig Mautner322e4032012-07-13 13:35:20 -0700197 || (mAttachedWinAnimator != null && mAttachedWinAnimator.mAnimation != null)
198 || (mAppAnimator != null &&
199 (mAppAnimator.animation != null
200 || mAppAnimator.mAppToken.inPendingTransaction));
Craig Mautnera2c77052012-03-26 12:14:43 -0700201 }
202
Craig Mautner0afddcb2012-05-08 15:38:00 -0700203 /** Is the window animating the DummyAnimation? */
204 boolean isDummyAnimation() {
Craig Mautner322e4032012-07-13 13:35:20 -0700205 return mAppAnimator != null
206 && mAppAnimator.animation == AppWindowAnimator.sDummyAnimation;
Craig Mautner0afddcb2012-05-08 15:38:00 -0700207 }
208
Craig Mautnera2c77052012-03-26 12:14:43 -0700209 /** Is this window currently animating? */
210 boolean isWindowAnimating() {
211 return mAnimation != null;
212 }
213
Craig Mautnera2c77052012-03-26 12:14:43 -0700214 void cancelExitAnimationForNextAnimationLocked() {
Craig Mautnera2c77052012-03-26 12:14:43 -0700215 if (mAnimation != null) {
216 mAnimation.cancel();
217 mAnimation = null;
Craig Mautner4d7349b2012-04-20 14:52:47 -0700218 mLocalAnimating = false;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700219 destroySurfaceLocked();
Craig Mautnera2c77052012-03-26 12:14:43 -0700220 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700221 }
222
223 private boolean stepAnimation(long currentTime) {
224 if ((mAnimation == null) || !mLocalAnimating) {
225 return false;
226 }
227 mTransformation.clear();
228 final boolean more = mAnimation.getTransformation(currentTime, mTransformation);
Craig Mautner9e809442012-06-22 17:13:04 -0700229 if (false && DEBUG_ANIM) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700230 TAG, "Stepped animation in " + this +
Craig Mautnera2c77052012-03-26 12:14:43 -0700231 ": more=" + more + ", xform=" + mTransformation);
232 return more;
233 }
234
235 // This must be called while inside a transaction. Returns true if
236 // there is more animation to run.
237 boolean stepAnimationLocked(long currentTime) {
238 // Save the animation state as it was before this step so WindowManagerService can tell if
239 // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
240 mWasAnimating = mAnimating;
241 if (mService.okToDisplay()) {
242 // We will run animations as long as the display isn't frozen.
243
244 if (mWin.isDrawnLw() && mAnimation != null) {
245 mHasTransformation = true;
246 mHasLocalTransformation = true;
247 if (!mLocalAnimating) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700248 if (DEBUG_ANIM) Slog.v(
249 TAG, "Starting animation in " + this +
Craig Mautnera2c77052012-03-26 12:14:43 -0700250 " @ " + currentTime + ": ww=" + mWin.mFrame.width() +
251 " wh=" + mWin.mFrame.height() +
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700252 " dw=" + mAnimDw + " dh=" + mAnimDh +
Craig Mautnera2c77052012-03-26 12:14:43 -0700253 " scale=" + mService.mWindowAnimationScale);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700254 mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
255 mAnimDw, mAnimDh);
Craig Mautner59c00972012-07-30 12:10:24 -0700256 final DisplayInfo displayInfo = mWin.mDisplayContent.getDisplayInfo();
257 mAnimDw = displayInfo.appWidth;
258 mAnimDh = displayInfo.appHeight;
Craig Mautnera2c77052012-03-26 12:14:43 -0700259 mAnimation.setStartTime(currentTime);
260 mLocalAnimating = true;
261 mAnimating = true;
262 }
263 if ((mAnimation != null) && mLocalAnimating) {
264 if (stepAnimation(currentTime)) {
265 return true;
266 }
267 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700268 if (DEBUG_ANIM) Slog.v(
269 TAG, "Finished animation in " + this +
Craig Mautnera2c77052012-03-26 12:14:43 -0700270 " @ " + currentTime);
271 //WindowManagerService.this.dump();
272 }
273 mHasLocalTransformation = false;
Craig Mautner322e4032012-07-13 13:35:20 -0700274 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppAnimator != null
275 && mAppAnimator.animation != null) {
Craig Mautnera2c77052012-03-26 12:14:43 -0700276 // When our app token is animating, we kind-of pretend like
277 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
278 // part of this check means that we will only do this if
279 // our window is not currently exiting, or it is not
280 // locally animating itself. The idea being that one that
281 // is exiting and doing a local animation should be removed
282 // once that animation is done.
283 mAnimating = true;
284 mHasTransformation = true;
285 mTransformation.clear();
286 return false;
287 } else if (mHasTransformation) {
288 // Little trick to get through the path below to act like
289 // we have finished an animation.
290 mAnimating = true;
291 } else if (isAnimating()) {
292 mAnimating = true;
293 }
294 } else if (mAnimation != null) {
295 // If the display is frozen, and there is a pending animation,
296 // clear it and make sure we run the cleanup code.
297 mAnimating = true;
Craig Mautnera2c77052012-03-26 12:14:43 -0700298 }
299
300 if (!mAnimating && !mLocalAnimating) {
301 return false;
302 }
303
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700304 // Done animating, clean up.
305 if (DEBUG_ANIM) Slog.v(
306 TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting
Craig Mautnera2c77052012-03-26 12:14:43 -0700307 + ", reportedVisible="
308 + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
309
310 mAnimating = false;
311 mLocalAnimating = false;
312 if (mAnimation != null) {
313 mAnimation.cancel();
314 mAnimation = null;
315 }
Craig Mautnere7ae2502012-03-26 17:11:19 -0700316 if (mAnimator.mWindowDetachedWallpaper == mWin) {
317 mAnimator.mWindowDetachedWallpaper = null;
Craig Mautnera2c77052012-03-26 12:14:43 -0700318 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700319 mAnimLayer = mWin.mLayer;
Craig Mautnera2c77052012-03-26 12:14:43 -0700320 if (mWin.mIsImWindow) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700321 mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
Craig Mautner918b53b2012-07-09 14:15:54 -0700322 } else if (mIsWallpaper) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700323 mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
Craig Mautnera2c77052012-03-26 12:14:43 -0700324 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700325 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
326 + " anim layer: " + mAnimLayer);
Craig Mautnera2c77052012-03-26 12:14:43 -0700327 mHasTransformation = false;
328 mHasLocalTransformation = false;
329 if (mWin.mPolicyVisibility != mWin.mPolicyVisibilityAfterAnim) {
330 if (WindowState.DEBUG_VISIBILITY) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700331 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
Craig Mautnera2c77052012-03-26 12:14:43 -0700332 + mWin.mPolicyVisibilityAfterAnim);
333 }
334 mWin.mPolicyVisibility = mWin.mPolicyVisibilityAfterAnim;
335 mService.mLayoutNeeded = true;
336 if (!mWin.mPolicyVisibility) {
337 if (mService.mCurrentFocus == mWin) {
338 mService.mFocusMayChange = true;
339 }
340 // Window is no longer visible -- make sure if we were waiting
341 // for it to be displayed before enabling the display, that
342 // we allow the display to be enabled now.
343 mService.enableScreenIfNeededLocked();
344 }
345 }
346 mTransformation.clear();
Craig Mautner749a7bb2012-04-02 13:49:53 -0700347 if (mDrawState == HAS_DRAWN
Craig Mautnera2c77052012-03-26 12:14:43 -0700348 && mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
349 && mWin.mAppToken != null
350 && mWin.mAppToken.firstWindowDrawn
351 && mWin.mAppToken.startingData != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700352 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
Craig Mautnera2c77052012-03-26 12:14:43 -0700353 + mWin.mToken + ": first real window done animating");
354 mService.mFinishedStarting.add(mWin.mAppToken);
355 mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
356 }
357
358 finishExit();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700359 mAnimator.mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
360 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats(
361 "WindowStateAnimator", mAnimator.mPendingLayoutChanges);
Craig Mautnera2c77052012-03-26 12:14:43 -0700362
363 if (mWin.mAppToken != null) {
364 mWin.mAppToken.updateReportedVisibilityLocked();
365 }
366
367 return false;
368 }
369
370 void finishExit() {
371 if (WindowManagerService.DEBUG_ANIM) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700372 TAG, "finishExit in " + this
Craig Mautnera2c77052012-03-26 12:14:43 -0700373 + ": exiting=" + mWin.mExiting
374 + " remove=" + mWin.mRemoveOnExit
375 + " windowAnimating=" + isWindowAnimating());
376
377 final int N = mWin.mChildWindows.size();
378 for (int i=0; i<N; i++) {
379 mWin.mChildWindows.get(i).mWinAnimator.finishExit();
380 }
381
382 if (!mWin.mExiting) {
383 return;
384 }
385
386 if (isWindowAnimating()) {
387 return;
388 }
389
390 if (WindowManagerService.localLOGV) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700391 TAG, "Exit animation finished in " + this
Craig Mautnera2c77052012-03-26 12:14:43 -0700392 + ": remove=" + mWin.mRemoveOnExit);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700393 if (mSurface != null) {
Craig Mautnera2c77052012-03-26 12:14:43 -0700394 mService.mDestroySurface.add(mWin);
395 mWin.mDestroying = true;
396 if (WindowState.SHOW_TRANSACTIONS) WindowManagerService.logSurface(
397 mWin, "HIDE (finishExit)", null);
Craig Mautner0afddcb2012-05-08 15:38:00 -0700398 hide();
Craig Mautnera2c77052012-03-26 12:14:43 -0700399 }
400 mWin.mExiting = false;
401 if (mWin.mRemoveOnExit) {
402 mService.mPendingRemove.add(mWin);
403 mWin.mRemoveOnExit = false;
404 }
Craig Mautnerb9836b92012-06-11 11:40:09 -0700405 mAnimator.hideWallpapersLocked(mWin);
Craig Mautner0afddcb2012-05-08 15:38:00 -0700406 }
407
408 void hide() {
409 if (!mLastHidden) {
410 //dump();
411 mLastHidden = true;
412 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
413 "HIDE (performLayout)", null);
414 if (mSurface != null) {
415 mSurfaceShown = false;
416 try {
417 mSurface.hide();
418 } catch (RuntimeException e) {
419 Slog.w(TAG, "Exception hiding surface in " + mWin);
420 }
421 }
422 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700423 }
424
Craig Mautnera608b882012-03-30 13:03:49 -0700425 boolean finishDrawingLocked() {
Craig Mautner6fbda632012-07-03 09:26:39 -0700426 if (DEBUG_STARTING_WINDOW &&
427 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
428 Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
429 + drawStateToString(mDrawState));
430 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700431 if (mDrawState == DRAW_PENDING) {
Craig Mautneref25d7a2012-05-15 23:01:47 -0700432 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
433 Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + this + " in "
Craig Mautner83339b42012-05-01 22:13:23 -0700434 + mSurface);
Craig Mautner6fbda632012-07-03 09:26:39 -0700435 if (DEBUG_STARTING_WINDOW &&
436 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
437 Slog.v(TAG, "Draw state now committed in " + mWin);
438 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700439 mDrawState = COMMIT_DRAW_PENDING;
Craig Mautnera608b882012-03-30 13:03:49 -0700440 return true;
441 }
442 return false;
443 }
444
445 // This must be called while inside a transaction.
446 boolean commitFinishDrawingLocked(long currentTime) {
Craig Mautner6fbda632012-07-03 09:26:39 -0700447 if (DEBUG_STARTING_WINDOW &&
448 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
449 Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
450 + drawStateToString(mDrawState));
451 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700452 if (mDrawState != COMMIT_DRAW_PENDING) {
Craig Mautnera608b882012-03-30 13:03:49 -0700453 return false;
454 }
Craig Mautner6fbda632012-07-03 09:26:39 -0700455 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) {
Craig Mautner83339b42012-05-01 22:13:23 -0700456 Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurface);
Craig Mautner6fbda632012-07-03 09:26:39 -0700457 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700458 mDrawState = READY_TO_SHOW;
Craig Mautnera608b882012-03-30 13:03:49 -0700459 final boolean starting = mWin.mAttrs.type == TYPE_APPLICATION_STARTING;
460 final AppWindowToken atoken = mWin.mAppToken;
461 if (atoken == null || atoken.allDrawn || starting) {
462 performShowLocked();
463 }
464 return true;
465 }
466
Craig Mautner7d8df392012-04-06 15:26:23 -0700467 static class SurfaceTrace extends Surface {
468 private final static String SURFACE_TAG = "SurfaceTrace";
469 final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
Craig Mautner7358fbf2012-04-12 21:06:33 -0700470
Craig Mautner7d8df392012-04-06 15:26:23 -0700471 private float mSurfaceTraceAlpha = 0;
Craig Mautner7358fbf2012-04-12 21:06:33 -0700472 private int mLayer;
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700473 private final PointF mPosition = new PointF();
474 private final Point mSize = new Point();
475 private final Rect mWindowCrop = new Rect();
Craig Mautner7358fbf2012-04-12 21:06:33 -0700476 private boolean mShown = false;
Craig Mautner9de49362012-08-02 14:30:30 -0700477 private int mDisplayId;
Craig Mautner7358fbf2012-04-12 21:06:33 -0700478 private String mName = "Not named";
479
Craig Mautner7d8df392012-04-06 15:26:23 -0700480 public SurfaceTrace(SurfaceSession s,
Craig Mautner6881a102012-07-27 13:04:51 -0700481 int pid, int displayId, int w, int h, int format, int flags) throws
Craig Mautner7358fbf2012-04-12 21:06:33 -0700482 OutOfResourcesException {
Craig Mautner6881a102012-07-27 13:04:51 -0700483 super(s, pid, displayId, w, h, format, flags);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700484 mSize.set(w, h);
Craig Mautner9de49362012-08-02 14:30:30 -0700485 mDisplayId = displayId;
Craig Mautner7d8df392012-04-06 15:26:23 -0700486 Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700487 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700488 }
489
Craig Mautner7d8df392012-04-06 15:26:23 -0700490 public SurfaceTrace(SurfaceSession s,
Craig Mautner6881a102012-07-27 13:04:51 -0700491 int pid, String name, int displayId, int w, int h, int format, int flags)
Craig Mautner7358fbf2012-04-12 21:06:33 -0700492 throws OutOfResourcesException {
Craig Mautner6881a102012-07-27 13:04:51 -0700493 super(s, pid, name, displayId, w, h, format, flags);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700494 mName = name;
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700495 mSize.set(w, h);
Craig Mautner7d8df392012-04-06 15:26:23 -0700496 Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700497 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700498 }
499
500 @Override
501 public void setAlpha(float alpha) {
502 super.setAlpha(alpha);
Craig Mautner7d8df392012-04-06 15:26:23 -0700503 mSurfaceTraceAlpha = alpha;
504 Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700505 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700506 }
507
508 @Override
509 public void setLayer(int zorder) {
510 super.setLayer(zorder);
511 mLayer = zorder;
Craig Mautner7d8df392012-04-06 15:26:23 -0700512 Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700513 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700514
515 sSurfaces.remove(this);
516 int i;
517 for (i = sSurfaces.size() - 1; i >= 0; i--) {
Craig Mautner7d8df392012-04-06 15:26:23 -0700518 SurfaceTrace s = sSurfaces.get(i);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700519 if (s.mLayer < zorder) {
520 break;
521 }
522 }
523 sSurfaces.add(i + 1, this);
524 }
525
526 @Override
527 public void setPosition(float x, float y) {
528 super.setPosition(x, y);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700529 mPosition.set(x, y);
Craig Mautner7d8df392012-04-06 15:26:23 -0700530 Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700531 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700532 }
533
534 @Override
535 public void setSize(int w, int h) {
536 super.setSize(w, h);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700537 mSize.set(w, h);
Craig Mautner7d8df392012-04-06 15:26:23 -0700538 Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700539 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700540 }
541
542 @Override
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700543 public void setWindowCrop(Rect crop) {
544 super.setWindowCrop(crop);
Craig Mautneref25d7a2012-05-15 23:01:47 -0700545 if (crop != null) {
546 mWindowCrop.set(crop);
547 }
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700548 Slog.v(SURFACE_TAG, "setWindowCrop: " + this + ". Called by "
549 + Debug.getCallers(3));
550 }
551
552 @Override
Craig Mautner9de49362012-08-02 14:30:30 -0700553 public void setDisplayId(int displayId) {
554 super.setDisplayId(displayId);
555 mDisplayId = displayId;
556 Slog.v(SURFACE_TAG, "setDisplayId: " + this + ". Called by " + Debug.getCallers(3));
557 }
558
559 @Override
Craig Mautner7358fbf2012-04-12 21:06:33 -0700560 public void hide() {
561 super.hide();
562 mShown = false;
Craig Mautner7d8df392012-04-06 15:26:23 -0700563 Slog.v(SURFACE_TAG, "hide: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700564 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700565 }
566 @Override
567 public void show() {
568 super.show();
569 mShown = true;
Craig Mautner7d8df392012-04-06 15:26:23 -0700570 Slog.v(SURFACE_TAG, "show: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700571 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700572 }
573
574 @Override
575 public void destroy() {
576 super.destroy();
Craig Mautner7d8df392012-04-06 15:26:23 -0700577 Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700578 + Debug.getCallers(3));
Craig Mautner7358fbf2012-04-12 21:06:33 -0700579 sSurfaces.remove(this);
580 }
581
Craig Mautneracaf9cc2012-04-17 11:45:25 -0700582 @Override
583 public void release() {
584 super.release();
585 Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -0700586 + Debug.getCallers(3));
Craig Mautneracaf9cc2012-04-17 11:45:25 -0700587 sSurfaces.remove(this);
588 }
589
Craig Mautner7358fbf2012-04-12 21:06:33 -0700590 static void dumpAllSurfaces() {
591 final int N = sSurfaces.size();
592 for (int i = 0; i < N; i++) {
593 Slog.i(TAG, "SurfaceDump: " + sSurfaces.get(i));
594 }
595 }
596
597 @Override
598 public String toString() {
Craig Mautnerfbf378c2012-04-23 17:24:21 -0700599 return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
Craig Mautner9de49362012-08-02 14:30:30 -0700600 + mName + " (" + mDisplayId + "): shown=" + mShown + " layer=" + mLayer
Craig Mautner7d8df392012-04-06 15:26:23 -0700601 + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700602 + " " + mSize.x + "x" + mSize.y
603 + " crop=" + mWindowCrop.toShortString();
Craig Mautner7358fbf2012-04-12 21:06:33 -0700604 }
605 }
606
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700607 Surface createSurfaceLocked() {
608 if (mSurface == null) {
Craig Mautner83339b42012-05-01 22:13:23 -0700609 if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
610 "createSurface " + this + ": mDrawState=DRAW_PENDING");
Craig Mautner749a7bb2012-04-02 13:49:53 -0700611 mDrawState = DRAW_PENDING;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700612 if (mWin.mAppToken != null) {
613 mWin.mAppToken.allDrawn = false;
614 }
615
616 mService.makeWindowFreezingScreenIfNeededLocked(mWin);
617
618 int flags = 0;
619 final WindowManager.LayoutParams attrs = mWin.mAttrs;
620
621 if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
622 flags |= Surface.SECURE;
623 }
624 if (WindowState.DEBUG_VISIBILITY) Slog.v(
625 TAG, "Creating surface in session "
626 + mSession.mSurfaceSession + " window " + this
627 + " w=" + mWin.mCompatFrame.width()
628 + " h=" + mWin.mCompatFrame.height() + " format="
629 + attrs.format + " flags=" + flags);
630
631 int w = mWin.mCompatFrame.width();
632 int h = mWin.mCompatFrame.height();
633 if ((attrs.flags & LayoutParams.FLAG_SCALED) != 0) {
634 // for a scaled surface, we always want the requested
635 // size.
636 w = mWin.mRequestedWidth;
637 h = mWin.mRequestedHeight;
638 }
639
640 // Something is wrong and SurfaceFlinger will not like this,
641 // try to revert to sane values
642 if (w <= 0) w = 1;
643 if (h <= 0) h = 1;
644
645 mSurfaceShown = false;
646 mSurfaceLayer = 0;
Craig Mautner7d8df392012-04-06 15:26:23 -0700647 mSurfaceAlpha = 0;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700648 mSurfaceX = 0;
649 mSurfaceY = 0;
650 mSurfaceW = w;
651 mSurfaceH = h;
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700652 mWin.mLastSystemDecorRect.set(0, 0, 0, 0);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700653 try {
654 final boolean isHwAccelerated = (attrs.flags &
655 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
656 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
657 if (!PixelFormat.formatHasAlpha(attrs.format)) {
658 flags |= Surface.OPAQUE;
659 }
Craig Mautner7358fbf2012-04-12 21:06:33 -0700660 if (DEBUG_SURFACE_TRACE) {
Craig Mautner7d8df392012-04-06 15:26:23 -0700661 mSurface = new SurfaceTrace(
Craig Mautner7358fbf2012-04-12 21:06:33 -0700662 mSession.mSurfaceSession, mSession.mPid,
663 attrs.getTitle().toString(),
Craig Mautner59c00972012-07-30 12:10:24 -0700664 mWin.mDisplayContent.getDisplayId(), w, h, format, flags);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700665 } else {
666 mSurface = new Surface(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700667 mSession.mSurfaceSession, mSession.mPid,
668 attrs.getTitle().toString(),
Craig Mautner59c00972012-07-30 12:10:24 -0700669 mWin.mDisplayContent.getDisplayId(), w, h, format, flags);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700670 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700671 mWin.mHasSurface = true;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700672 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG,
673 " CREATE SURFACE "
674 + mSurface + " IN SESSION "
675 + mSession.mSurfaceSession
676 + ": pid=" + mSession.mPid + " format="
677 + attrs.format + " flags=0x"
678 + Integer.toHexString(flags)
679 + " / " + this);
680 } catch (Surface.OutOfResourcesException e) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700681 mWin.mHasSurface = false;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700682 Slog.w(TAG, "OutOfResourcesException creating surface");
683 mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
Craig Mautner749a7bb2012-04-02 13:49:53 -0700684 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700685 return null;
686 } catch (Exception e) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700687 mWin.mHasSurface = false;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700688 Slog.e(TAG, "Exception creating surface", e);
Craig Mautner749a7bb2012-04-02 13:49:53 -0700689 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700690 return null;
691 }
692
693 if (WindowManagerService.localLOGV) Slog.v(
694 TAG, "Got surface: " + mSurface
695 + ", set left=" + mWin.mFrame.left + " top=" + mWin.mFrame.top
696 + ", animLayer=" + mAnimLayer);
697 if (SHOW_LIGHT_TRANSACTIONS) {
698 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
699 WindowManagerService.logSurface(mWin, "CREATE pos=("
700 + mWin.mFrame.left + "," + mWin.mFrame.top + ") ("
701 + mWin.mCompatFrame.width() + "x" + mWin.mCompatFrame.height()
702 + "), layer=" + mAnimLayer + " HIDE", null);
703 }
704 Surface.openTransaction();
705 try {
706 try {
707 mSurfaceX = mWin.mFrame.left + mWin.mXOffset;
708 mSurfaceY = mWin.mFrame.top + mWin.mYOffset;
709 mSurface.setPosition(mSurfaceX, mSurfaceY);
710 mSurfaceLayer = mAnimLayer;
711 mSurface.setLayer(mAnimLayer);
Craig Mautner7d8df392012-04-06 15:26:23 -0700712 mSurface.setAlpha(0);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700713 mSurfaceShown = false;
714 mSurface.hide();
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700715 } catch (RuntimeException e) {
716 Slog.w(TAG, "Error creating surface in " + w, e);
717 mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
718 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700719 mLastHidden = true;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700720 } finally {
721 Surface.closeTransaction();
722 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
723 "<<< CLOSE TRANSACTION createSurfaceLocked");
724 }
725 if (WindowManagerService.localLOGV) Slog.v(
726 TAG, "Created surface " + this);
727 }
728 return mSurface;
729 }
730
731 void destroySurfaceLocked() {
732 if (mWin.mAppToken != null && mWin == mWin.mAppToken.startingWindow) {
733 mWin.mAppToken.startingDisplayed = false;
734 }
735
736 if (mSurface != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700737
738 int i = mWin.mChildWindows.size();
739 while (i > 0) {
740 i--;
741 WindowState c = mWin.mChildWindows.get(i);
742 c.mAttachedHidden = true;
743 }
744
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700745 try {
746 if (DEBUG_VISIBILITY) {
747 RuntimeException e = null;
748 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
749 e = new RuntimeException();
750 e.fillInStackTrace();
751 }
752 Slog.w(TAG, "Window " + this + " destroying surface "
753 + mSurface + ", session " + mSession, e);
754 }
755 if (mSurfaceDestroyDeferred) {
756 if (mSurface != null && mPendingDestroySurface != mSurface) {
757 if (mPendingDestroySurface != null) {
758 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
759 RuntimeException e = null;
760 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
761 e = new RuntimeException();
762 e.fillInStackTrace();
763 }
764 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
765 }
766 mPendingDestroySurface.destroy();
767 }
768 mPendingDestroySurface = mSurface;
769 }
770 } else {
771 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
772 RuntimeException e = null;
773 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
774 e = new RuntimeException();
775 e.fillInStackTrace();
776 }
777 WindowManagerService.logSurface(mWin, "DESTROY", e);
778 }
779 mSurface.destroy();
780 }
Craig Mautnerb9836b92012-06-11 11:40:09 -0700781 mAnimator.hideWallpapersLocked(mWin);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700782 } catch (RuntimeException e) {
783 Slog.w(TAG, "Exception thrown when destroying Window " + this
784 + " surface " + mSurface + " session " + mSession
785 + ": " + e.toString());
786 }
787
788 mSurfaceShown = false;
789 mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700790 mWin.mHasSurface =false;
Craig Mautnerbf08af32012-05-16 19:43:42 -0700791 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700792 }
793 }
794
795 void destroyDeferredSurfaceLocked() {
796 try {
797 if (mPendingDestroySurface != null) {
798 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
799 RuntimeException e = null;
800 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
801 e = new RuntimeException();
802 e.fillInStackTrace();
803 }
804 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
805 }
806 mPendingDestroySurface.destroy();
Craig Mautnerb9836b92012-06-11 11:40:09 -0700807 mAnimator.hideWallpapersLocked(mWin);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700808 }
809 } catch (RuntimeException e) {
Craig Mautnerd87946b2012-03-29 18:00:19 -0700810 Slog.w(TAG, "Exception thrown when destroying Window "
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700811 + this + " surface " + mPendingDestroySurface
812 + " session " + mSession + ": " + e.toString());
813 }
814 mSurfaceDestroyDeferred = false;
815 mPendingDestroySurface = null;
816 }
817
818 void computeShownFrameLocked() {
819 final boolean selfTransformation = mHasLocalTransformation;
820 Transformation attachedTransformation =
Craig Mautner322e4032012-07-13 13:35:20 -0700821 (mAttachedWinAnimator != null && mAttachedWinAnimator.mHasLocalTransformation)
822 ? mAttachedWinAnimator.mTransformation : null;
823 Transformation appTransformation = (mAppAnimator != null && mAppAnimator.hasTransformation)
824 ? mAppAnimator.transformation : null;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700825
826 // Wallpapers are animated based on the "real" window they
827 // are currently targeting.
Craig Mautner918b53b2012-07-09 14:15:54 -0700828 if (mIsWallpaper && mAnimator.mLowerWallpaperTarget == null
829 && mAnimator.mWallpaperTarget != null) {
830 final WindowStateAnimator wallpaperAnimator = mAnimator.mWallpaperTarget.mWinAnimator;
831 if (wallpaperAnimator.mHasLocalTransformation &&
832 wallpaperAnimator.mAnimation != null &&
833 !wallpaperAnimator.mAnimation.getDetachWallpaper()) {
834 attachedTransformation = wallpaperAnimator.mTransformation;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700835 if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
836 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
837 }
838 }
Craig Mautner918b53b2012-07-09 14:15:54 -0700839 final AppWindowAnimator wpAppAnimator = mAnimator.mWpAppAnimator;
840 if (wpAppAnimator != null && wpAppAnimator.hasTransformation
841 && wpAppAnimator.animation != null
842 && !wpAppAnimator.animation.getDetachWallpaper()) {
Craig Mautner59431632012-04-04 11:56:44 -0700843 appTransformation = wpAppAnimator.transformation;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700844 if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
845 Slog.v(TAG, "WP target app xform: " + appTransformation);
846 }
847 }
848 }
849
850 final boolean screenAnimation = mService.mAnimator.mScreenRotationAnimation != null
851 && mService.mAnimator.mScreenRotationAnimation.isAnimating();
852 if (selfTransformation || attachedTransformation != null
853 || appTransformation != null || screenAnimation) {
854 // cache often used attributes locally
855 final Rect frame = mWin.mFrame;
856 final float tmpFloats[] = mService.mTmpFloats;
857 final Matrix tmpMatrix = mWin.mTmpMatrix;
858
859 // Compute the desired transformation.
860 if (screenAnimation) {
861 // If we are doing a screen animation, the global rotation
862 // applied to windows can result in windows that are carefully
863 // aligned with each other to slightly separate, allowing you
864 // to see what is behind them. An unsightly mess. This...
865 // thing... magically makes it call good: scale each window
866 // slightly (two pixels larger in each dimension, from the
867 // window's center).
868 final float w = frame.width();
869 final float h = frame.height();
870 if (w>=1 && h>=1) {
871 tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
872 } else {
873 tmpMatrix.reset();
874 }
875 } else {
876 tmpMatrix.reset();
877 }
878 tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
879 if (selfTransformation) {
880 tmpMatrix.postConcat(mTransformation.getMatrix());
881 }
882 tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
883 if (attachedTransformation != null) {
884 tmpMatrix.postConcat(attachedTransformation.getMatrix());
885 }
886 if (appTransformation != null) {
887 tmpMatrix.postConcat(appTransformation.getMatrix());
888 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700889 if (mAnimator.mUniverseBackground != null) {
890 tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix());
891 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700892 if (screenAnimation) {
893 tmpMatrix.postConcat(
894 mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getMatrix());
895 }
896
897 // "convert" it into SurfaceFlinger's format
898 // (a 2x2 matrix + an offset)
899 // Here we must not transform the position of the surface
900 // since it is already included in the transformation.
901 //Slog.i(TAG, "Transform: " + matrix);
902
903 mHaveMatrix = true;
904 tmpMatrix.getValues(tmpFloats);
905 mDsDx = tmpFloats[Matrix.MSCALE_X];
906 mDtDx = tmpFloats[Matrix.MSKEW_Y];
907 mDsDy = tmpFloats[Matrix.MSKEW_X];
908 mDtDy = tmpFloats[Matrix.MSCALE_Y];
909 float x = tmpFloats[Matrix.MTRANS_X];
910 float y = tmpFloats[Matrix.MTRANS_Y];
911 int w = frame.width();
912 int h = frame.height();
913 mWin.mShownFrame.set(x, y, x+w, y+h);
914
915 // Now set the alpha... but because our current hardware
916 // can't do alpha transformation on a non-opaque surface,
917 // turn it off if we are running an animation that is also
918 // transforming since it is more important to have that
919 // animation be smooth.
920 mShownAlpha = mAlpha;
921 if (!mService.mLimitedAlphaCompositing
922 || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
923 || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
924 && x == frame.left && y == frame.top))) {
925 //Slog.i(TAG, "Applying alpha transform");
926 if (selfTransformation) {
927 mShownAlpha *= mTransformation.getAlpha();
928 }
929 if (attachedTransformation != null) {
930 mShownAlpha *= attachedTransformation.getAlpha();
931 }
932 if (appTransformation != null) {
933 mShownAlpha *= appTransformation.getAlpha();
934 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700935 if (mAnimator.mUniverseBackground != null) {
936 mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
937 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700938 if (screenAnimation) {
939 mShownAlpha *=
940 mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha();
941 }
942 } else {
943 //Slog.i(TAG, "Not applying alpha transform");
944 }
945
Craig Mautner9e809442012-06-22 17:13:04 -0700946 if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV) && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700947 TAG, "computeShownFrameLocked: Animating " + this +
Craig Mautnerf4120952012-06-21 18:25:39 -0700948 " mAlpha=" + mAlpha +
949 " self=" + (selfTransformation ? mTransformation.getAlpha() : "null") +
950 " attached=" + (attachedTransformation == null ? "null" : attachedTransformation.getAlpha()) +
951 " app=" + (appTransformation == null ? "null" : appTransformation.getAlpha()) +
952 " screen=" + (screenAnimation ? mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha()
953 : "null"));
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700954 return;
Craig Mautner918b53b2012-07-09 14:15:54 -0700955 } else if (mIsWallpaper &&
Craig Mautner4d7349b2012-04-20 14:52:47 -0700956 (mAnimator.mPendingActions & WindowAnimator.WALLPAPER_ACTION_PENDING) != 0) {
957 return;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700958 }
959
960 if (WindowManagerService.localLOGV) Slog.v(
Craig Mautner4d7349b2012-04-20 14:52:47 -0700961 TAG, "computeShownFrameLocked: " + this +
962 " not attached, mAlpha=" + mAlpha);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700963 if (mAnimator.mUniverseBackground != null &&
964 mWin.mAttrs.type != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND
965 && mWin.mBaseLayer < mAnimator.mAboveUniverseLayer) {
966 final Rect frame = mWin.mFrame;
967 final float tmpFloats[] = mService.mTmpFloats;
968 final Matrix tmpMatrix = mWin.mTmpMatrix;
969 tmpMatrix.setScale(mWin.mGlobalScale, mWin.mGlobalScale);
970 tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
971 tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix());
972 tmpMatrix.getValues(tmpFloats);
973 mHaveMatrix = true;
974 mDsDx = tmpFloats[Matrix.MSCALE_X];
975 mDtDx = tmpFloats[Matrix.MSKEW_Y];
976 mDsDy = tmpFloats[Matrix.MSKEW_X];
977 mDtDy = tmpFloats[Matrix.MSCALE_Y];
978 float x = tmpFloats[Matrix.MTRANS_X];
979 float y = tmpFloats[Matrix.MTRANS_Y];
980 int w = frame.width();
981 int h = frame.height();
982 mWin.mShownFrame.set(x, y, x+w, y+h);
983 mShownAlpha = mAlpha * mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
984 } else {
985 mWin.mShownFrame.set(mWin.mFrame);
986 if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
987 mWin.mShownFrame.offset(mWin.mXOffset, mWin.mYOffset);
988 }
989 mShownAlpha = mAlpha;
990 mHaveMatrix = false;
991 mDsDx = mWin.mGlobalScale;
992 mDtDx = 0;
993 mDsDy = 0;
994 mDtDy = mWin.mGlobalScale;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700995 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700996 }
997
998 void applyDecorRect(final Rect decorRect) {
999 final WindowState w = mWin;
1000 // Compute the offset of the window in relation to the decor rect.
1001 final int offX = w.mXOffset + w.mFrame.left;
1002 final int offY = w.mYOffset + w.mFrame.top;
1003 // Initialize the decor rect to the entire frame.
1004 w.mSystemDecorRect.set(0, 0, w.mFrame.width(), w.mFrame.height());
1005 // Intersect with the decor rect, offsetted by window position.
1006 w.mSystemDecorRect.intersect(decorRect.left-offX, decorRect.top-offY,
1007 decorRect.right-offX, decorRect.bottom-offY);
1008 // If size compatibility is being applied to the window, the
1009 // surface is scaled relative to the screen. Also apply this
1010 // scaling to the crop rect. We aren't using the standard rect
1011 // scale function because we want to round things to make the crop
1012 // always round to a larger rect to ensure we don't crop too
1013 // much and hide part of the window that should be seen.
1014 if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
1015 final float scale = w.mInvGlobalScale;
1016 w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
1017 w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
1018 w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
1019 w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
1020 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001021 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001022
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001023 void updateSurfaceWindowCrop(final boolean recoveringMemory) {
1024 final WindowState w = mWin;
1025
1026 // Need to recompute a new system decor rect each time.
1027 if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
1028 // Currently can't do this cropping for scaled windows. We'll
1029 // just keep the crop rect the same as the source surface.
1030 w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight);
1031 } else if (w.mLayer >= mService.mSystemDecorLayer) {
1032 // Above the decor layer is easy, just use the entire window.
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07001033 // Unless we have a universe background... in which case all the
1034 // windows need to be cropped by the screen, so they don't cover
1035 // the universe background.
1036 if (mAnimator.mUniverseBackground == null) {
1037 w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(),
1038 w.mCompatFrame.height());
1039 } else {
1040 applyDecorRect(mService.mScreenRect);
1041 }
1042 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND) {
1043 // The universe background isn't cropped.
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001044 w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(),
1045 w.mCompatFrame.height());
1046 } else {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07001047 applyDecorRect(mService.mSystemDecorRect);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001048 }
1049
1050 if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) {
1051 w.mLastSystemDecorRect.set(w.mSystemDecorRect);
1052 try {
1053 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1054 "CROP " + w.mSystemDecorRect.toShortString(), null);
1055 mSurface.setWindowCrop(w.mSystemDecorRect);
1056 } catch (RuntimeException e) {
1057 Slog.w(TAG, "Error setting crop surface of " + w
1058 + " crop=" + w.mSystemDecorRect.toShortString(), e);
1059 if (!recoveringMemory) {
1060 mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
1061 }
1062 }
1063 }
1064 }
1065
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001066 void setSurfaceBoundaries(final boolean recoveringMemory) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001067 final WindowState w = mWin;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001068 int width, height;
1069 if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
1070 // for a scaled surface, we just want to use
1071 // the requested size.
1072 width = w.mRequestedWidth;
1073 height = w.mRequestedHeight;
1074 } else {
1075 width = w.mCompatFrame.width();
1076 height = w.mCompatFrame.height();
1077 }
1078
1079 if (width < 1) {
1080 width = 1;
1081 }
1082 if (height < 1) {
1083 height = 1;
1084 }
1085 final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height;
1086 if (surfaceResized) {
1087 mSurfaceW = width;
1088 mSurfaceH = height;
1089 }
1090
Craig Mautner4d7349b2012-04-20 14:52:47 -07001091 final float left = w.mShownFrame.left;
1092 final float top = w.mShownFrame.top;
1093 if (mSurfaceX != left || mSurfaceY != top) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001094 try {
1095 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
Craig Mautner4d7349b2012-04-20 14:52:47 -07001096 "POS " + left + ", " + top, null);
1097 mSurfaceX = left;
1098 mSurfaceY = top;
1099 mSurface.setPosition(left, top);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001100 } catch (RuntimeException e) {
1101 Slog.w(TAG, "Error positioning surface of " + w
Craig Mautner4d7349b2012-04-20 14:52:47 -07001102 + " pos=(" + left
1103 + "," + top + ")", e);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001104 if (!recoveringMemory) {
1105 mService.reclaimSomeSurfaceMemoryLocked(this, "position", true);
1106 }
1107 }
1108 }
1109
1110 if (surfaceResized) {
1111 try {
1112 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1113 "SIZE " + width + "x" + height, null);
1114 mSurfaceResized = true;
1115 mSurface.setSize(width, height);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001116 mAnimator.mPendingLayoutChanges |=
1117 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Craig Mautner3a67f352012-05-07 11:21:33 -07001118 if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001119 final DisplayInfo displayInfo = mWin.mDisplayContent.getDisplayInfo();
Craig Mautnera76fdb72012-07-03 19:03:02 -07001120 mService.startDimming(this, w.mExiting ? 0 : w.mAttrs.dimAmount,
Craig Mautner59c00972012-07-30 12:10:24 -07001121 displayInfo.appWidth, displayInfo.appHeight);
Craig Mautner3a67f352012-05-07 11:21:33 -07001122 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001123 } catch (RuntimeException e) {
1124 // If something goes wrong with the surface (such
1125 // as running out of memory), don't take down the
1126 // entire system.
1127 Slog.e(TAG, "Error resizing surface of " + w
1128 + " size=(" + width + "x" + height + ")", e);
1129 if (!recoveringMemory) {
1130 mService.reclaimSomeSurfaceMemoryLocked(this, "size", true);
1131 }
1132 }
1133 }
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07001134
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001135 updateSurfaceWindowCrop(recoveringMemory);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001136 }
1137
1138 public void prepareSurfaceLocked(final boolean recoveringMemory) {
1139 final WindowState w = mWin;
1140 if (mSurface == null) {
1141 if (w.mOrientationChanging) {
1142 if (DEBUG_ORIENTATION) {
1143 Slog.v(TAG, "Orientation change skips hidden " + w);
1144 }
1145 w.mOrientationChanging = false;
1146 }
1147 return;
1148 }
1149
1150 boolean displayed = false;
1151
1152 computeShownFrameLocked();
1153
1154 setSurfaceBoundaries(recoveringMemory);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001155
Craig Mautner918b53b2012-07-09 14:15:54 -07001156 if (mIsWallpaper && !mWin.mWallpaperVisible) {
Craig Mautner0fa77c12012-06-11 15:57:19 -07001157 // Wallpaper is no longer visible and there is no wp target => hide it.
1158 hide();
1159 } else if (w.mAttachedHidden || !w.isReadyForDisplay()) {
Craig Mautner0afddcb2012-05-08 15:38:00 -07001160 hide();
Craig Mautnerb9836b92012-06-11 11:40:09 -07001161 mAnimator.hideWallpapersLocked(w);
1162
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001163 // If we are waiting for this window to handle an
1164 // orientation change, well, it is hidden, so
1165 // doesn't really matter. Note that this does
1166 // introduce a potential glitch if the window
1167 // becomes unhidden before it has drawn for the
1168 // new orientation.
1169 if (w.mOrientationChanging) {
1170 w.mOrientationChanging = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001171 if (DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001172 "Orientation change skips hidden " + w);
1173 }
1174 } else if (mLastLayer != mAnimLayer
1175 || mLastAlpha != mShownAlpha
1176 || mLastDsDx != mDsDx
1177 || mLastDtDx != mDtDx
1178 || mLastDsDy != mDsDy
1179 || mLastDtDy != mDtDy
1180 || w.mLastHScale != w.mHScale
1181 || w.mLastVScale != w.mVScale
Craig Mautner749a7bb2012-04-02 13:49:53 -07001182 || mLastHidden) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001183 displayed = true;
1184 mLastAlpha = mShownAlpha;
1185 mLastLayer = mAnimLayer;
1186 mLastDsDx = mDsDx;
1187 mLastDtDx = mDtDx;
1188 mLastDsDy = mDsDy;
1189 mLastDtDy = mDtDy;
1190 w.mLastHScale = w.mHScale;
1191 w.mLastVScale = w.mVScale;
1192 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1193 "alpha=" + mShownAlpha + " layer=" + mAnimLayer
1194 + " matrix=[" + (mDsDx*w.mHScale)
1195 + "," + (mDtDx*w.mVScale)
1196 + "][" + (mDsDy*w.mHScale)
1197 + "," + (mDtDy*w.mVScale) + "]", null);
1198 if (mSurface != null) {
1199 try {
1200 mSurfaceAlpha = mShownAlpha;
1201 mSurface.setAlpha(mShownAlpha);
Craig Mautnerad5725d2012-06-05 10:20:56 -07001202 mSurfaceLayer = mAnimLayer;
1203 mSurface.setLayer(mAnimLayer);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001204 mSurface.setMatrix(
1205 mDsDx*w.mHScale, mDtDx*w.mVScale,
1206 mDsDy*w.mHScale, mDtDy*w.mVScale);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001207
1208 if (mLastHidden && mDrawState == HAS_DRAWN) {
1209 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1210 "SHOW (performLayout)", null);
1211 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
1212 + " during relayout");
1213 if (showSurfaceRobustlyLocked()) {
1214 mLastHidden = false;
Craig Mautner918b53b2012-07-09 14:15:54 -07001215 if (mIsWallpaper) {
Craig Mautner507a2ee2012-06-13 08:39:38 -07001216 mService.dispatchWallpaperVisibility(w, true);
1217 }
Craig Mautner749a7bb2012-04-02 13:49:53 -07001218 } else {
1219 w.mOrientationChanging = false;
1220 }
1221 }
1222 if (mSurface != null) {
1223 w.mToken.hasVisible = true;
1224 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001225 } catch (RuntimeException e) {
1226 Slog.w(TAG, "Error updating surface in " + w, e);
1227 if (!recoveringMemory) {
1228 mService.reclaimSomeSurfaceMemoryLocked(this, "update", true);
1229 }
1230 }
1231 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001232 } else {
Craig Mautner9e809442012-06-22 17:13:04 -07001233 if (DEBUG_ANIM && isAnimating()) {
1234 Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
Craig Mautner83339b42012-05-01 22:13:23 -07001235 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001236 displayed = true;
1237 }
1238
1239 if (displayed) {
1240 if (w.mOrientationChanging) {
1241 if (!w.isDrawnLw()) {
Craig Mautner2639da52012-07-09 09:39:06 -07001242 mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001243 if (DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001244 "Orientation continue waiting for draw in " + w);
1245 } else {
1246 w.mOrientationChanging = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001247 if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001248 }
1249 }
1250 w.mToken.hasVisible = true;
1251 }
1252 }
1253
Craig Mautner48ba1e72012-04-02 13:18:16 -07001254 void setTransparentRegionHint(final Region region) {
Craig Mautner1f4e0cc2012-04-10 14:24:38 -07001255 if (mSurface == null) {
1256 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
1257 return;
1258 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07001259 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1260 ">>> OPEN TRANSACTION setTransparentRegion");
1261 Surface.openTransaction();
1262 try {
1263 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
1264 "transparentRegionHint=" + region, null);
1265 mSurface.setTransparentRegionHint(region);
1266 } finally {
1267 Surface.closeTransaction();
1268 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1269 "<<< CLOSE TRANSACTION setTransparentRegion");
1270 }
1271 }
1272
1273 void setWallpaperOffset(int left, int top) {
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001274 mSurfaceX = left;
1275 mSurfaceY = top;
1276 if (mAnimating) {
1277 // If this window (or its app token) is animating, then the position
1278 // of the surface will be re-computed on the next animation frame.
1279 // We can't poke it directly here because it depends on whatever
1280 // transformation is being applied by the animation.
1281 return;
1282 }
1283 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1284 ">>> OPEN TRANSACTION setWallpaperOffset");
Craig Mautner48ba1e72012-04-02 13:18:16 -07001285 Surface.openTransaction();
1286 try {
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001287 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
1288 "POS " + left + ", " + top, null);
1289 mSurface.setPosition(mWin.mFrame.left + left, mWin.mFrame.top + top);
1290 updateSurfaceWindowCrop(false);
Craig Mautner48ba1e72012-04-02 13:18:16 -07001291 } catch (RuntimeException e) {
1292 Slog.w(TAG, "Error positioning surface of " + mWin
1293 + " pos=(" + left + "," + top + ")", e);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001294 } finally {
1295 Surface.closeTransaction();
1296 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1297 "<<< CLOSE TRANSACTION setWallpaperOffset");
Craig Mautner48ba1e72012-04-02 13:18:16 -07001298 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07001299 }
1300
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001301 // This must be called while inside a transaction.
1302 boolean performShowLocked() {
Craig Mautner9dc52bc2012-08-06 14:15:42 -07001303 if (mWin.isOtherUsersAppWindow()) {
1304 Slog.w(TAG, "Current user " + mService.mCurrentUserId + " trying to display "
Craig Mautnera2d7b112012-08-21 15:12:20 -07001305 + this + ", type " + mWin.mAttrs.type + ", belonging to " + mWin.mOwnerUid);
Craig Mautner9dc52bc2012-08-06 14:15:42 -07001306 return false;
1307 }
Craig Mautner6fbda632012-07-03 09:26:39 -07001308 if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
1309 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001310 RuntimeException e = null;
1311 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
1312 e = new RuntimeException();
1313 e.fillInStackTrace();
1314 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001315 Slog.v(TAG, "performShow on " + this
Craig Mautner749a7bb2012-04-02 13:49:53 -07001316 + ": mDrawState=" + mDrawState + " readyForDisplay="
Dianne Hackborn6e2281d2012-06-19 17:48:32 -07001317 + mWin.isReadyForDisplayIgnoringKeyguard()
Craig Mautner6fbda632012-07-03 09:26:39 -07001318 + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING)
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001319 + " during animation: policyVis=" + mWin.mPolicyVisibility
1320 + " attHidden=" + mWin.mAttachedHidden
1321 + " tok.hiddenRequested="
1322 + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
1323 + " tok.hidden="
1324 + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
1325 + " animating=" + mAnimating
1326 + " tok animating="
Craig Mautner322e4032012-07-13 13:35:20 -07001327 + (mAppAnimator != null ? mAppAnimator.animating : false), e);
Craig Mautner6fbda632012-07-03 09:26:39 -07001328 }
1329 if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplayIgnoringKeyguard()) {
1330 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
1331 WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null);
1332 if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
1333 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
1334 Slog.v(TAG, "Showing " + this
1335 + " during animation: policyVis=" + mWin.mPolicyVisibility
1336 + " attHidden=" + mWin.mAttachedHidden
1337 + " tok.hiddenRequested="
1338 + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
1339 + " tok.hidden="
1340 + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
1341 + " animating=" + mAnimating
1342 + " tok animating="
Craig Mautner322e4032012-07-13 13:35:20 -07001343 + (mAppAnimator != null ? mAppAnimator.animating : false));
Craig Mautner6fbda632012-07-03 09:26:39 -07001344 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001345
1346 mService.enableScreenIfNeededLocked();
1347
1348 applyEnterAnimationLocked();
1349
Craig Mautnerde6198e2012-04-19 09:59:31 -07001350 // Force the show in the next prepareSurfaceLocked() call.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001351 mLastAlpha = -1;
Craig Mautneref25d7a2012-05-15 23:01:47 -07001352 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM)
1353 Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN in " + this);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001354 mDrawState = HAS_DRAWN;
Craig Mautner711f90a2012-07-03 18:43:52 -07001355 mService.updateLayoutToAnimationLocked();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001356
1357 int i = mWin.mChildWindows.size();
1358 while (i > 0) {
1359 i--;
1360 WindowState c = mWin.mChildWindows.get(i);
1361 if (c.mAttachedHidden) {
1362 c.mAttachedHidden = false;
1363 if (c.mWinAnimator.mSurface != null) {
1364 c.mWinAnimator.performShowLocked();
1365 // It hadn't been shown, which means layout not
1366 // performed on it, so now we want to make sure to
1367 // do a layout. If called from within the transaction
1368 // loop, this will cause it to restart with a new
1369 // layout.
1370 mService.mLayoutNeeded = true;
1371 }
1372 }
1373 }
1374
1375 if (mWin.mAttrs.type != TYPE_APPLICATION_STARTING
1376 && mWin.mAppToken != null) {
1377 mWin.mAppToken.firstWindowDrawn = true;
1378
1379 if (mWin.mAppToken.startingData != null) {
1380 if (WindowManagerService.DEBUG_STARTING_WINDOW ||
Craig Mautnerd87946b2012-03-29 18:00:19 -07001381 WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001382 "Finish starting " + mWin.mToken
1383 + ": first real window is shown, no animation");
1384 // If this initial window is animating, stop it -- we
1385 // will do an animation to reveal it from behind the
1386 // starting window, so there is no need for it to also
1387 // be doing its own stuff.
Craig Mautner4d7349b2012-04-20 14:52:47 -07001388 clearAnimation();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001389 mService.mFinishedStarting.add(mWin.mAppToken);
1390 mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
1391 }
1392 mWin.mAppToken.updateReportedVisibilityLocked();
1393 }
1394
1395 return true;
1396 }
1397
1398 return false;
1399 }
1400
1401 /**
1402 * Have the surface flinger show a surface, robustly dealing with
1403 * error conditions. In particular, if there is not enough memory
1404 * to show the surface, then we will try to get rid of other surfaces
1405 * in order to succeed.
1406 *
1407 * @return Returns true if the surface was successfully shown.
1408 */
1409 boolean showSurfaceRobustlyLocked() {
1410 try {
1411 if (mSurface != null) {
1412 mSurfaceShown = true;
1413 mSurface.show();
1414 if (mWin.mTurnOnScreen) {
1415 if (DEBUG_VISIBILITY) Slog.v(TAG,
1416 "Show surface turning screen on: " + mWin);
1417 mWin.mTurnOnScreen = false;
Craig Mautner7d8df392012-04-06 15:26:23 -07001418 mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001419 }
1420 }
1421 return true;
1422 } catch (RuntimeException e) {
1423 Slog.w(TAG, "Failure showing surface " + mSurface + " in " + mWin, e);
1424 }
1425
1426 mService.reclaimSomeSurfaceMemoryLocked(this, "show", true);
1427
1428 return false;
1429 }
1430
1431 void applyEnterAnimationLocked() {
1432 final int transit;
1433 if (mEnterAnimationPending) {
1434 mEnterAnimationPending = false;
1435 transit = WindowManagerPolicy.TRANSIT_ENTER;
1436 } else {
1437 transit = WindowManagerPolicy.TRANSIT_SHOW;
1438 }
1439
1440 applyAnimationLocked(transit, true);
1441 }
1442
Craig Mautner48ba1e72012-04-02 13:18:16 -07001443 // TODO(cmautner): Move back to WindowState?
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001444 /**
1445 * Choose the correct animation and set it to the passed WindowState.
1446 * @param transit If WindowManagerPolicy.TRANSIT_PREVIEW_DONE and the app window has been drawn
1447 * then the animation will be app_starting_exit. Any other value loads the animation from
1448 * the switch statement below.
1449 * @param isEntrance The animation type the last time this was called. Used to keep from
1450 * loading the same animation twice.
1451 * @return true if an animation has been loaded.
1452 */
1453 boolean applyAnimationLocked(int transit, boolean isEntrance) {
1454 if (mLocalAnimating && mAnimationIsEntrance == isEntrance) {
1455 // If we are trying to apply an animation, but already running
1456 // an animation of the same type, then just leave that one alone.
1457 return true;
1458 }
1459
1460 // Only apply an animation if the display isn't frozen. If it is
1461 // frozen, there is no reason to animate and it can cause strange
1462 // artifacts when we unfreeze the display if some different animation
1463 // is running.
1464 if (mService.okToDisplay()) {
1465 int anim = mPolicy.selectAnimationLw(mWin, transit);
1466 int attr = -1;
1467 Animation a = null;
1468 if (anim != 0) {
1469 a = AnimationUtils.loadAnimation(mContext, anim);
1470 } else {
1471 switch (transit) {
1472 case WindowManagerPolicy.TRANSIT_ENTER:
1473 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
1474 break;
1475 case WindowManagerPolicy.TRANSIT_EXIT:
1476 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
1477 break;
1478 case WindowManagerPolicy.TRANSIT_SHOW:
1479 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
1480 break;
1481 case WindowManagerPolicy.TRANSIT_HIDE:
1482 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
1483 break;
1484 }
1485 if (attr >= 0) {
1486 a = mService.loadAnimation(mWin.mAttrs, attr);
1487 }
1488 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001489 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001490 "applyAnimation: win=" + this
1491 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
Craig Mautner4d7349b2012-04-20 14:52:47 -07001492 + " a=" + a
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001493 + " mAnimation=" + mAnimation
Craig Mautner83339b42012-05-01 22:13:23 -07001494 + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3));
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001495 if (a != null) {
1496 if (WindowManagerService.DEBUG_ANIM) {
1497 RuntimeException e = null;
1498 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
1499 e = new RuntimeException();
1500 e.fillInStackTrace();
1501 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001502 Slog.v(TAG, "Loaded animation " + a + " for " + this, e);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001503 }
1504 setAnimation(a);
1505 mAnimationIsEntrance = isEntrance;
1506 }
1507 } else {
1508 clearAnimation();
1509 }
1510
1511 return mAnimation != null;
1512 }
1513
Craig Mautnera2c77052012-03-26 12:14:43 -07001514 public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
1515 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
1516 || mAnimation != null) {
1517 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
1518 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
1519 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
1520 pw.print(" mAnimation="); pw.println(mAnimation);
1521 }
1522 if (mHasTransformation || mHasLocalTransformation) {
1523 pw.print(prefix); pw.print("XForm: has=");
1524 pw.print(mHasTransformation);
1525 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
1526 pw.print(" "); mTransformation.printShortString(pw);
1527 pw.println();
1528 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001529 if (mSurface != null) {
1530 if (dumpAll) {
1531 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Craig Mautner6fbda632012-07-03 09:26:39 -07001532 pw.print(prefix); pw.print("mDrawState=");
1533 pw.print(drawStateToString(mDrawState));
Craig Mautner749a7bb2012-04-02 13:49:53 -07001534 pw.print(" mLastHidden="); pw.println(mLastHidden);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001535 }
1536 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
1537 pw.print(" layer="); pw.print(mSurfaceLayer);
1538 pw.print(" alpha="); pw.print(mSurfaceAlpha);
1539 pw.print(" rect=("); pw.print(mSurfaceX);
1540 pw.print(","); pw.print(mSurfaceY);
1541 pw.print(") "); pw.print(mSurfaceW);
1542 pw.print(" x "); pw.println(mSurfaceH);
1543 }
1544 if (mPendingDestroySurface != null) {
1545 pw.print(prefix); pw.print("mPendingDestroySurface=");
1546 pw.println(mPendingDestroySurface);
1547 }
1548 if (mSurfaceResized || mSurfaceDestroyDeferred) {
1549 pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
1550 pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
1551 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07001552 if (mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND) {
1553 pw.print(prefix); pw.print("mUniverseTransform=");
1554 mUniverseTransform.printShortString(pw);
1555 pw.println();
1556 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001557 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
1558 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
1559 pw.print(" mAlpha="); pw.print(mAlpha);
1560 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
1561 }
1562 if (mHaveMatrix || mWin.mGlobalScale != 1) {
1563 pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale);
1564 pw.print(" mDsDx="); pw.print(mDsDx);
1565 pw.print(" mDtDx="); pw.print(mDtDx);
1566 pw.print(" mDsDy="); pw.print(mDsDy);
1567 pw.print(" mDtDy="); pw.println(mDtDy);
1568 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001569 }
1570
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001571 @Override
1572 public String toString() {
1573 StringBuffer sb = new StringBuffer("WindowStateAnimator (");
1574 sb.append(mWin.mLastTitle + "): ");
1575 sb.append("mSurface " + mSurface);
1576 sb.append(", mAnimation " + mAnimation);
1577 return sb.toString();
1578 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001579}