WindowAnimator.java revision 918b53bc531f5bd1ea102e8b827d693bd4d0555b
1// Copyright 2012 Google Inc. All Rights Reserved.
2
3package com.android.server.wm;
4
5import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
6import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
7
8import static com.android.server.wm.WindowManagerService.LayoutFields.SET_UPDATE_ROTATION;
9import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_MAY_CHANGE;
10import static com.android.server.wm.WindowManagerService.LayoutFields.SET_FORCE_HIDING_CHANGED;
11import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
12
13import static com.android.server.wm.WindowManagerService.H.UPDATE_ANIM_PARAMETERS;
14
15import android.content.Context;
16import android.os.SystemClock;
17import android.util.Log;
18import android.util.Slog;
19import android.view.Surface;
20import android.view.WindowManagerPolicy;
21import android.view.animation.Animation;
22
23import com.android.internal.policy.impl.PhoneWindowManager;
24import com.android.server.wm.WindowManagerService.LayoutToAnimatorParams;
25
26import java.io.PrintWriter;
27import java.util.ArrayList;
28
29/**
30 * Singleton class that carries out the animations and Surface operations in a separate task
31 * on behalf of WindowManagerService.
32 */
33public class WindowAnimator {
34    private static final String TAG = "WindowAnimator";
35
36    final WindowManagerService mService;
37    final Context mContext;
38    final WindowManagerPolicy mPolicy;
39
40    ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>();
41
42    boolean mAnimating;
43
44    final Runnable mAnimationRunnable;
45
46    int mAdjResult;
47
48    int mPendingLayoutChanges;
49
50    /** Overall window dimensions */
51    int mDw, mDh;
52
53    /** Interior window dimensions */
54    int mInnerDw, mInnerDh;
55
56    /** Time of current animation step. Reset on each iteration */
57    long mCurrentTime;
58
59    /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
60     * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
61    private int mAnimTransactionSequence;
62
63    /** The one and only screen rotation if one is happening */
64    ScreenRotationAnimation mScreenRotationAnimation = null;
65
66    // Window currently running an animation that has requested it be detached
67    // from the wallpaper.  This means we need to ensure the wallpaper is
68    // visible behind it in case it animates in a way that would allow it to be
69    // seen. If multiple windows satisfy this, use the lowest window.
70    WindowState mWindowDetachedWallpaper = null;
71
72    DimSurface mWindowAnimationBackgroundSurface = null;
73
74    WindowStateAnimator mUniverseBackground = null;
75    int mAboveUniverseLayer = 0;
76
77    int mBulkUpdateParams = 0;
78
79    DimAnimator mDimAnimator = null;
80    DimAnimator.Parameters mDimParams = null;
81
82    static final int WALLPAPER_ACTION_PENDING = 1;
83    int mPendingActions;
84
85    WindowState mWallpaperTarget = null;
86    AppWindowAnimator mWpAppAnimator = null;
87    WindowState mLowerWallpaperTarget = null;
88    WindowState mUpperWallpaperTarget = null;
89
90    ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
91
92    /** Parameters being passed from this into mService. */
93    static class AnimatorToLayoutParams {
94        boolean mUpdateQueued;
95        int mBulkUpdateParams;
96        int mPendingLayoutChanges;
97        WindowState mWindowDetachedWallpaper;
98    }
99    /** Do not modify unless holding mService.mWindowMap or this and mAnimToLayout in that order */
100    final AnimatorToLayoutParams mAnimToLayout = new AnimatorToLayoutParams();
101
102    WindowAnimator(final WindowManagerService service) {
103        mService = service;
104        mContext = service.mContext;
105        mPolicy = service.mPolicy;
106
107        mAnimationRunnable = new Runnable() {
108            @Override
109            public void run() {
110                // TODO(cmautner): When full isolation is achieved for animation, the first lock
111                // goes away and only the WindowAnimator.this remains.
112                synchronized(mService.mWindowMap) {
113                    synchronized(WindowAnimator.this) {
114                        copyLayoutToAnimParamsLocked();
115                        animateLocked();
116                    }
117                }
118            }
119        };
120
121        mWindowAnimationBackgroundSurface = new DimSurface(mService.mFxSession);
122        mDimAnimator = new DimAnimator(mService.mFxSession);
123    }
124
125    /** Locked on mAnimToLayout */
126    void updateAnimToLayoutLocked() {
127        final AnimatorToLayoutParams animToLayout = mAnimToLayout;
128        synchronized (animToLayout) {
129            animToLayout.mBulkUpdateParams = mBulkUpdateParams;
130            animToLayout.mPendingLayoutChanges = mPendingLayoutChanges;
131            animToLayout.mWindowDetachedWallpaper = mWindowDetachedWallpaper;
132
133            if (!animToLayout.mUpdateQueued) {
134                animToLayout.mUpdateQueued = true;
135                mService.mH.sendMessage(mService.mH.obtainMessage(UPDATE_ANIM_PARAMETERS));
136            }
137        }
138    }
139
140    /** Copy all WindowManagerService params into local params here. Locked on 'this'. */
141    private void copyLayoutToAnimParamsLocked() {
142        final LayoutToAnimatorParams layoutToAnim = mService.mLayoutToAnim;
143        synchronized(layoutToAnim) {
144            layoutToAnim.mAnimationScheduled = false;
145
146            if ((layoutToAnim.mChanges & LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED) != 0) {
147                layoutToAnim.mChanges &= ~LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED;
148                mWallpaperTokens = new ArrayList<WindowToken>(layoutToAnim.mWallpaperTokens);
149            }
150
151            mWinAnimators = new ArrayList<WindowStateAnimator>(layoutToAnim.mWinAnimators);
152            mWallpaperTarget = layoutToAnim.mWallpaperTarget;
153            mWpAppAnimator = mWallpaperTarget == null
154                    ? null : mWallpaperTarget.mAppToken == null
155                            ? null : mWallpaperTarget.mAppToken.mAppAnimator;
156            mLowerWallpaperTarget = layoutToAnim.mLowerWallpaperTarget;
157            mUpperWallpaperTarget = layoutToAnim.mUpperWallpaperTarget;
158
159            // Set the new DimAnimator params.
160            DimAnimator.Parameters dimParams = layoutToAnim.mDimParams;
161            if (dimParams == null) {
162                mDimParams = dimParams;
163            } else {
164                final WindowStateAnimator newWinAnimator = dimParams.mDimWinAnimator;
165
166                // Only set dim params on the highest dimmed layer.
167                final WindowStateAnimator existingDimWinAnimator = mDimParams == null
168                        ? null : mDimParams.mDimWinAnimator;
169                // Don't turn on for an unshown surface, or for any layer but the highest dimmed one.
170                if (newWinAnimator.mSurfaceShown &&
171                        (existingDimWinAnimator == null || !existingDimWinAnimator.mSurfaceShown
172                        || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
173                    mDimParams = dimParams;
174                }
175            }
176        }
177    }
178
179    void hideWallpapersLocked(final WindowState w) {
180        if ((mWallpaperTarget == w && mLowerWallpaperTarget == null) || mWallpaperTarget == null) {
181            final int numTokens = mWallpaperTokens.size();
182            for (int i = numTokens - 1; i >= 0; i--) {
183                final WindowToken token = mWallpaperTokens.get(i);
184                final int numWindows = token.windows.size();
185                for (int j = numWindows - 1; j >= 0; j--) {
186                    final WindowState wallpaper = token.windows.get(j);
187                    final WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
188                    if (!winAnimator.mLastHidden) {
189                        winAnimator.hide();
190                        mService.dispatchWallpaperVisibility(wallpaper, false);
191                        mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
192                    }
193                }
194                token.hidden = true;
195            }
196        }
197    }
198
199    private void updateWindowsAppsAndRotationAnimationsLocked() {
200        final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens;
201        int i;
202        final int NAT = appTokens.size();
203        for (i=0; i<NAT; i++) {
204            final AppWindowAnimator appAnimator = appTokens.get(i).mAppAnimator;
205            final boolean wasAnimating = appAnimator.animation != null
206                    && appAnimator.animation != AppWindowAnimator.sDummyAnimation;
207            if (appAnimator.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) {
208                mAnimating = true;
209            } else if (wasAnimating) {
210                // stopped animating, do one more pass through the layout
211                mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
212                if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
213                    mService.debugLayoutRepeats("appToken " + appAnimator.mAppToken + " done",
214                        mPendingLayoutChanges);
215                }
216                if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
217                        "updateWindowsApps...: done animating " + appAnimator.mAppToken);
218            }
219        }
220
221        final int NEAT = mService.mExitingAppTokens.size();
222        for (i=0; i<NEAT; i++) {
223            final AppWindowAnimator appAnimator = mService.mExitingAppTokens.get(i).mAppAnimator;
224            final boolean wasAnimating = appAnimator.animation != null
225                    && appAnimator.animation != AppWindowAnimator.sDummyAnimation;
226            if (appAnimator.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) {
227                mAnimating = true;
228            } else if (wasAnimating) {
229                // stopped animating, do one more pass through the layout
230                mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
231                if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
232                    mService.debugLayoutRepeats("exiting appToken " + appAnimator.mAppToken
233                        + " done", mPendingLayoutChanges);
234                }
235                if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
236                        "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken);
237            }
238        }
239
240        if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) {
241            if (mScreenRotationAnimation.stepAnimationLocked(mCurrentTime)) {
242                mAnimating = true;
243            } else {
244                mBulkUpdateParams |= SET_UPDATE_ROTATION;
245                mScreenRotationAnimation.kill();
246                mScreenRotationAnimation = null;
247            }
248        }
249    }
250
251    private void updateWindowsLocked() {
252        ++mAnimTransactionSequence;
253
254        ArrayList<WindowStateAnimator> unForceHiding = null;
255        boolean wallpaperInUnForceHiding = false;
256
257        boolean forceHiding = false;
258        for (int i = mWinAnimators.size() - 1; i >= 0; i--) {
259            WindowStateAnimator winAnimator = mWinAnimators.get(i);
260            WindowState win = winAnimator.mWin;
261            final int flags = winAnimator.mAttrFlags;
262
263            if (winAnimator.mSurface != null) {
264                final boolean wasAnimating = winAnimator.mWasAnimating;
265                final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime);
266
267                if (WindowManagerService.DEBUG_WALLPAPER) {
268                    Slog.v(TAG, win + ": wasAnimating=" + wasAnimating +
269                            ", nowAnimating=" + nowAnimating);
270                }
271
272                if (wasAnimating && !winAnimator.mAnimating && mWallpaperTarget == win) {
273                    mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
274                    mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
275                    if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
276                        mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 2",
277                            mPendingLayoutChanges);
278                    }
279                }
280
281                if (mPolicy.doesForceHide(win, win.mAttrs)) {
282                    if (!wasAnimating && nowAnimating) {
283                        if (WindowManagerService.DEBUG_ANIM ||
284                                WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
285                                "Animation started that could impact force hide: " + win);
286                        mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED;
287                        mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
288                        if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
289                            mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 3",
290                                mPendingLayoutChanges);
291                        }
292                        mService.mFocusMayChange = true;
293                    }
294                    if (win.isReadyForDisplay() && winAnimator.mAnimationIsEntrance) {
295                        forceHiding = true;
296                    }
297                    if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
298                            "Force hide " + forceHiding
299                            + " hasSurface=" + win.mHasSurface
300                            + " policyVis=" + win.mPolicyVisibility
301                            + " destroying=" + win.mDestroying
302                            + " attHidden=" + win.mAttachedHidden
303                            + " vis=" + win.mViewVisibility
304                            + " hidden=" + win.mRootToken.hidden
305                            + " anim=" + win.mWinAnimator.mAnimation);
306                } else if (mPolicy.canBeForceHidden(win, win.mAttrs)) {
307                    final boolean changed;
308                    if (forceHiding && (!winAnimator.isAnimating()
309                            || (winAnimator.mAttrFlags & FLAG_SHOW_WHEN_LOCKED) == 0)) {
310                        changed = win.hideLw(false, false);
311                        if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG,
312                                "Now policy hidden: " + win);
313                    } else {
314                        changed = win.showLw(false, false);
315                        if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG,
316                                "Now policy shown: " + win);
317                        if (changed) {
318                            if ((mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0
319                                    && win.isVisibleNow() /*w.isReadyForDisplay()*/) {
320                                if (unForceHiding == null) {
321                                    unForceHiding = new ArrayList<WindowStateAnimator>();
322                                }
323                                unForceHiding.add(winAnimator);
324                                if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
325                                    wallpaperInUnForceHiding = true;
326                                }
327                            }
328                            if (mCurrentFocus == null || mCurrentFocus.mLayer < win.mLayer) {
329                                // We are showing on to of the current
330                                // focus, so re-evaluate focus to make
331                                // sure it is correct.
332                                mService.mFocusMayChange = true;
333                            }
334                        }
335                    }
336                    if (changed && (flags & FLAG_SHOW_WALLPAPER) != 0) {
337                        mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
338                        mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
339                        if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
340                            mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 4",
341                                mPendingLayoutChanges);
342                        }
343                    }
344                }
345            }
346
347            final AppWindowToken atoken = win.mAppToken;
348            if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) {
349                if (atoken == null || atoken.allDrawn) {
350                    if (winAnimator.performShowLocked()) {
351                        mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
352                        if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
353                            mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5",
354                                mPendingLayoutChanges);
355                        }
356                    }
357                }
358            }
359            final AppWindowAnimator appAnimator =
360                    atoken == null ? null : atoken.mAppAnimator;
361            if (appAnimator != null && appAnimator.thumbnail != null) {
362                if (appAnimator.thumbnailTransactionSeq != mAnimTransactionSequence) {
363                    appAnimator.thumbnailTransactionSeq = mAnimTransactionSequence;
364                    appAnimator.thumbnailLayer = 0;
365                }
366                if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) {
367                    appAnimator.thumbnailLayer = winAnimator.mAnimLayer;
368                }
369            }
370        } // end forall windows
371
372        // If we have windows that are being show due to them no longer
373        // being force-hidden, apply the appropriate animation to them.
374        if (unForceHiding != null) {
375            for (int i=unForceHiding.size()-1; i>=0; i--) {
376                Animation a = mPolicy.createForceHideEnterAnimation(wallpaperInUnForceHiding);
377                if (a != null) {
378                    final WindowStateAnimator winAnimator = unForceHiding.get(i);
379                    winAnimator.setAnimation(a);
380                    winAnimator.mAnimationIsEntrance = true;
381                }
382            }
383        }
384    }
385
386    private void updateWallpaperLocked() {
387        WindowStateAnimator windowAnimationBackground = null;
388        int windowAnimationBackgroundColor = 0;
389        WindowState detachedWallpaper = null;
390
391        for (int i = mWinAnimators.size() - 1; i >= 0; i--) {
392            WindowStateAnimator winAnimator = mWinAnimators.get(i);
393            if (winAnimator.mSurface == null) {
394                continue;
395            }
396
397            final int flags = winAnimator.mAttrFlags;
398            final WindowState win = winAnimator.mWin;
399
400            // If this window is animating, make a note that we have
401            // an animating window and take care of a request to run
402            // a detached wallpaper animation.
403            if (winAnimator.mAnimating) {
404                if (winAnimator.mAnimation != null) {
405                    if ((flags & FLAG_SHOW_WALLPAPER) != 0
406                            && winAnimator.mAnimation.getDetachWallpaper()) {
407                        detachedWallpaper = win;
408                    }
409                    final int backgroundColor = winAnimator.mAnimation.getBackgroundColor();
410                    if (backgroundColor != 0) {
411                        if (windowAnimationBackground == null || (winAnimator.mAnimLayer <
412                                windowAnimationBackground.mAnimLayer)) {
413                            windowAnimationBackground = winAnimator;
414                            windowAnimationBackgroundColor = backgroundColor;
415                        }
416                    }
417                }
418                mAnimating = true;
419            }
420
421            // If this window's app token is running a detached wallpaper
422            // animation, make a note so we can ensure the wallpaper is
423            // displayed behind it.
424            final AppWindowAnimator appAnimator =
425                    win.mAppToken == null ? null : win.mAppToken.mAppAnimator;
426            if (appAnimator != null && appAnimator.animation != null
427                    && appAnimator.animating) {
428                if ((flags & FLAG_SHOW_WALLPAPER) != 0
429                        && appAnimator.animation.getDetachWallpaper()) {
430                    detachedWallpaper = win;
431                }
432
433                final int backgroundColor = appAnimator.animation.getBackgroundColor();
434                if (backgroundColor != 0) {
435                    if (windowAnimationBackground == null || (winAnimator.mAnimLayer <
436                            windowAnimationBackground.mAnimLayer)) {
437                        windowAnimationBackground = winAnimator;
438                        windowAnimationBackgroundColor = backgroundColor;
439                    }
440                }
441            }
442        } // end forall windows
443
444        if (mWindowDetachedWallpaper != detachedWallpaper) {
445            if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG,
446                    "Detached wallpaper changed from " + mWindowDetachedWallpaper
447                    + " to " + detachedWallpaper);
448            mWindowDetachedWallpaper = detachedWallpaper;
449            mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
450        }
451
452        if (windowAnimationBackgroundColor != 0) {
453            // If the window that wants black is the current wallpaper
454            // target, then the black goes *below* the wallpaper so we
455            // don't cause the wallpaper to suddenly disappear.
456            int animLayer = windowAnimationBackground.mAnimLayer;
457            WindowState win = windowAnimationBackground.mWin;
458            if (windowAnimationBackground != null && mWallpaperTarget == win
459                    || mLowerWallpaperTarget == win || mUpperWallpaperTarget == win) {
460                final int N = mWinAnimators.size();
461                for (int i = 0; i < N; i++) {
462                    WindowStateAnimator winAnimator = mWinAnimators.get(i);
463                    if (winAnimator.mIsWallpaper) {
464                        animLayer = winAnimator.mAnimLayer;
465                        break;
466                    }
467                }
468            }
469
470            mWindowAnimationBackgroundSurface.show(mDw, mDh,
471                    animLayer - WindowManagerService.LAYER_OFFSET_DIM,
472                    windowAnimationBackgroundColor);
473        } else {
474            mWindowAnimationBackgroundSurface.hide();
475        }
476    }
477
478    private void testTokenMayBeDrawnLocked() {
479        // See if any windows have been drawn, so they (and others
480        // associated with them) can now be shown.
481        final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens;
482        final int NT = appTokens.size();
483        for (int i=0; i<NT; i++) {
484            AppWindowToken wtoken = appTokens.get(i);
485            final boolean allDrawn = wtoken.allDrawn;
486            if (allDrawn != wtoken.mAppAnimator.allDrawn) {
487                wtoken.mAppAnimator.allDrawn = allDrawn;
488                if (allDrawn) {
489                    // The token has now changed state to having all
490                    // windows shown...  what to do, what to do?
491                    if (wtoken.mAppAnimator.freezingScreen) {
492                        wtoken.mAppAnimator.showAllWindowsLocked();
493                        mService.unsetAppFreezingScreenLocked(wtoken, false, true);
494                        if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG,
495                                "Setting mOrientationChangeComplete=true because wtoken "
496                                + wtoken + " numInteresting=" + wtoken.numInterestingWindows
497                                + " numDrawn=" + wtoken.numDrawnWindows);
498                        // This will set mOrientationChangeComplete and cause a pass through layout.
499                        mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
500                    } else {
501                        mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
502                        if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
503                            mService.debugLayoutRepeats("testTokenMayBeDrawnLocked",
504                                mPendingLayoutChanges);
505                        }
506
507                        // We can now show all of the drawn windows!
508                        if (!mService.mOpeningApps.contains(wtoken)) {
509                            mAnimating |= wtoken.mAppAnimator.showAllWindowsLocked();
510                        }
511                    }
512                }
513            }
514        }
515    }
516
517    private void performAnimationsLocked() {
518        updateWindowsLocked();
519        updateWallpaperLocked();
520
521        if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
522            mPendingActions |= WALLPAPER_ACTION_PENDING;
523        }
524
525        testTokenMayBeDrawnLocked();
526    }
527
528    // TODO(cmautner): Change the following comment when no longer locked on mWindowMap */
529    /** Locked on mService.mWindowMap and this. */
530    private void animateLocked() {
531        mPendingLayoutChanges = 0;
532        mCurrentTime = SystemClock.uptimeMillis();
533        mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
534        boolean wasAnimating = mAnimating;
535        mAnimating = false;
536        if (WindowManagerService.DEBUG_WINDOW_TRACE) {
537            Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
538        }
539
540        // Update animations of all applications, including those
541        // associated with exiting/removed apps
542        Surface.openTransaction();
543
544        try {
545            updateWindowsAppsAndRotationAnimationsLocked();
546            performAnimationsLocked();
547
548            // THIRD LOOP: Update the surfaces of all windows.
549
550            if (mScreenRotationAnimation != null) {
551                mScreenRotationAnimation.updateSurfaces();
552            }
553
554            final int N = mWinAnimators.size();
555            for (int i = 0; i < N; i++) {
556                mWinAnimators.get(i).prepareSurfaceLocked(true);
557            }
558
559            if (mDimParams != null) {
560                mDimAnimator.updateParameters(mContext.getResources(), mDimParams, mCurrentTime);
561            }
562            if (mDimAnimator != null && mDimAnimator.mDimShown) {
563                mAnimating |= mDimAnimator.updateSurface(isDimming(), mCurrentTime,
564                        !mService.okToDisplay());
565            }
566
567            if (mService.mBlackFrame != null) {
568                if (mScreenRotationAnimation != null) {
569                    mService.mBlackFrame.setMatrix(
570                            mScreenRotationAnimation.getEnterTransformation().getMatrix());
571                } else {
572                    mService.mBlackFrame.clearMatrix();
573                }
574            }
575
576            if (mService.mWatermark != null) {
577                mService.mWatermark.drawIfNeeded();
578            }
579        } catch (RuntimeException e) {
580            Log.wtf(TAG, "Unhandled exception in Window Manager", e);
581        } finally {
582            Surface.closeTransaction();
583        }
584
585        if (mBulkUpdateParams != 0 || mPendingLayoutChanges != 0) {
586            updateAnimToLayoutLocked();
587        }
588
589        if (mAnimating) {
590            synchronized (mService.mLayoutToAnim) {
591                mService.scheduleAnimationLocked();
592            }
593        } else if (wasAnimating) {
594            mService.requestTraversalLocked();
595        }
596        if (WindowManagerService.DEBUG_WINDOW_TRACE) {
597            Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating
598                + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams)
599                + " mPendingLayoutChanges=" + Integer.toHexString(mPendingLayoutChanges));
600        }
601    }
602
603    WindowState mCurrentFocus;
604    void setCurrentFocus(final WindowState currentFocus) {
605        mCurrentFocus = currentFocus;
606    }
607
608    void setDisplayDimensions(final int curWidth, final int curHeight,
609                        final int appWidth, final int appHeight) {
610        mDw = curWidth;
611        mDh = curHeight;
612        mInnerDw = appWidth;
613        mInnerDh = appHeight;
614    }
615
616    boolean isDimming() {
617        return mDimParams != null;
618    }
619
620    boolean isDimming(final WindowStateAnimator winAnimator) {
621        return mDimParams != null && mDimParams.mDimWinAnimator == winAnimator;
622    }
623
624    public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
625        if (dumpAll) {
626            if (mWindowDetachedWallpaper != null) {
627                pw.print(prefix); pw.print("mWindowDetachedWallpaper=");
628                        pw.println(mWindowDetachedWallpaper);
629            }
630            pw.print(prefix); pw.print("mAnimTransactionSequence=");
631                    pw.println(mAnimTransactionSequence);
632            if (mWindowAnimationBackgroundSurface != null) {
633                pw.print(prefix); pw.print("mWindowAnimationBackgroundSurface:");
634                        mWindowAnimationBackgroundSurface.printTo(prefix + "  ", pw);
635            }
636            if (mDimAnimator != null) {
637                pw.print(prefix); pw.print("mDimAnimator:");
638                mDimAnimator.printTo(prefix + "  ", pw);
639            } else {
640                pw.print(prefix); pw.print("no DimAnimator ");
641            }
642        }
643    }
644
645    static class SetAnimationParams {
646        final WindowStateAnimator mWinAnimator;
647        final Animation mAnimation;
648        final int mAnimDw;
649        final int mAnimDh;
650        public SetAnimationParams(final WindowStateAnimator winAnimator,
651                                  final Animation animation, final int animDw, final int animDh) {
652            mWinAnimator = winAnimator;
653            mAnimation = animation;
654            mAnimDw = animDw;
655            mAnimDh = animDh;
656        }
657    }
658
659    synchronized void clearPendingActions() {
660        mPendingActions = 0;
661    }
662}
663