diff options
4 files changed, 675 insertions, 649 deletions
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java index 3043da2d8aa2..0e110be18272 100644 --- a/services/java/com/android/server/wm/AppWindowToken.java +++ b/services/java/com/android/server/wm/AppWindowToken.java @@ -56,7 +56,8 @@ class AppWindowToken extends WindowToken { // These are used for determining when all windows associated with // an activity have been drawn, so they can be made visible together // at the same time. - int lastTransactionSequence; + // initialize so that it doesn't match mTransactionSequence which is an int. + long lastTransactionSequence = Long.MIN_VALUE; int numInterestingWindows; int numDrawnWindows; boolean inPendingTransaction; @@ -113,7 +114,6 @@ class AppWindowToken extends WindowToken { appWindowToken = this; appToken = _token; mInputApplicationHandle = new InputApplicationHandle(this); - lastTransactionSequence = service.mTransactionSequence-1; } public void setAnimation(Animation anim) { diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java new file mode 100644 index 000000000000..b3dbee192cfd --- /dev/null +++ b/services/java/com/android/server/wm/WindowAnimator.java @@ -0,0 +1,575 @@ +// Copyright 2012 Google Inc. All Rights Reserved. + +package com.android.server.wm; + +import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; + +import android.content.Context; +import android.os.SystemClock; +import android.util.Log; +import android.util.Slog; +import android.view.Surface; +import android.view.WindowManager; +import android.view.WindowManager.LayoutParams; +import android.view.WindowManagerPolicy; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; + +import com.android.internal.policy.impl.PhoneWindowManager; + +/** + * @author cmautner@google.com (Craig Mautner) + * Singleton class that carries out the animations and Surface operations in a separate task + * on behalf of WindowManagerService. + */ +public class WindowAnimator { + private static final String TAG = "WindowAnimations"; + + final WindowManagerService mService; + final Context mContext; + final WindowManagerPolicy mPolicy; + + boolean mAnimating; + boolean mUpdateRotation; + boolean mTokenMayBeDrawn; + boolean mForceHiding; + WindowState mWindowAnimationBackground; + int mWindowAnimationBackgroundColor; + int mAdjResult; + + int mPendingLayoutChanges; + + /** Overall window dimensions */ + int mDw, mDh; + + /** Interior window dimensions */ + int mInnerDw, mInnerDh; + + /** Time of current animation step. Reset on each iteration */ + long mCurrentTime; + + /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this + * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */ + private int mTransactionSequence; + + /** The one and only screen rotation if one is happening */ + ScreenRotationAnimation mScreenRotationAnimation = null; + + WindowAnimator(final WindowManagerService service, final Context context, + final WindowManagerPolicy policy) { + mService = service; + mContext = context; + mPolicy = policy; + } + + private void updateWindowsAppsAndRotationAnimationsLocked() { + int i; + final int NAT = mService.mAppTokens.size(); + for (i=0; i<NAT; i++) { + final AppWindowToken appToken = mService.mAppTokens.get(i); + if (appToken.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) { + mAnimating = true; + } + } + + if (mScreenRotationAnimation != null && + (mScreenRotationAnimation.isAnimating() || + mScreenRotationAnimation.mFinishAnimReady)) { + if (mScreenRotationAnimation.stepAnimationLocked(mCurrentTime)) { + mUpdateRotation = false; + mAnimating = true; + } else { + mUpdateRotation = true; + mScreenRotationAnimation.kill(); + mScreenRotationAnimation = null; + } + } + } + + private void updateWindowsAndWallpaperLocked() { + ++mTransactionSequence; + + for (int i = mService.mWindows.size() - 1; i >= 0; i--) { + WindowState w = mService.mWindows.get(i); + + final WindowManager.LayoutParams attrs = w.mAttrs; + + if (w.mSurface != null) { + // Take care of the window being ready to display. + if (w.commitFinishDrawingLocked(mCurrentTime)) { + if ((w.mAttrs.flags + & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) { + if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG, + "First draw done in potential wallpaper target " + w); + mService.mInnerFields.mWallpaperMayChange = true; + mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; + } + } + + // If the window has moved due to its containing + // content frame changing, then we'd like to animate + // it. The checks here are ordered by what is least + // likely to be true first. + if (w.shouldAnimateMove()) { + // Frame has moved, containing content frame + // has also moved, and we're not currently animating... + // let's do something. + Animation a = AnimationUtils.loadAnimation(mContext, + com.android.internal.R.anim.window_move_from_decor); + w.setAnimation(a); + w.mAnimDw = w.mLastFrame.left - w.mFrame.left; + w.mAnimDh = w.mLastFrame.top - w.mFrame.top; + } else { + w.mAnimDw = mInnerDw; + w.mAnimDh = mInnerDh; + } + + final boolean wasAnimating = w.mWasAnimating; + final boolean nowAnimating = w.stepAnimationLocked(mCurrentTime); + + if (WindowManagerService.DEBUG_WALLPAPER) { + Slog.v(TAG, w + ": wasAnimating=" + wasAnimating + + ", nowAnimating=" + nowAnimating); + } + + // If this window is animating, make a note that we have + // an animating window and take care of a request to run + // a detached wallpaper animation. + if (nowAnimating) { + if (w.mAnimation != null) { + if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 + && w.mAnimation.getDetachWallpaper()) { + mService.mInnerFields.mDetachedWallpaper = w; + } + if (w.mAnimation.getBackgroundColor() != 0) { + if (mWindowAnimationBackground == null + || (w.mAnimLayer < mWindowAnimationBackground.mAnimLayer)) { + mWindowAnimationBackground = w; + mWindowAnimationBackgroundColor = + w.mAnimation.getBackgroundColor(); + } + } + } + mAnimating = true; + } + + // If this window's app token is running a detached wallpaper + // animation, make a note so we can ensure the wallpaper is + // displayed behind it. + if (w.mAppToken != null && w.mAppToken.animation != null + && w.mAppToken.animating) { + if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 + && w.mAppToken.animation.getDetachWallpaper()) { + mService.mInnerFields.mDetachedWallpaper = w; + } + if (w.mAppToken.animation.getBackgroundColor() != 0) { + if (mWindowAnimationBackground == null + || (w.mAnimLayer < + mWindowAnimationBackground.mAnimLayer)) { + mWindowAnimationBackground = w; + mWindowAnimationBackgroundColor = + w.mAppToken.animation.getBackgroundColor(); + } + } + } + + if (wasAnimating && !w.mAnimating && mService.mWallpaperTarget == w) { + mService.mInnerFields.mWallpaperMayChange = true; + mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; + } + + if (mPolicy.doesForceHide(w, attrs)) { + if (!wasAnimating && nowAnimating) { + if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, + "Animation started that could impact force hide: " + + w); + mService.mInnerFields.mWallpaperForceHidingChanged = true; + mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; + mService.mFocusMayChange = true; + } else if (w.isReadyForDisplay() && w.mAnimation == null) { + mForceHiding = true; + } + } else if (mPolicy.canBeForceHidden(w, attrs)) { + boolean changed; + if (mForceHiding) { + changed = w.hideLw(false, false); + if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG, + "Now policy hidden: " + w); + } else { + changed = w.showLw(false, false); + if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG, + "Now policy shown: " + w); + if (changed) { + if (mService.mInnerFields.mWallpaperForceHidingChanged + && w.isVisibleNow() /*w.isReadyForDisplay()*/) { + // Assume we will need to animate. If + // we don't (because the wallpaper will + // stay with the lock screen), then we will + // clean up later. + Animation a = mPolicy.createForceHideEnterAnimation(); + if (a != null) { + w.setAnimation(a); + } + } + if (mCurrentFocus == null || mCurrentFocus.mLayer < w.mLayer) { + // We are showing on to of the current + // focus, so re-evaluate focus to make + // sure it is correct. + mService.mFocusMayChange = true; + } + } + } + if (changed && (attrs.flags + & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) { + mService.mInnerFields.mWallpaperMayChange = true; + mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; + } + } + } + + final AppWindowToken atoken = w.mAppToken; + if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) { + if (atoken.lastTransactionSequence != mTransactionSequence) { + atoken.lastTransactionSequence = mTransactionSequence; + atoken.numInterestingWindows = atoken.numDrawnWindows = 0; + atoken.startingDisplayed = false; + } + if ((w.isOnScreen() || w.mAttrs.type + == WindowManager.LayoutParams.TYPE_BASE_APPLICATION) + && !w.mExiting && !w.mDestroying) { + if (WindowManagerService.DEBUG_VISIBILITY || + WindowManagerService.DEBUG_ORIENTATION) { + Slog.v(TAG, "Eval win " + w + ": isDrawn=" + + w.isDrawnLw() + + ", isAnimating=" + w.isAnimating()); + if (!w.isDrawnLw()) { + Slog.v(TAG, "Not displayed: s=" + w.mSurface + + " pv=" + w.mPolicyVisibility + + " dp=" + w.mDrawPending + + " cdp=" + w.mCommitDrawPending + + " ah=" + w.mAttachedHidden + + " th=" + atoken.hiddenRequested + + " a=" + w.mAnimating); + } + } + if (w != atoken.startingWindow) { + if (!atoken.freezingScreen || !w.mAppFreezing) { + atoken.numInterestingWindows++; + if (w.isDrawnLw()) { + atoken.numDrawnWindows++; + if (WindowManagerService.DEBUG_VISIBILITY || + WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG, + "tokenMayBeDrawn: " + atoken + + " freezingScreen=" + atoken.freezingScreen + + " mAppFreezing=" + w.mAppFreezing); + mTokenMayBeDrawn = true; + } + } + } else if (w.isDrawnLw()) { + atoken.startingDisplayed = true; + } + } + } else if (w.mReadyToShow) { + w.performShowLocked(); + mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; + } + } // end forall windows + } + + private void testTokenMayBeDrawnLocked() { + // See if any windows have been drawn, so they (and others + // associated with them) can now be shown. + final int NT = mService.mAppTokens.size(); + for (int i=0; i<NT; i++) { + AppWindowToken wtoken = mService.mAppTokens.get(i); + if (wtoken.freezingScreen) { + int numInteresting = wtoken.numInterestingWindows; + if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) { + if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, + "allDrawn: " + wtoken + + " interesting=" + numInteresting + + " drawn=" + wtoken.numDrawnWindows); + wtoken.showAllWindowsLocked(); + mService.unsetAppFreezingScreenLocked(wtoken, false, true); + if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG, + "Setting mOrientationChangeComplete=true because wtoken " + + wtoken + " numInteresting=" + numInteresting + + " numDrawn=" + wtoken.numDrawnWindows); + mService.mInnerFields.mOrientationChangeComplete = true; + } + } else if (!wtoken.allDrawn) { + int numInteresting = wtoken.numInterestingWindows; + if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) { + if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, + "allDrawn: " + wtoken + + " interesting=" + numInteresting + + " drawn=" + wtoken.numDrawnWindows); + wtoken.allDrawn = true; + mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM; + + // We can now show all of the drawn windows! + if (!mService.mOpeningApps.contains(wtoken)) { + mAnimating |= wtoken.showAllWindowsLocked(); + } + } + } + } + } + + private void performAnimationsLocked() { + if (WindowManagerService.DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq=" + + mTransactionSequence + " mAnimating=" + + mAnimating); + + mTokenMayBeDrawn = false; + mService.mInnerFields.mWallpaperMayChange = false; + mForceHiding = false; + mService.mInnerFields.mDetachedWallpaper = null; + mWindowAnimationBackground = null; + mWindowAnimationBackgroundColor = 0; + + updateWindowsAndWallpaperLocked(); + + if (mTokenMayBeDrawn) { + testTokenMayBeDrawnLocked(); + } + + if (WindowManagerService.DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x" + + Integer.toHexString(mPendingLayoutChanges)); + } + + public void prepareSurfaceLocked(final WindowState w, final boolean recoveringMemory) { + if (w.mSurface == null) { + if (w.mOrientationChanging) { + if (WindowManagerService.DEBUG_ORIENTATION) { + Slog.v(TAG, "Orientation change skips hidden " + w); + } + w.mOrientationChanging = false; + } + return; + } + + boolean displayed = false; + + w.computeShownFrameLocked(); + + int width, height; + if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) { + // for a scaled surface, we just want to use + // the requested size. + width = w.mRequestedWidth; + height = w.mRequestedHeight; + } else { + width = w.mCompatFrame.width(); + height = w.mCompatFrame.height(); + } + + if (width < 1) { + width = 1; + } + if (height < 1) { + height = 1; + } + final boolean surfaceResized = w.mSurfaceW != width || w.mSurfaceH != height; + if (surfaceResized) { + w.mSurfaceW = width; + w.mSurfaceH = height; + } + + if (w.mSurfaceX != w.mShownFrame.left + || w.mSurfaceY != w.mShownFrame.top) { + try { + if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, + "POS " + w.mShownFrame.left + + ", " + w.mShownFrame.top, null); + w.mSurfaceX = w.mShownFrame.left; + w.mSurfaceY = w.mShownFrame.top; + w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top); + } catch (RuntimeException e) { + Slog.w(TAG, "Error positioning surface of " + w + + " pos=(" + w.mShownFrame.left + + "," + w.mShownFrame.top + ")", e); + if (!recoveringMemory) { + mService.reclaimSomeSurfaceMemoryLocked(w, "position", true); + } + } + } + + if (surfaceResized) { + try { + if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, + "SIZE " + width + "x" + height, null); + w.mSurfaceResized = true; + w.mSurface.setSize(width, height); + } catch (RuntimeException e) { + // If something goes wrong with the surface (such + // as running out of memory), don't take down the + // entire system. + Slog.e(TAG, "Error resizing surface of " + w + + " size=(" + width + "x" + height + ")", e); + if (!recoveringMemory) { + mService.reclaimSomeSurfaceMemoryLocked(w, "size", true); + } + } + } + + if (w.mAttachedHidden || !w.isReadyForDisplay()) { + if (!w.mLastHidden) { + //dump(); + w.mLastHidden = true; + if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, + "HIDE (performLayout)", null); + if (w.mSurface != null) { + w.mSurfaceShown = false; + try { + w.mSurface.hide(); + } catch (RuntimeException e) { + Slog.w(TAG, "Exception hiding surface in " + w); + } + } + } + // If we are waiting for this window to handle an + // orientation change, well, it is hidden, so + // doesn't really matter. Note that this does + // introduce a potential glitch if the window + // becomes unhidden before it has drawn for the + // new orientation. + if (w.mOrientationChanging) { + w.mOrientationChanging = false; + if (WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG, + "Orientation change skips hidden " + w); + } + } else if (w.mLastLayer != w.mAnimLayer + || w.mLastAlpha != w.mShownAlpha + || w.mLastDsDx != w.mDsDx + || w.mLastDtDx != w.mDtDx + || w.mLastDsDy != w.mDsDy + || w.mLastDtDy != w.mDtDy + || w.mLastHScale != w.mHScale + || w.mLastVScale != w.mVScale + || w.mLastHidden) { + displayed = true; + w.mLastAlpha = w.mShownAlpha; + w.mLastLayer = w.mAnimLayer; + w.mLastDsDx = w.mDsDx; + w.mLastDtDx = w.mDtDx; + w.mLastDsDy = w.mDsDy; + w.mLastDtDy = w.mDtDy; + w.mLastHScale = w.mHScale; + w.mLastVScale = w.mVScale; + if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, + "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer + + " matrix=[" + (w.mDsDx*w.mHScale) + + "," + (w.mDtDx*w.mVScale) + + "][" + (w.mDsDy*w.mHScale) + + "," + (w.mDtDy*w.mVScale) + "]", null); + if (w.mSurface != null) { + try { + w.mSurfaceAlpha = w.mShownAlpha; + w.mSurface.setAlpha(w.mShownAlpha); + w.mSurfaceLayer = w.mAnimLayer; + w.mSurface.setLayer(w.mAnimLayer); + w.mSurface.setMatrix( + w.mDsDx*w.mHScale, w.mDtDx*w.mVScale, + w.mDsDy*w.mHScale, w.mDtDy*w.mVScale); + } catch (RuntimeException e) { + Slog.w(TAG, "Error updating surface in " + w, e); + if (!recoveringMemory) { + mService.reclaimSomeSurfaceMemoryLocked(w, "update", true); + } + } + } + + if (w.mLastHidden && w.isDrawnLw() + && !w.mReadyToShow) { + if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, + "SHOW (performLayout)", null); + if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w + + " during relayout"); + if (mService.showSurfaceRobustlyLocked(w)) { + w.mHasDrawn = true; + w.mLastHidden = false; + } else { + w.mOrientationChanging = false; + } + } + if (w.mSurface != null) { + w.mToken.hasVisible = true; + } + } else { + displayed = true; + } + + if (displayed) { + if (w.mOrientationChanging) { + if (!w.isDrawnLw()) { + mService.mInnerFields.mOrientationChangeComplete = false; + if (WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG, + "Orientation continue waiting for draw in " + w); + } else { + w.mOrientationChanging = false; + if (WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG, + "Orientation change complete in " + w); + } + } + w.mToken.hasVisible = true; + } + } + + void animate() { + mCurrentTime = SystemClock.uptimeMillis(); + + // Update animations of all applications, including those + // associated with exiting/removed apps + Surface.openTransaction(); + + try { + updateWindowsAppsAndRotationAnimationsLocked(); + performAnimationsLocked(); + + // THIRD LOOP: Update the surfaces of all windows. + + if (mScreenRotationAnimation != null) { + mScreenRotationAnimation.updateSurfaces(); + } + + final int N = mService.mWindows.size(); + for (int i=N-1; i>=0; i--) { + WindowState w = mService.mWindows.get(i); + prepareSurfaceLocked(w, true); + } + + if (mService.mDimAnimator != null && mService.mDimAnimator.mDimShown) { + mAnimating |= mService.mDimAnimator.updateSurface(mService.mInnerFields.mDimming, + mCurrentTime, !mService.okToDisplay()); + } + + if (mService.mBlackFrame != null) { + if (mScreenRotationAnimation != null) { + mService.mBlackFrame.setMatrix( + mScreenRotationAnimation.getEnterTransformation().getMatrix()); + } else { + mService.mBlackFrame.clearMatrix(); + } + } + } catch (RuntimeException e) { + Log.wtf(TAG, "Unhandled exception in Window Manager", e); + } finally { + Surface.closeTransaction(); + } + } + + WindowState mCurrentFocus; + void setCurrentFocus(WindowState currentFocus) { + mCurrentFocus = currentFocus; + } + + void setDisplayDimensions(final int curWidth, final int curHeight, + final int appWidth, final int appHeight) { + mDw = curWidth; + mDh = curHeight; + mInnerDw = appWidth; + mInnerDh = appHeight; + } + +} diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 31a278888ade..26367d29e30b 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -408,15 +408,12 @@ public class WindowManagerService extends IWindowManager.Stub IInputMethodManager mInputMethodManager; SurfaceSession mFxSession; - private DimAnimator mDimAnimator = null; + DimAnimator mDimAnimator = null; Watermark mWatermark; StrictModeFlash mStrictModeFlash; - ScreenRotationAnimation mScreenRotationAnimation; BlackFrame mBlackFrame; - int mTransactionSequence = 0; - final float[] mTmpFloats = new float[9]; boolean mSafeMode; @@ -575,26 +572,21 @@ public class WindowManagerService extends IWindowManager.Stub /** Pulled out of performLayoutAndPlaceSurfacesLockedInner in order to refactor into multiple * methods. */ - private class LayoutAndSurfaceFields { - private boolean mAnimating = false; - private boolean mWallpaperForceHidingChanged = false; - private boolean mTokenMayBeDrawn = false; - private boolean mWallpaperMayChange = false; - private boolean mForceHiding = false; - private WindowState mDetachedWallpaper = null; - private WindowState mWindowAnimationBackground = null; - private int mWindowAnimationBackgroundColor = 0; - private boolean mOrientationChangeComplete = true; + class LayoutAndSurfaceFields { + boolean mWallpaperForceHidingChanged = false; + boolean mWallpaperMayChange = false; + WindowState mDetachedWallpaper = null; + boolean mOrientationChangeComplete = true; private int mAdjResult = 0; private Session mHoldScreen = null; private boolean mObscured = false; - private boolean mDimming = false; + boolean mDimming = false; private boolean mSyswin = false; private float mScreenBrightness = -1; private float mButtonBrightness = -1; private boolean mUpdateRotation = false; } - private LayoutAndSurfaceFields mInnerFields = new LayoutAndSurfaceFields(); + LayoutAndSurfaceFields mInnerFields = new LayoutAndSurfaceFields(); private final class AnimationRunnable implements Runnable { @Override @@ -607,6 +599,8 @@ public class WindowManagerService extends IWindowManager.Stub } final AnimationRunnable mAnimationRunnable = new AnimationRunnable(); boolean mAnimationScheduled; + + final WindowAnimator mAnimator; final class DragInputEventReceiver extends InputEventReceiver { public DragInputEventReceiver(InputChannel inputChannel, Looper looper) { @@ -828,6 +822,7 @@ public class WindowManagerService extends IWindowManager.Stub mHoldingScreenWakeLock.setReferenceCounted(false); mInputManager = new InputManager(context, this); + mAnimator = new WindowAnimator(this, context, mPolicy); PolicyThread thr = new PolicyThread(mPolicy, this, context, pm); thr.start(); @@ -2209,7 +2204,7 @@ public class WindowManagerService extends IWindowManager.Stub if (mInTouchMode) { res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE; } - if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) { + if (win.mAppToken == null || !win.mAppToken.clientHidden) { res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE; } @@ -2276,7 +2271,7 @@ public class WindowManagerService extends IWindowManager.Stub + ", surface=" + win.mSurface); final long origId = Binder.clearCallingIdentity(); - + win.disposeInputChannel(); if (DEBUG_APP_TRANSITIONS) Slog.v( @@ -2297,7 +2292,8 @@ public class WindowManagerService extends IWindowManager.Stub if (win.mSurface != null && okToDisplay()) { // If we are not currently running the exit animation, we // need to see about starting one. - if (wasVisible=win.isWinVisibleLw()) { + wasVisible = win.isWinVisibleLw(); + if (wasVisible) { int transit = WindowManagerPolicy.TRANSIT_EXIT; if (win.getAttrs().type == TYPE_APPLICATION_STARTING) { @@ -5382,7 +5378,8 @@ public class WindowManagerService extends IWindowManager.Stub return false; } - if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) { + if (mAnimator.mScreenRotationAnimation != null && + mAnimator.mScreenRotationAnimation.isAnimating()) { // Rotation updates cannot be performed while the previous rotation change // animation is still in progress. Skip this update. We will try updating // again after the animation is finished and the display is unfrozen. @@ -5452,9 +5449,9 @@ public class WindowManagerService extends IWindowManager.Stub try { // NOTE: We disable the rotation in the emulator because // it doesn't support hardware OpenGL emulation yet. - if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null - && mScreenRotationAnimation.hasScreenshot()) { - if (mScreenRotationAnimation.setRotation(rotation, mFxSession, + if (CUSTOM_SCREEN_ROTATION && mAnimator.mScreenRotationAnimation != null + && mAnimator.mScreenRotationAnimation.hasScreenshot()) { + if (mAnimator.mScreenRotationAnimation.setRotation(rotation, mFxSession, MAX_ANIMATION_DURATION, mTransitionAnimationScale, mCurDisplayWidth, mCurDisplayHeight)) { scheduleAnimationLocked(); @@ -6156,6 +6153,8 @@ public class WindowManagerService extends IWindowManager.Stub synchronized(mDisplaySizeLock) { mAppDisplayWidth = appWidth; mAppDisplayHeight = appHeight; + mAnimator.setDisplayDimensions(mCurDisplayWidth, mCurDisplayHeight, + mAppDisplayWidth, mAppDisplayHeight); } if (false) { Slog.i(TAG, "Set app display size: " + mAppDisplayWidth @@ -6542,6 +6541,8 @@ public class WindowManagerService extends IWindowManager.Stub } mBaseDisplayWidth = mCurDisplayWidth = mAppDisplayWidth = mInitialDisplayWidth; mBaseDisplayHeight = mCurDisplayHeight = mAppDisplayHeight = mInitialDisplayHeight; + mAnimator.setDisplayDimensions(mCurDisplayWidth, mCurDisplayHeight, + mAppDisplayWidth, mAppDisplayHeight); } mInputManager.setDisplaySize(Display.DEFAULT_DISPLAY, mDisplay.getRawWidth(), mDisplay.getRawHeight(), @@ -7622,342 +7623,6 @@ public class WindowManagerService extends IWindowManager.Stub /** * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method. - * Update animations of all applications, including those associated with exiting/removed apps. - * - * @param currentTime The time which animations use for calculating transitions. - * @param innerDw Width of app window. - * @param innerDh Height of app window. - */ - private void updateWindowsAppsAndRotationAnimationsLocked(long currentTime, - int innerDw, int innerDh) { - int i; - final int NAT = mAppTokens.size(); - for (i=0; i<NAT; i++) { - final AppWindowToken appToken = mAppTokens.get(i); - if (appToken.stepAnimationLocked(currentTime, innerDw, innerDh)) { - mInnerFields.mAnimating = true; - } - } - final int NEAT = mExitingAppTokens.size(); - for (i=0; i<NEAT; i++) { - final AppWindowToken appToken = mExitingAppTokens.get(i); - if (appToken.stepAnimationLocked(currentTime, innerDw, innerDh)) { - mInnerFields.mAnimating = true; - } - } - - if (mScreenRotationAnimation != null && - (mScreenRotationAnimation.isAnimating() || - mScreenRotationAnimation.mFinishAnimReady)) { - if (mScreenRotationAnimation.stepAnimationLocked(currentTime)) { - mInnerFields.mUpdateRotation = false; - mInnerFields.mAnimating = true; - } else { - mInnerFields.mUpdateRotation = true; - mScreenRotationAnimation.kill(); - mScreenRotationAnimation = null; - } - } - } - - private void animateAndUpdateSurfaces(final long currentTime, final int dw, final int dh, - final int innerDw, final int innerDh, - final boolean recoveringMemory) { - // Update animations of all applications, including those - // associated with exiting/removed apps - Surface.openTransaction(); - - try { - updateWindowsAppsAndRotationAnimationsLocked(currentTime, innerDw, innerDh); - mPendingLayoutChanges = performAnimationsLocked(currentTime, dw, dh, - innerDw, innerDh); - - // THIRD LOOP: Update the surfaces of all windows. - - if (mScreenRotationAnimation != null) { - mScreenRotationAnimation.updateSurfaces(); - } - - final int N = mWindows.size(); - for (int i=N-1; i>=0; i--) { - WindowState w = mWindows.get(i); - prepareSurfaceLocked(w, recoveringMemory); - } - - if (mDimAnimator != null && mDimAnimator.mDimShown) { - mInnerFields.mAnimating |= - mDimAnimator.updateSurface(mInnerFields.mDimming, currentTime, - !okToDisplay()); - } - - if (mBlackFrame != null) { - if (mScreenRotationAnimation != null) { - mBlackFrame.setMatrix( - mScreenRotationAnimation.getEnterTransformation().getMatrix()); - } else { - mBlackFrame.clearMatrix(); - } - } - } catch (RuntimeException e) { - Log.wtf(TAG, "Unhandled exception in Window Manager", e); - } finally { - Surface.closeTransaction(); - } - } - - /** - * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method. - * - * @param currentTime The time which animations use for calculating transitions. - * @param dw Width of app window. - * @param dh Height of app window. - * @param innerDw Width of app window. - * @param innerDh Height of app window. - */ - private int updateWindowsAndWallpaperLocked(final long currentTime, final int dw, final int dh, - final int innerDw, final int innerDh) { - ++mTransactionSequence; - - int changes = 0; - for (int i = mWindows.size() - 1; i >= 0; i--) { - WindowState w = mWindows.get(i); - - final WindowManager.LayoutParams attrs = w.mAttrs; - - if (w.mSurface != null) { - // Take care of the window being ready to display. - if (w.commitFinishDrawingLocked(currentTime)) { - if ((w.mAttrs.flags - & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) { - if (DEBUG_WALLPAPER) Slog.v(TAG, - "First draw done in potential wallpaper target " + w); - mInnerFields.mWallpaperMayChange = true; - changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; - } - } - - // If the window has moved due to its containing - // content frame changing, then we'd like to animate - // it. The checks here are ordered by what is least - // likely to be true first. - if (w.shouldAnimateMove()) { - // Frame has moved, containing content frame - // has also moved, and we're not currently animating... - // let's do something. - Animation a = AnimationUtils.loadAnimation(mContext, - com.android.internal.R.anim.window_move_from_decor); - w.setAnimation(a); - w.mAnimDw = w.mLastFrame.left - w.mFrame.left; - w.mAnimDh = w.mLastFrame.top - w.mFrame.top; - } else { - w.mAnimDw = innerDw; - w.mAnimDh = innerDh; - } - - final boolean wasAnimating = w.mWasAnimating; - final boolean nowAnimating = w.stepAnimationLocked(currentTime); - - if (DEBUG_WALLPAPER) { - Slog.v(TAG, w + ": wasAnimating=" + wasAnimating + - ", nowAnimating=" + nowAnimating); - } - - // If this window is animating, make a note that we have - // an animating window and take care of a request to run - // a detached wallpaper animation. - if (nowAnimating) { - if (w.mAnimation != null) { - if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 - && w.mAnimation.getDetachWallpaper()) { - mInnerFields.mDetachedWallpaper = w; - } - if (w.mAnimation.getBackgroundColor() != 0) { - if (mInnerFields.mWindowAnimationBackground == null - || (w.mAnimLayer < - mInnerFields.mWindowAnimationBackground.mAnimLayer)) { - mInnerFields.mWindowAnimationBackground = w; - mInnerFields.mWindowAnimationBackgroundColor = - w.mAnimation.getBackgroundColor(); - } - } - } - mInnerFields.mAnimating = true; - } - - // If this window's app token is running a detached wallpaper - // animation, make a note so we can ensure the wallpaper is - // displayed behind it. - if (w.mAppToken != null && w.mAppToken.animation != null - && w.mAppToken.animating) { - if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 - && w.mAppToken.animation.getDetachWallpaper()) { - mInnerFields.mDetachedWallpaper = w; - } - if (w.mAppToken.animation.getBackgroundColor() != 0) { - if (mInnerFields.mWindowAnimationBackground == null - || (w.mAnimLayer < - mInnerFields.mWindowAnimationBackground.mAnimLayer)) { - mInnerFields.mWindowAnimationBackground = w; - mInnerFields.mWindowAnimationBackgroundColor = - w.mAppToken.animation.getBackgroundColor(); - } - } - } - - if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) { - mInnerFields.mWallpaperMayChange = true; - changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; - } - - if (mPolicy.doesForceHide(w, attrs)) { - if (!wasAnimating && nowAnimating) { - if (DEBUG_VISIBILITY) Slog.v(TAG, - "Animation started that could impact force hide: " - + w); - mInnerFields.mWallpaperForceHidingChanged = true; - changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; - mFocusMayChange = true; - } else if (w.isReadyForDisplay() && w.mAnimation == null) { - mInnerFields.mForceHiding = true; - } - } else if (mPolicy.canBeForceHidden(w, attrs)) { - boolean changed; - if (mInnerFields.mForceHiding) { - changed = w.hideLw(false, false); - if (DEBUG_VISIBILITY && changed) Slog.v(TAG, - "Now policy hidden: " + w); - } else { - changed = w.showLw(false, false); - if (DEBUG_VISIBILITY && changed) Slog.v(TAG, - "Now policy shown: " + w); - if (changed) { - if (mInnerFields.mWallpaperForceHidingChanged - && w.isVisibleNow() /*w.isReadyForDisplay()*/) { - // Assume we will need to animate. If - // we don't (because the wallpaper will - // stay with the lock screen), then we will - // clean up later. - Animation a = mPolicy.createForceHideEnterAnimation(); - if (a != null) { - w.setAnimation(a); - } - } - if (mCurrentFocus == null || - mCurrentFocus.mLayer < w.mLayer) { - // We are showing on to of the current - // focus, so re-evaluate focus to make - // sure it is correct. - mFocusMayChange = true; - } - } - } - if (changed && (attrs.flags - & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) { - mInnerFields.mWallpaperMayChange = true; - changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; - } - } - } - - final AppWindowToken atoken = w.mAppToken; - if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) { - if (atoken.lastTransactionSequence != mTransactionSequence) { - atoken.lastTransactionSequence = mTransactionSequence; - atoken.numInterestingWindows = atoken.numDrawnWindows = 0; - atoken.startingDisplayed = false; - } - if ((w.isOnScreen() || w.mAttrs.type - == WindowManager.LayoutParams.TYPE_BASE_APPLICATION) - && !w.mExiting && !w.mDestroying) { - if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) { - Slog.v(TAG, "Eval win " + w + ": isDrawn=" - + w.isDrawnLw() - + ", isAnimating=" + w.isAnimating()); - if (!w.isDrawnLw()) { - Slog.v(TAG, "Not displayed: s=" + w.mSurface - + " pv=" + w.mPolicyVisibility - + " dp=" + w.mDrawPending - + " cdp=" + w.mCommitDrawPending - + " ah=" + w.mAttachedHidden - + " th=" + atoken.hiddenRequested - + " a=" + w.mAnimating); - } - } - if (w != atoken.startingWindow) { - if (!atoken.freezingScreen || !w.mAppFreezing) { - atoken.numInterestingWindows++; - if (w.isDrawnLw()) { - atoken.numDrawnWindows++; - if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, - "tokenMayBeDrawn: " + atoken - + " freezingScreen=" + atoken.freezingScreen - + " mAppFreezing=" + w.mAppFreezing); - mInnerFields.mTokenMayBeDrawn = true; - } - } - } else if (w.isDrawnLw()) { - atoken.startingDisplayed = true; - } - } - } else if (w.mReadyToShow) { - w.performShowLocked(); - changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; - } - } // end forall windows - - return changes; - } - - /** - * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method. - * - * @return bitmap indicating if another pass through layout must be made. - */ - private int testTokenMayBeDrawnLocked() { - int changes = 0; - // See if any windows have been drawn, so they (and others - // associated with them) can now be shown. - final int NT = mAppTokens.size(); - for (int i=0; i<NT; i++) { - AppWindowToken wtoken = mAppTokens.get(i); - if (wtoken.freezingScreen) { - int numInteresting = wtoken.numInterestingWindows; - if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) { - if (DEBUG_VISIBILITY) Slog.v(TAG, - "allDrawn: " + wtoken - + " interesting=" + numInteresting - + " drawn=" + wtoken.numDrawnWindows); - wtoken.showAllWindowsLocked(); - unsetAppFreezingScreenLocked(wtoken, false, true); - if (DEBUG_ORIENTATION) Slog.i(TAG, - "Setting mOrientationChangeComplete=true because wtoken " - + wtoken + " numInteresting=" + numInteresting - + " numDrawn=" + wtoken.numDrawnWindows); - mInnerFields.mOrientationChangeComplete = true; - } - } else if (!wtoken.allDrawn) { - int numInteresting = wtoken.numInterestingWindows; - if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) { - if (DEBUG_VISIBILITY) Slog.v(TAG, - "allDrawn: " + wtoken - + " interesting=" + numInteresting - + " drawn=" + wtoken.numDrawnWindows); - wtoken.allDrawn = true; - changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM; - - // We can now show all of the drawn windows! - if (!mOpeningApps.contains(wtoken)) { - mInnerFields.mAnimating |= wtoken.showAllWindowsLocked(); - } - } - } - } - - return changes; - } - - /** - * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method. * * @return bitmap indicating if another pass through layout must be made. */ @@ -8131,7 +7796,7 @@ public class WindowManagerService extends IWindowManager.Stub transit, false); wtoken.updateReportedVisibilityLocked(); wtoken.waitingToShow = false; - mInnerFields.mAnimating |= wtoken.showAllWindowsLocked(); + mAnimator.mAnimating |= wtoken.showAllWindowsLocked(); } NN = mClosingApps.size(); for (i=0; i<NN; i++) { @@ -8229,14 +7894,14 @@ public class WindowManagerService extends IWindowManager.Stub if (mLowerWallpaperTarget == null) { // Whoops, we don't need a special wallpaper animation. // Clear them out. - mInnerFields.mForceHiding = false; + mAnimator.mForceHiding = false; for (int i=mWindows.size()-1; i>=0; i--) { WindowState w = mWindows.get(i); if (w.mSurface != null) { final WindowManager.LayoutParams attrs = w.mAttrs; if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) { if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows"); - mInnerFields.mForceHiding = true; + mAnimator.mForceHiding = true; } else if (mPolicy.canBeForceHidden(w, attrs)) { if (!w.mAnimating) { // We set the animation above so it @@ -8267,11 +7932,11 @@ public class WindowManagerService extends IWindowManager.Stub mInnerFields.mWallpaperMayChange = true; } - if (mInnerFields.mWindowAnimationBackgroundColor != 0) { + if (mAnimator.mWindowAnimationBackgroundColor != 0) { // If the window that wants black is the current wallpaper // target, then the black goes *below* the wallpaper so we // don't cause the wallpaper to suddenly disappear. - WindowState target = mInnerFields.mWindowAnimationBackground; + WindowState target = mAnimator.mWindowAnimationBackground; if (mWallpaperTarget == target || mLowerWallpaperTarget == target || mUpperWallpaperTarget == target) { @@ -8290,7 +7955,7 @@ public class WindowManagerService extends IWindowManager.Stub final int dh = mCurDisplayHeight; mWindowAnimationBackgroundSurface.show(dw, dh, target.mAnimLayer - LAYER_OFFSET_DIM, - mInnerFields.mWindowAnimationBackgroundColor); + mAnimator.mWindowAnimationBackgroundColor); } else if (mWindowAnimationBackgroundSurface != null) { mWindowAnimationBackgroundSurface.hide(); } @@ -8393,206 +8058,6 @@ public class WindowManagerService extends IWindowManager.Stub /** * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method. * - * @param w WindowState whos Surface is being prepared. - * @param recoveringMemory true if the caller will reclaim surface memory on error. - */ - public void prepareSurfaceLocked(final WindowState w, final boolean recoveringMemory) { - // XXX NOTE: The logic here could be improved. We have - // the decision about whether to resize a window separated - // from whether to hide the surface. This can cause us to - // resize a surface even if we are going to hide it. You - // can see this by (1) holding device in landscape mode on - // home screen; (2) tapping browser icon (device will rotate - // to landscape; (3) tap home. The wallpaper will be resized - // in step 2 but then immediately hidden, causing us to - // have to resize and then redraw it again in step 3. It - // would be nice to figure out how to avoid this, but it is - // difficult because we do need to resize surfaces in some - // cases while they are hidden such as when first showing a - // window. - - if (w.mSurface == null) { - if (w.mOrientationChanging) { - if (DEBUG_ORIENTATION) { - Slog.v(TAG, "Orientation change skips hidden " + w); - } - w.mOrientationChanging = false; - } - return; - } - - boolean displayed = false; - - w.computeShownFrameLocked(); - - int width, height; - if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) { - // for a scaled surface, we just want to use - // the requested size. - width = w.mRequestedWidth; - height = w.mRequestedHeight; - } else { - width = w.mCompatFrame.width(); - height = w.mCompatFrame.height(); - } - - if (width < 1) { - width = 1; - } - if (height < 1) { - height = 1; - } - final boolean surfaceResized = w.mSurfaceW != width || w.mSurfaceH != height; - if (surfaceResized) { - w.mSurfaceW = width; - w.mSurfaceH = height; - } - - if (w.mSurfaceX != w.mShownFrame.left - || w.mSurfaceY != w.mShownFrame.top) { - try { - if (SHOW_TRANSACTIONS) logSurface(w, - "POS " + w.mShownFrame.left - + ", " + w.mShownFrame.top, null); - w.mSurfaceX = w.mShownFrame.left; - w.mSurfaceY = w.mShownFrame.top; - w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top); - } catch (RuntimeException e) { - Slog.w(TAG, "Error positioning surface of " + w - + " pos=(" + w.mShownFrame.left - + "," + w.mShownFrame.top + ")", e); - if (!recoveringMemory) { - reclaimSomeSurfaceMemoryLocked(w, "position", true); - } - } - } - - if (surfaceResized) { - try { - if (SHOW_TRANSACTIONS) logSurface(w, - "SIZE " + width + "x" + height, null); - w.mSurfaceResized = true; - w.mSurface.setSize(width, height); - } catch (RuntimeException e) { - // If something goes wrong with the surface (such - // as running out of memory), don't take down the - // entire system. - Slog.e(TAG, "Error resizing surface of " + w - + " size=(" + width + "x" + height + ")", e); - if (!recoveringMemory) { - reclaimSomeSurfaceMemoryLocked(w, "size", true); - } - } - } - - updateResizingWindows(w); - - if (w.mAttachedHidden || !w.isReadyForDisplay()) { - if (!w.mLastHidden) { - //dump(); - w.mLastHidden = true; - if (SHOW_TRANSACTIONS) logSurface(w, - "HIDE (performLayout)", null); - if (w.mSurface != null) { - w.mSurfaceShown = false; - try { - w.mSurface.hide(); - } catch (RuntimeException e) { - Slog.w(TAG, "Exception hiding surface in " + w); - } - } - } - // If we are waiting for this window to handle an - // orientation change, well, it is hidden, so - // doesn't really matter. Note that this does - // introduce a potential glitch if the window - // becomes unhidden before it has drawn for the - // new orientation. - if (w.mOrientationChanging) { - w.mOrientationChanging = false; - if (DEBUG_ORIENTATION) Slog.v(TAG, - "Orientation change skips hidden " + w); - } - } else if (w.mLastLayer != w.mAnimLayer - || w.mLastAlpha != w.mShownAlpha - || w.mLastDsDx != w.mDsDx - || w.mLastDtDx != w.mDtDx - || w.mLastDsDy != w.mDsDy - || w.mLastDtDy != w.mDtDy - || w.mLastHScale != w.mHScale - || w.mLastVScale != w.mVScale - || w.mLastHidden) { - displayed = true; - w.mLastAlpha = w.mShownAlpha; - w.mLastLayer = w.mAnimLayer; - w.mLastDsDx = w.mDsDx; - w.mLastDtDx = w.mDtDx; - w.mLastDsDy = w.mDsDy; - w.mLastDtDy = w.mDtDy; - w.mLastHScale = w.mHScale; - w.mLastVScale = w.mVScale; - if (SHOW_TRANSACTIONS) logSurface(w, - "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer - + " matrix=[" + (w.mDsDx*w.mHScale) - + "," + (w.mDtDx*w.mVScale) - + "][" + (w.mDsDy*w.mHScale) - + "," + (w.mDtDy*w.mVScale) + "]", null); - if (w.mSurface != null) { - try { - w.mSurfaceAlpha = w.mShownAlpha; - w.mSurface.setAlpha(w.mShownAlpha); - w.mSurfaceLayer = w.mAnimLayer; - w.mSurface.setLayer(w.mAnimLayer); - w.mSurface.setMatrix( - w.mDsDx*w.mHScale, w.mDtDx*w.mVScale, - w.mDsDy*w.mHScale, w.mDtDy*w.mVScale); - } catch (RuntimeException e) { - Slog.w(TAG, "Error updating surface in " + w, e); - if (!recoveringMemory) { - reclaimSomeSurfaceMemoryLocked(w, "update", true); - } - } - } - - if (w.mLastHidden && w.isDrawnLw() - && !w.mReadyToShow) { - if (SHOW_TRANSACTIONS) logSurface(w, - "SHOW (performLayout)", null); - if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w - + " during relayout"); - if (showSurfaceRobustlyLocked(w)) { - w.mHasDrawn = true; - w.mLastHidden = false; - } else { - w.mOrientationChanging = false; - } - } - if (w.mSurface != null) { - w.mToken.hasVisible = true; - } - } else { - displayed = true; - } - - if (displayed) { - if (w.mOrientationChanging) { - if (!w.isDrawnLw()) { - mInnerFields.mOrientationChangeComplete = false; - if (DEBUG_ORIENTATION) Slog.v(TAG, - "Orientation continue waiting for draw in " + w); - } else { - w.mOrientationChanging = false; - if (DEBUG_ORIENTATION) Slog.v(TAG, - "Orientation change complete in " + w); - } - } - w.mToken.hasVisible = true; - } - } - - /** - * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method. - * * @param w WindowState this method is applied to. * @param currentTime The time which animations use for calculating transitions. * @param innerDw Width of app window. @@ -8649,65 +8114,6 @@ public class WindowManagerService extends IWindowManager.Stub } } - private final int performAnimationsLocked(long currentTime, int dw, int dh, - int innerDw, int innerDh) { - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq=" - + mTransactionSequence + " mAnimating=" - + mInnerFields.mAnimating); - - mInnerFields.mTokenMayBeDrawn = false; - mInnerFields.mWallpaperMayChange = false; - mInnerFields.mForceHiding = false; - mInnerFields.mDetachedWallpaper = null; - mInnerFields.mWindowAnimationBackground = null; - mInnerFields.mWindowAnimationBackgroundColor = 0; - - int changes = updateWindowsAndWallpaperLocked(currentTime, dw, dh, innerDw, innerDh); - - if (mInnerFields.mTokenMayBeDrawn) { - changes |= testTokenMayBeDrawnLocked(); - } - - // If we are ready to perform an app transition, check through - // all of the app tokens to be shown and see if they are ready - // to go. - if (mAppTransitionReady) { - changes |= handleAppTransitionReadyLocked(); - } - - mInnerFields.mAdjResult = 0; - - if (!mInnerFields.mAnimating && mAppTransitionRunning) { - // We have finished the animation of an app transition. To do - // this, we have delayed a lot of operations like showing and - // hiding apps, moving apps in Z-order, etc. The app token list - // reflects the correct Z-order, but the window list may now - // be out of sync with it. So here we will just rebuild the - // entire app window list. Fun! - changes |= handleAnimatingStoppedAndTransitionLocked(); - } - - if (mInnerFields.mWallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) { - // At this point, there was a window with a wallpaper that - // was force hiding other windows behind it, but now it - // is going away. This may be simple -- just animate - // away the wallpaper and its window -- or it may be - // hard -- the wallpaper now needs to be shown behind - // something that was hidden. - changes |= animateAwayWallpaperLocked(); - } - - changes |= testWallpaperAndBackgroundLocked(); - - if (mLayoutNeeded) { - changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT; - } - - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x" - + Integer.toHexString(changes)); - return changes; - } - // "Something has changed! Let's make it correct now." private final void performLayoutAndPlaceSurfacesLockedInner( boolean recoveringMemory) { @@ -8745,7 +8151,7 @@ public class WindowManagerService extends IWindowManager.Stub mInnerFields.mScreenBrightness = -1; mInnerFields.mButtonBrightness = -1; boolean focusDisplayed = false; - mInnerFields.mAnimating = false; + mAnimator.mAnimating = false; boolean createWatermark = false; if (mFxSession == null) { @@ -8855,9 +8261,53 @@ public class WindowManagerService extends IWindowManager.Stub Surface.closeTransaction(); } + // If we are ready to perform an app transition, check through + // all of the app tokens to be shown and see if they are ready + // to go. + if (mAppTransitionReady) { + mPendingLayoutChanges |= handleAppTransitionReadyLocked(); + } + + mInnerFields.mAdjResult = 0; + + if (!mAnimator.mAnimating && mAppTransitionRunning) { + // We have finished the animation of an app transition. To do + // this, we have delayed a lot of operations like showing and + // hiding apps, moving apps in Z-order, etc. The app token list + // reflects the correct Z-order, but the window list may now + // be out of sync with it. So here we will just rebuild the + // entire app window list. Fun! + mPendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked(); + } + + if (mInnerFields.mWallpaperForceHidingChanged && mPendingLayoutChanges == 0 && + !mAppTransitionReady) { + // At this point, there was a window with a wallpaper that + // was force hiding other windows behind it, but now it + // is going away. This may be simple -- just animate + // away the wallpaper and its window -- or it may be + // hard -- the wallpaper now needs to be shown behind + // something that was hidden. + mPendingLayoutChanges |= animateAwayWallpaperLocked(); + } + + mPendingLayoutChanges |= testWallpaperAndBackgroundLocked(); + + if (mLayoutNeeded) { + mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT; + } + + final int N = mWindows.size(); + for (i=N-1; i>=0; i--) { + WindowState w = mWindows.get(i); + // TODO(cmautner): Can this move up to the loop at the end of try/catch above? + updateResizingWindows(w); + } + // Update animations of all applications, including those // associated with exiting/removed apps - animateAndUpdateSurfaces(currentTime, dw, dh, innerDw, innerDh, recoveringMemory); + mAnimator.animate(); + mPendingLayoutChanges |= mAnimator.mPendingLayoutChanges; if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces"); @@ -8961,7 +8411,7 @@ public class WindowManagerService extends IWindowManager.Stub boolean needRelayout = false; - if (!mInnerFields.mAnimating && mAppTransitionRunning) { + if (!mAnimator.mAnimating && mAppTransitionRunning) { // We have finished the animation of an app transition. To do // this, we have delayed a lot of operations like showing and // hiding apps, moving apps in Z-order, etc. The app token list @@ -8991,7 +8441,7 @@ public class WindowManagerService extends IWindowManager.Stub } if (needRelayout) { requestTraversalLocked(); - } else if (mInnerFields.mAnimating) { + } else if (mAnimator.mAnimating) { scheduleAnimationLocked(); } @@ -9257,6 +8707,7 @@ public class WindowManagerService extends IWindowManager.Stub TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus); final WindowState oldFocus = mCurrentFocus; mCurrentFocus = newFocus; + mAnimator.setCurrentFocus(mCurrentFocus); mLosingFocus.remove(newFocus); int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus); @@ -9397,16 +8848,16 @@ public class WindowManagerService extends IWindowManager.Stub } if (CUSTOM_SCREEN_ROTATION) { - if (mScreenRotationAnimation != null) { - mScreenRotationAnimation.kill(); - mScreenRotationAnimation = null; + if (mAnimator.mScreenRotationAnimation != null) { + mAnimator.mScreenRotationAnimation.kill(); + mAnimator.mScreenRotationAnimation = null; } - if (mScreenRotationAnimation == null) { - mScreenRotationAnimation = new ScreenRotationAnimation(mContext, + if (mAnimator.mScreenRotationAnimation == null) { + mAnimator.mScreenRotationAnimation = new ScreenRotationAnimation(mContext, mFxSession, inTransaction, mCurDisplayWidth, mCurDisplayHeight, mDisplay.getRotation()); } - if (!mScreenRotationAnimation.hasScreenshot()) { + if (!mAnimator.mScreenRotationAnimation.hasScreenshot()) { Surface.freezeDisplay(0); } } else { @@ -9431,20 +8882,20 @@ public class WindowManagerService extends IWindowManager.Stub boolean updateRotation = false; - if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null - && mScreenRotationAnimation.hasScreenshot()) { + if (CUSTOM_SCREEN_ROTATION && mAnimator.mScreenRotationAnimation != null + && mAnimator.mScreenRotationAnimation.hasScreenshot()) { if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation"); - if (mScreenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION, + if (mAnimator.mScreenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION, mTransitionAnimationScale, mCurDisplayWidth, mCurDisplayHeight)) { scheduleAnimationLocked(); } else { - mScreenRotationAnimation = null; + mAnimator.mScreenRotationAnimation = null; updateRotation = true; } } else { - if (mScreenRotationAnimation != null) { - mScreenRotationAnimation.kill(); - mScreenRotationAnimation = null; + if (mAnimator.mScreenRotationAnimation != null) { + mAnimator.mScreenRotationAnimation.kill(); + mAnimator.mScreenRotationAnimation = null; } updateRotation = true; } @@ -9927,9 +9378,9 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(" mLastWindowForcedOrientation"); pw.print(mLastWindowForcedOrientation); pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation); pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount); - if (mScreenRotationAnimation != null) { + if (mAnimator.mScreenRotationAnimation != null) { pw.println(" mScreenRotationAnimation:"); - mScreenRotationAnimation.printTo(" ", pw); + mAnimator.mScreenRotationAnimation.printTo(" ", pw); } pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale); pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale); diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index d1a14df3f520..cf61f7f7412a 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -1227,8 +1227,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { } } - final boolean screenAnimation = mService.mScreenRotationAnimation != null - && mService.mScreenRotationAnimation.isAnimating(); + final boolean screenAnimation = mService.mAnimator.mScreenRotationAnimation != null + && mService.mAnimator.mScreenRotationAnimation.isAnimating(); if (selfTransformation || attachedTransformation != null || appTransformation != null || screenAnimation) { // cache often used attributes locally @@ -1268,7 +1268,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { } if (screenAnimation) { tmpMatrix.postConcat( - mService.mScreenRotationAnimation.getEnterTransformation().getMatrix()); + mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getMatrix()); } // "convert" it into SurfaceFlinger's format @@ -1311,7 +1311,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { } if (screenAnimation) { mShownAlpha *= - mService.mScreenRotationAnimation.getEnterTransformation().getAlpha(); + mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha(); } } else { //Slog.i(TAG, "Not applying alpha transform"); |