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