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