1c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner/*
2c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * Copyright (C) 2014 The Android Open Source Project
3c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner *
4c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * Licensed under the Apache License, Version 2.0 (the "License");
5c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * you may not use this file except in compliance with the License.
6c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * You may obtain a copy of the License at
7c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner *
8c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner *      http://www.apache.org/licenses/LICENSE-2.0
9c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner *
10c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * Unless required by applicable law or agreed to in writing, software
11c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * distributed under the License is distributed on an "AS IS" BASIS,
12c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * See the License for the specific language governing permissions and
14c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * limitations under the License.
15c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner */
16594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
17594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautnerpackage com.android.server.wm;
18594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
198ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwaleimport static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
208ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwaleimport static com.android.server.wm.WindowManagerService.DEBUG_LAYERS;
218ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwaleimport static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
228ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwaleimport static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
238ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale
24594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautnerimport android.graphics.Matrix;
25594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautnerimport android.util.Slog;
26a57c695bf2c0f917517ecac8251043716b34f72dDianne Hackbornimport android.util.TimeUtils;
27c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggiimport android.view.Choreographer;
28a91f9e2959ee905f97977a88fe45bde6ffb874b0Craig Mautnerimport android.view.Display;
293866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport android.view.SurfaceControl;
30594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautnerimport android.view.WindowManagerPolicy;
31594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautnerimport android.view.animation.Animation;
32594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautnerimport android.view.animation.Transformation;
33594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
34594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautnerimport java.io.PrintWriter;
35322e40315609acd5a608440bc469d873e09559caCraig Mautnerimport java.util.ArrayList;
36594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
37594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautnerpublic class AppWindowAnimator {
38fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner    static final String TAG = "AppWindowAnimator";
39594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
40594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    final AppWindowToken mAppToken;
41594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    final WindowManagerService mService;
42594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    final WindowAnimator mAnimator;
43594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
44594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    boolean animating;
45827e0facfefd0c0033dcfb1747b4fa6f80f9e0e2Jorim Jaggi    boolean wasAnimating;
46594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    Animation animation;
47594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    boolean hasTransformation;
48594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    final Transformation transformation = new Transformation();
49594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
50594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    // Have we been asked to have this token keep the screen frozen?
51594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    // Protect with mAnimator.
52594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    boolean freezingScreen;
53594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
54a57c695bf2c0f917517ecac8251043716b34f72dDianne Hackborn    /**
55a57c695bf2c0f917517ecac8251043716b34f72dDianne Hackborn     * How long we last kept the screen frozen.
56a57c695bf2c0f917517ecac8251043716b34f72dDianne Hackborn     */
57a57c695bf2c0f917517ecac8251043716b34f72dDianne Hackborn    int lastFreezeDuration;
58a57c695bf2c0f917517ecac8251043716b34f72dDianne Hackborn
59594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    // Offset to the window of all layers in the token, for use by
60594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    // AppWindowToken animations.
61594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    int animLayerAdjustment;
62594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
636fbda63e68513ece4409dac845588711ab25c39dCraig Mautner    // Propagated from AppWindowToken.allDrawn, to determine when
646fbda63e68513ece4409dac845588711ab25c39dCraig Mautner    // the state changes.
656fbda63e68513ece4409dac845588711ab25c39dCraig Mautner    boolean allDrawn;
666fbda63e68513ece4409dac845588711ab25c39dCraig Mautner
67ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung    // Special surface for thumbnail animation.  If deferThumbnailDestruction is enabled, then we
68ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung    // will make sure that the thumbnail is destroyed after the other surface is completed.  This
69ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung    // requires that the duration of the two animations are the same.
703866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    SurfaceControl thumbnail;
71594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    int thumbnailTransactionSeq;
72594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    int thumbnailX;
73594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    int thumbnailY;
74594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    int thumbnailLayer;
75a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    int thumbnailForceAboveLayer;
76594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    Animation thumbnailAnimation;
77594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    final Transformation thumbnailTransformation = new Transformation();
78a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    // This flag indicates that the destruction of the thumbnail surface is synchronized with
79ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung    // another animation, so defer the destruction of this thumbnail surface for a single frame
80ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung    // after the secondary animation completes.
81a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    boolean deferThumbnailDestruction;
82ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung    // This flag is set if the animator has deferThumbnailDestruction set and has reached the final
83ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung    // frame of animation.  It will extend the animation by one frame and then clean up afterwards.
84ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung    boolean deferFinalFrameCleanup;
85594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
86322e40315609acd5a608440bc469d873e09559caCraig Mautner    /** WindowStateAnimator from mAppAnimator.allAppWindows as of last performLayout */
878ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale    ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<>();
888ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale
898ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale    /** True if the current animation was transferred from another AppWindowAnimator.
908ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale     *  See {@link #transferCurrentAnimation}*/
918ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale    boolean usingTransferredAnimation = false;
92322e40315609acd5a608440bc469d873e09559caCraig Mautner
93c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi    private boolean mSkipFirstFrame = false;
94c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi
95fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner    static final Animation sDummyAnimation = new DummyAnimation();
96fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner
97322e40315609acd5a608440bc469d873e09559caCraig Mautner    public AppWindowAnimator(final AppWindowToken atoken) {
98594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        mAppToken = atoken;
99322e40315609acd5a608440bc469d873e09559caCraig Mautner        mService = atoken.service;
100322e40315609acd5a608440bc469d873e09559caCraig Mautner        mAnimator = atoken.mAnimator;
101594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    }
102594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
103c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi    public void setAnimation(Animation anim, int width, int height, boolean skipFirstFrame) {
10472669d18016446d874e4fa1005464e36375124e4Craig Mautner        if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting animation in " + mAppToken
10572669d18016446d874e4fa1005464e36375124e4Craig Mautner                + ": " + anim + " wxh=" + width + "x" + height
10672669d18016446d874e4fa1005464e36375124e4Craig Mautner                + " isVisible=" + mAppToken.isVisible());
107594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        animation = anim;
108594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        animating = false;
1099339c401cf1a056a3a1caddc648334069e6bd267Craig Mautner        if (!anim.isInitialized()) {
1109339c401cf1a056a3a1caddc648334069e6bd267Craig Mautner            anim.initialize(width, height, width, height);
1119339c401cf1a056a3a1caddc648334069e6bd267Craig Mautner        }
112594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        anim.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
113eb94fa7975b1e8742f3b00cec6bd4f9d6b329e3aDianne Hackborn        anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
114594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        int zorder = anim.getZAdjustment();
115594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        int adj = 0;
116594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        if (zorder == Animation.ZORDER_TOP) {
1178ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            adj = TYPE_LAYER_OFFSET;
118594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        } else if (zorder == Animation.ZORDER_BOTTOM) {
1198ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            adj = -TYPE_LAYER_OFFSET;
120594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
121594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
122594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        if (animLayerAdjustment != adj) {
123594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            animLayerAdjustment = adj;
124594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            updateLayers();
125594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
126594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        // Start out animation gone if window is gone, or visible if window is visible.
127594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        transformation.clear();
12872669d18016446d874e4fa1005464e36375124e4Craig Mautner        transformation.setAlpha(mAppToken.isVisible() ? 1 : 0);
129594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        hasTransformation = true;
1301ad99155b37c0cb0b7d95f084a2bff0cbfc8e12dCraig Mautner
131c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi        this.mSkipFirstFrame = skipFirstFrame;
132c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi
1331ad99155b37c0cb0b7d95f084a2bff0cbfc8e12dCraig Mautner        if (!mAppToken.appFullscreen) {
1341ad99155b37c0cb0b7d95f084a2bff0cbfc8e12dCraig Mautner            anim.setBackgroundColor(0);
1351ad99155b37c0cb0b7d95f084a2bff0cbfc8e12dCraig Mautner        }
136594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    }
137594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
138594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    public void setDummyAnimation() {
13972669d18016446d874e4fa1005464e36375124e4Craig Mautner        if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting dummy animation in " + mAppToken
14072669d18016446d874e4fa1005464e36375124e4Craig Mautner                + " isVisible=" + mAppToken.isVisible());
1411d961d46d68eb3134e4bd6c3751f9730e9d32f17Craig Mautner        animation = sDummyAnimation;
14294ef9df22c5960b74359e1a98e5c210787d382f2Craig Mautner        hasTransformation = true;
14394ef9df22c5960b74359e1a98e5c210787d382f2Craig Mautner        transformation.clear();
14472669d18016446d874e4fa1005464e36375124e4Craig Mautner        transformation.setAlpha(mAppToken.isVisible() ? 1 : 0);
145594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    }
146594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
147594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    public void clearAnimation() {
148594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        if (animation != null) {
149594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            animation = null;
150594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            animating = true;
151594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
152ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung        clearThumbnail();
1537636dfbc3331dec0cea374a9540a1f31fb7dbf77Craig Mautner        if (mAppToken.deferClearAllDrawn) {
1547636dfbc3331dec0cea374a9540a1f31fb7dbf77Craig Mautner            mAppToken.allDrawn = false;
1557636dfbc3331dec0cea374a9540a1f31fb7dbf77Craig Mautner            mAppToken.deferClearAllDrawn = false;
1567636dfbc3331dec0cea374a9540a1f31fb7dbf77Craig Mautner        }
1578ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale        usingTransferredAnimation = false;
158594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    }
159594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
160378756154fce86b53e91746583bfe15996ef680bJorim Jaggi    public boolean isAnimating() {
161378756154fce86b53e91746583bfe15996ef680bJorim Jaggi        return animation != null || mAppToken.inPendingTransaction;
162378756154fce86b53e91746583bfe15996ef680bJorim Jaggi    }
163378756154fce86b53e91746583bfe15996ef680bJorim Jaggi
164594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    public void clearThumbnail() {
165594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        if (thumbnail != null) {
166594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            thumbnail.destroy();
167594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            thumbnail = null;
168594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
169ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung        deferThumbnailDestruction = false;
170a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    }
171a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung
1728ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale    void transferCurrentAnimation(
1738ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            AppWindowAnimator toAppAnimator, WindowStateAnimator transferWinAnimator) {
1748ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale
1758ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale        if (animation != null) {
1768ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            toAppAnimator.animation = animation;
1778ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            animation = null;
1788ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            toAppAnimator.animating = animating;
1798ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            toAppAnimator.animLayerAdjustment = animLayerAdjustment;
1808ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            animLayerAdjustment = 0;
1818ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            toAppAnimator.updateLayers();
1828ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            updateLayers();
1838ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            toAppAnimator.usingTransferredAnimation = true;
1848ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale        }
1858ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale        if (transferWinAnimator != null) {
1868ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            mAllAppWinAnimators.remove(transferWinAnimator);
1878ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            toAppAnimator.mAllAppWinAnimators.add(transferWinAnimator);
1888ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            transferWinAnimator.mAppAnimator = toAppAnimator;
1898ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale        }
1908ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale    }
1918ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale
192594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    void updateLayers() {
1938ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale        final int windowCount = mAppToken.allAppWindows.size();
194594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        final int adj = animLayerAdjustment;
195594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        thumbnailLayer = -1;
1968ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale        for (int i = 0; i < windowCount; i++) {
197594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            final WindowState w = mAppToken.allAppWindows.get(i);
198594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            final WindowStateAnimator winAnimator = w.mWinAnimator;
199594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            winAnimator.mAnimLayer = w.mLayer + adj;
200594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            if (winAnimator.mAnimLayer > thumbnailLayer) {
201594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                thumbnailLayer = winAnimator.mAnimLayer;
202594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            }
2038ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": " + winAnimator.mAnimLayer);
204594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
205594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                mService.setInputMethodAnimLayerAdjustment(adj);
206594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            }
207968683335e17c06504a11bc2e38a2580f613ea16Craig Mautner            if (w == mService.mWallpaperTarget && mService.mLowerWallpaperTarget == null) {
208594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                mService.setWallpaperAnimLayerAdjustmentLocked(adj);
209594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            }
210594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
211594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    }
212594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
213594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    private void stepThumbnailAnimation(long currentTime) {
214594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        thumbnailTransformation.clear();
215594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        thumbnailAnimation.getTransformation(currentTime, thumbnailTransformation);
216594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        thumbnailTransformation.getMatrix().preTranslate(thumbnailX, thumbnailY);
217a91f9e2959ee905f97977a88fe45bde6ffb874b0Craig Mautner
218a91f9e2959ee905f97977a88fe45bde6ffb874b0Craig Mautner        ScreenRotationAnimation screenRotationAnimation =
219a91f9e2959ee905f97977a88fe45bde6ffb874b0Craig Mautner                mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
220a91f9e2959ee905f97977a88fe45bde6ffb874b0Craig Mautner        final boolean screenAnimation = screenRotationAnimation != null
221a91f9e2959ee905f97977a88fe45bde6ffb874b0Craig Mautner                && screenRotationAnimation.isAnimating();
222594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        if (screenAnimation) {
223a91f9e2959ee905f97977a88fe45bde6ffb874b0Craig Mautner            thumbnailTransformation.postCompose(screenRotationAnimation.getEnterTransformation());
224594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
225594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        // cache often used attributes locally
226594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        final float tmpFloats[] = mService.mTmpFloats;
227594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        thumbnailTransformation.getMatrix().getValues(tmpFloats);
2288ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale        if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
229594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                "thumbnail", "POS " + tmpFloats[Matrix.MTRANS_X]
230594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                + ", " + tmpFloats[Matrix.MTRANS_Y], null);
231594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        thumbnail.setPosition(tmpFloats[Matrix.MTRANS_X], tmpFloats[Matrix.MTRANS_Y]);
2328ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale        if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
233594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                "thumbnail", "alpha=" + thumbnailTransformation.getAlpha()
234594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                + " layer=" + thumbnailLayer
235594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                + " matrix=[" + tmpFloats[Matrix.MSCALE_X]
236594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                + "," + tmpFloats[Matrix.MSKEW_Y]
237594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                + "][" + tmpFloats[Matrix.MSKEW_X]
238594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                + "," + tmpFloats[Matrix.MSCALE_Y] + "]", null);
239594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        thumbnail.setAlpha(thumbnailTransformation.getAlpha());
240a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        if (thumbnailForceAboveLayer > 0) {
241a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            thumbnail.setLayer(thumbnailForceAboveLayer + 1);
242a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        } else {
243a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            // The thumbnail is layered below the window immediately above this
244a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            // token's anim layer.
245a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            thumbnail.setLayer(thumbnailLayer + WindowManagerService.WINDOW_LAYER_MULTIPLIER
246a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                    - WindowManagerService.LAYER_OFFSET_THUMBNAIL);
247a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        }
248594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        thumbnail.setMatrix(tmpFloats[Matrix.MSCALE_X], tmpFloats[Matrix.MSKEW_Y],
249594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                tmpFloats[Matrix.MSKEW_X], tmpFloats[Matrix.MSCALE_Y]);
250594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    }
251594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
252594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    private boolean stepAnimation(long currentTime) {
253594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        if (animation == null) {
254594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            return false;
255594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
256594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        transformation.clear();
257ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung        boolean hasMoreFrames = animation.getTransformation(currentTime, transformation);
258ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung        if (!hasMoreFrames) {
259ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung            if (deferThumbnailDestruction && !deferFinalFrameCleanup) {
260ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung                // We are deferring the thumbnail destruction, so extend the animation for one more
261ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung                // (dummy) frame before we clean up
262ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung                deferFinalFrameCleanup = true;
263ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung                hasMoreFrames = true;
264ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung            } else {
2658ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                if (false && DEBUG_ANIM) Slog.v(TAG,
2668ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                        "Stepped animation in " + mAppToken + ": more=" + hasMoreFrames +
2678ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                        ", xform=" + transformation);
268ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung                deferFinalFrameCleanup = false;
269ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung                animation = null;
270a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                clearThumbnail();
2718ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                if (DEBUG_ANIM) Slog.v(TAG,
2728ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                        "Finished animation in " + mAppToken + " @ " + currentTime);
273a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            }
274594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
275ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung        hasTransformation = hasMoreFrames;
276ab79fce2e71b6816b2b88b826ca723b3591f1e26Winson Chung        return hasMoreFrames;
277594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    }
278594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
279c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi    private long getStartTimeCorrection() {
280c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi        if (mSkipFirstFrame) {
281c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi
282c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi            // If the transition is an animation in which the first frame doesn't change the screen
283c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi            // contents at all, we can just skip it and start at the second frame. So we shift the
284c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi            // start time of the animation forward by minus the frame duration.
285c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi            return -Choreographer.getInstance().getFrameIntervalNanos() / TimeUtils.NANOS_PER_MS;
286c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi        } else {
287c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi            return 0;
288c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi        }
289c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi    }
290c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi
291594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    // This must be called while inside a transaction.
292f16a281066ed7b524676698f95642c0a550b0b62Wale Ogunwale    boolean stepAnimationLocked(long currentTime, final int displayId) {
293594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        if (mService.okToDisplay()) {
294594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            // We will run animations as long as the display isn't frozen.
295594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
296fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner            if (animation == sDummyAnimation) {
297594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                // This guy is going to animate, but not yet.  For now count
298594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                // it as not animating for purposes of scheduling transactions;
299594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                // when it is really time to animate, this will be set to
300594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                // a real animation and the next call will execute normally.
301594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                return false;
302594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            }
303594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
304594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            if ((mAppToken.allDrawn || animating || mAppToken.startingDisplayed)
305594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    && animation != null) {
306594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                if (!animating) {
3078ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                    if (DEBUG_ANIM) Slog.v(TAG,
3088ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                        "Starting animation in " + mAppToken +
309eb94fa7975b1e8742f3b00cec6bd4f9d6b329e3aDianne Hackborn                        " @ " + currentTime + " scale="
310eb94fa7975b1e8742f3b00cec6bd4f9d6b329e3aDianne Hackborn                        + mService.getTransitionAnimationScaleLocked()
311594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                        + " allDrawn=" + mAppToken.allDrawn + " animating=" + animating);
312c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi                    long correction = getStartTimeCorrection();
313c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi                    animation.setStartTime(currentTime + correction);
314594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    animating = true;
315594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    if (thumbnail != null) {
316594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                        thumbnail.show();
317c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi                        thumbnailAnimation.setStartTime(currentTime + correction);
318594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    }
319c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi                    mSkipFirstFrame = false;
320594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                }
321594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                if (stepAnimation(currentTime)) {
322594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    // animation isn't over, step any thumbnail and that's
323594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    // it for now.
324594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    if (thumbnail != null) {
325594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                        stepThumbnailAnimation(currentTime);
326594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    }
327594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    return true;
328594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                }
329594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            }
330594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        } else if (animation != null) {
331594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            // If the display is frozen, and there is a pending animation,
332594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            // clear it and make sure we run the cleanup code.
333594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            animating = true;
334594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            animation = null;
335594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
336594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
337594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        hasTransformation = false;
338594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
3393de422fe4fe903b1370f3f7ee9c7086966e15b28Craig Mautner        if (!animating && animation == null) {
340594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            return false;
341594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
342594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
34376a7165719dc3ccce902953f6244e2c2668aa753Craig Mautner        mAnimator.setAppLayoutChanges(this, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM,
344f16a281066ed7b524676698f95642c0a550b0b62Wale Ogunwale                "AppWindowToken", displayId);
345594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
346594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        clearAnimation();
347594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        animating = false;
348594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        if (animLayerAdjustment != 0) {
349594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            animLayerAdjustment = 0;
350594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            updateLayers();
351594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
352594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        if (mService.mInputMethodTarget != null
353594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                && mService.mInputMethodTarget.mAppToken == mAppToken) {
354594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            mService.moveInputMethodWindowsIfNeededLocked(true);
355594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
356594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
3578ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale        if (DEBUG_ANIM) Slog.v(TAG,
3588ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                "Animation done in " + mAppToken
359594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                + ": reportedVisible=" + mAppToken.reportedVisible);
360594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
361594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        transformation.clear();
362594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
363ec533f6a55cfe3b3fdc43f2cdd2305d952a2437bWale Ogunwale        final int numAllAppWinAnimators = mAllAppWinAnimators.size();
364ec533f6a55cfe3b3fdc43f2cdd2305d952a2437bWale Ogunwale        for (int i = 0; i < numAllAppWinAnimators; i++) {
365ec533f6a55cfe3b3fdc43f2cdd2305d952a2437bWale Ogunwale            mAllAppWinAnimators.get(i).finishExit();
366bb742462781a73bb25516067c8fe6311c1c8a93eCraig Mautner        }
367a48eadbeb6fa34f27d6db7de51d3c01972ea2ebfWale Ogunwale        mService.mAppTransition.notifyAppTransitionFinishedLocked(mAppToken.token);
368594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        return false;
369594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    }
370594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner
371bec53f7066852c1c5877c51fcd8c55840891d866Craig Mautner    boolean showAllWindowsLocked() {
372bec53f7066852c1c5877c51fcd8c55840891d866Craig Mautner        boolean isAnimating = false;
373322e40315609acd5a608440bc469d873e09559caCraig Mautner        final int NW = mAllAppWinAnimators.size();
374bec53f7066852c1c5877c51fcd8c55840891d866Craig Mautner        for (int i=0; i<NW; i++) {
375322e40315609acd5a608440bc469d873e09559caCraig Mautner            WindowStateAnimator winAnimator = mAllAppWinAnimators.get(i);
376fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner            if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
377bec53f7066852c1c5877c51fcd8c55840891d866Craig Mautner                    "performing show on: " + winAnimator);
378bec53f7066852c1c5877c51fcd8c55840891d866Craig Mautner            winAnimator.performShowLocked();
379bec53f7066852c1c5877c51fcd8c55840891d866Craig Mautner            isAnimating |= winAnimator.isAnimating();
380bec53f7066852c1c5877c51fcd8c55840891d866Craig Mautner        }
381bec53f7066852c1c5877c51fcd8c55840891d866Craig Mautner        return isAnimating;
382bec53f7066852c1c5877c51fcd8c55840891d866Craig Mautner    }
383bec53f7066852c1c5877c51fcd8c55840891d866Craig Mautner
384529e744d3131b9ebeb6b33c8030230c29a44ad12Dianne Hackborn    void dump(PrintWriter pw, String prefix, boolean dumpAll) {
385529e744d3131b9ebeb6b33c8030230c29a44ad12Dianne Hackborn        pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
386529e744d3131b9ebeb6b33c8030230c29a44ad12Dianne Hackborn        pw.print(prefix); pw.print("mAnimator="); pw.println(mAnimator);
387529e744d3131b9ebeb6b33c8030230c29a44ad12Dianne Hackborn        pw.print(prefix); pw.print("freezingScreen="); pw.print(freezingScreen);
388529e744d3131b9ebeb6b33c8030230c29a44ad12Dianne Hackborn                pw.print(" allDrawn="); pw.print(allDrawn);
389529e744d3131b9ebeb6b33c8030230c29a44ad12Dianne Hackborn                pw.print(" animLayerAdjustment="); pw.println(animLayerAdjustment);
390a57c695bf2c0f917517ecac8251043716b34f72dDianne Hackborn        if (lastFreezeDuration != 0) {
391a57c695bf2c0f917517ecac8251043716b34f72dDianne Hackborn            pw.print(prefix); pw.print("lastFreezeDuration=");
392a57c695bf2c0f917517ecac8251043716b34f72dDianne Hackborn                    TimeUtils.formatDuration(lastFreezeDuration, pw); pw.println();
393a57c695bf2c0f917517ecac8251043716b34f72dDianne Hackborn        }
394594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        if (animating || animation != null) {
3959339c401cf1a056a3a1caddc648334069e6bd267Craig Mautner            pw.print(prefix); pw.print("animating="); pw.println(animating);
396529e744d3131b9ebeb6b33c8030230c29a44ad12Dianne Hackborn            pw.print(prefix); pw.print("animation="); pw.println(animation);
397594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
398594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        if (hasTransformation) {
399594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            pw.print(prefix); pw.print("XForm: ");
400594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    transformation.printShortString(pw);
401594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    pw.println();
402594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
403594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        if (thumbnail != null) {
404594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            pw.print(prefix); pw.print("thumbnail="); pw.print(thumbnail);
405594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    pw.print(" x="); pw.print(thumbnailX);
406594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    pw.print(" y="); pw.print(thumbnailY);
407594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    pw.print(" layer="); pw.println(thumbnailLayer);
408594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            pw.print(prefix); pw.print("thumbnailAnimation="); pw.println(thumbnailAnimation);
409594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner            pw.print(prefix); pw.print("thumbnailTransformation=");
410594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner                    pw.println(thumbnailTransformation.toShortString());
411594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner        }
412529e744d3131b9ebeb6b33c8030230c29a44ad12Dianne Hackborn        for (int i=0; i<mAllAppWinAnimators.size(); i++) {
413529e744d3131b9ebeb6b33c8030230c29a44ad12Dianne Hackborn            WindowStateAnimator wanim = mAllAppWinAnimators.get(i);
414529e744d3131b9ebeb6b33c8030230c29a44ad12Dianne Hackborn            pw.print(prefix); pw.print("App Win Anim #"); pw.print(i);
415529e744d3131b9ebeb6b33c8030230c29a44ad12Dianne Hackborn                    pw.print(": "); pw.println(wanim);
416529e744d3131b9ebeb6b33c8030230c29a44ad12Dianne Hackborn        }
417594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner    }
418fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner
419fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner    // This is an animation that does nothing: it just immediately finishes
420fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner    // itself every time it is called.  It is used as a stub animation in cases
421fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner    // where we want to synchronize multiple things that may be animating.
422fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner    static final class DummyAnimation extends Animation {
423fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner        @Override
424fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner        public boolean getTransformation(long currentTime, Transformation outTransformation) {
425fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner            return false;
426fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner        }
427fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner    }
428fbf378c736a973b8edaf1fc4c187d11dc0f5e291Craig Mautner
429594316361d38d88b53c85bd5c8d58a92345e8187Craig Mautner}
430