ExitTransitionCoordinator.java revision b694e080546316a27d22eba759027f6cb0a24705
131a217290cf376d0573fc36e21c8940987485019George Mount/*
231a217290cf376d0573fc36e21c8940987485019George Mount * Copyright (C) 2014 The Android Open Source Project
331a217290cf376d0573fc36e21c8940987485019George Mount *
431a217290cf376d0573fc36e21c8940987485019George Mount * Licensed under the Apache License, Version 2.0 (the "License");
531a217290cf376d0573fc36e21c8940987485019George Mount * you may not use this file except in compliance with the License.
631a217290cf376d0573fc36e21c8940987485019George Mount * You may obtain a copy of the License at
731a217290cf376d0573fc36e21c8940987485019George Mount *
831a217290cf376d0573fc36e21c8940987485019George Mount *      http://www.apache.org/licenses/LICENSE-2.0
931a217290cf376d0573fc36e21c8940987485019George Mount *
1031a217290cf376d0573fc36e21c8940987485019George Mount * Unless required by applicable law or agreed to in writing, software
1131a217290cf376d0573fc36e21c8940987485019George Mount * distributed under the License is distributed on an "AS IS" BASIS,
1231a217290cf376d0573fc36e21c8940987485019George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1331a217290cf376d0573fc36e21c8940987485019George Mount * See the License for the specific language governing permissions and
1431a217290cf376d0573fc36e21c8940987485019George Mount * limitations under the License.
1531a217290cf376d0573fc36e21c8940987485019George Mount */
1631a217290cf376d0573fc36e21c8940987485019George Mountpackage android.app;
1731a217290cf376d0573fc36e21c8940987485019George Mount
1862ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.animation.Animator;
1962ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.animation.AnimatorListenerAdapter;
2062ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.animation.ObjectAnimator;
2162ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.content.Intent;
2285b764e22babfe5508286fbad5d7fee12345704fCraig Mautnerimport android.graphics.Color;
237bf379c8af399626d5b8b568fe1d4f96f56badccDake Guimport android.graphics.Matrix;
247bf379c8af399626d5b8b568fe1d4f96f56badccDake Guimport android.graphics.RectF;
2562ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.graphics.drawable.ColorDrawable;
268cab50afda0d8485436f72a93d668697f549d3b3George Mountimport android.graphics.drawable.Drawable;
2731a217290cf376d0573fc36e21c8940987485019George Mountimport android.os.Bundle;
2862ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.os.Handler;
2962ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.os.Message;
3031a217290cf376d0573fc36e21c8940987485019George Mountimport android.transition.Transition;
3162ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.transition.TransitionManager;
3231a217290cf376d0573fc36e21c8940987485019George Mountimport android.view.View;
33e678ab686643127b4b297ae7a1e4869b4cfc6e53George Mountimport android.view.ViewGroup;
34c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.view.ViewTreeObserver;
3531a217290cf376d0573fc36e21c8940987485019George Mount
3631a217290cf376d0573fc36e21c8940987485019George Mountimport java.util.ArrayList;
3731a217290cf376d0573fc36e21c8940987485019George Mount
3831a217290cf376d0573fc36e21c8940987485019George Mount/**
3931a217290cf376d0573fc36e21c8940987485019George Mount * This ActivityTransitionCoordinator is created in ActivityOptions#makeSceneTransitionAnimation
4031a217290cf376d0573fc36e21c8940987485019George Mount * to govern the exit of the Scene and the shared elements when calling an Activity as well as
4131a217290cf376d0573fc36e21c8940987485019George Mount * the reentry of the Scene when coming back from the called Activity.
4231a217290cf376d0573fc36e21c8940987485019George Mount */
4331a217290cf376d0573fc36e21c8940987485019George Mountclass ExitTransitionCoordinator extends ActivityTransitionCoordinator {
4431a217290cf376d0573fc36e21c8940987485019George Mount    private static final String TAG = "ExitTransitionCoordinator";
458cab50afda0d8485436f72a93d668697f549d3b3George Mount    private static final long MAX_WAIT_MS = 1000;
4631a217290cf376d0573fc36e21c8940987485019George Mount
4762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private boolean mExitComplete;
4831a217290cf376d0573fc36e21c8940987485019George Mount
4962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private Bundle mSharedElementBundle;
5031a217290cf376d0573fc36e21c8940987485019George Mount
5162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private boolean mExitNotified;
5231a217290cf376d0573fc36e21c8940987485019George Mount
5362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private boolean mSharedElementNotified;
5431a217290cf376d0573fc36e21c8940987485019George Mount
5562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private Activity mActivity;
5631a217290cf376d0573fc36e21c8940987485019George Mount
5762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private boolean mIsBackgroundReady;
5862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
5962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private boolean mIsCanceled;
6062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
6162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private Handler mHandler;
6262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
638cab50afda0d8485436f72a93d668697f549d3b3George Mount    private ObjectAnimator mBackgroundAnimator;
648cab50afda0d8485436f72a93d668697f549d3b3George Mount
658cab50afda0d8485436f72a93d668697f549d3b3George Mount    private boolean mIsHidden;
668cab50afda0d8485436f72a93d668697f549d3b3George Mount
67c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    private Bundle mExitSharedElementBundle;
68c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
69700db2a325bced35cebc403f272f988fad522892George Mount    private boolean mIsExitStarted;
70700db2a325bced35cebc403f272f988fad522892George Mount
71b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount    private boolean mSharedElementsHidden;
72b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount
7362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    public ExitTransitionCoordinator(Activity activity, ArrayList<String> names,
741fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount            ArrayList<String> accepted, ArrayList<View> mapped, boolean isReturning) {
75fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        super(activity.getWindow(), names, getListener(activity, isReturning), isReturning);
761fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount        viewsReady(mapSharedElements(accepted, mapped));
7760625b02ac099bacc96a387ec270751745dafae0George Mount        stripOffscreenViews();
78a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        mIsBackgroundReady = !isReturning;
7962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        mActivity = activity;
8031a217290cf376d0573fc36e21c8940987485019George Mount    }
8131a217290cf376d0573fc36e21c8940987485019George Mount
826558056e8fccc32f9e1dc59e46d09f8d916b7538George Mount    private static SharedElementCallback getListener(Activity activity, boolean isReturning) {
83d80154fba1c23834b5139aa764f9426bbf38a721George Mount        return isReturning ? activity.mEnterTransitionListener : activity.mExitTransitionListener;
84800d72b0e05049e4a8f90ea96ec165fc975264ceGeorge Mount    }
85800d72b0e05049e4a8f90ea96ec165fc975264ceGeorge Mount
8631a217290cf376d0573fc36e21c8940987485019George Mount    @Override
8762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    protected void onReceiveResult(int resultCode, Bundle resultData) {
8862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        switch (resultCode) {
8962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            case MSG_SET_REMOTE_RECEIVER:
90fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                stopCancel();
9162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                mResultReceiver = resultData.getParcelable(KEY_REMOTE_RECEIVER);
9262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                if (mIsCanceled) {
9362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                    mResultReceiver.send(MSG_CANCEL, null);
9462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                    mResultReceiver = null;
9562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                } else {
9662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                    notifyComplete();
9762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                }
9862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                break;
9962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            case MSG_HIDE_SHARED_ELEMENTS:
100fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                stopCancel();
10162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                if (!mIsCanceled) {
10262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                    hideSharedElements();
10362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                }
10462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                break;
10562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            case MSG_START_EXIT_TRANSITION:
106fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                mHandler.removeMessages(MSG_CANCEL);
10762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                startExit();
10862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                break;
109c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            case MSG_SHARED_ELEMENT_DESTINATION:
110c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                mExitSharedElementBundle = resultData;
11167d924341a1d0994ac68b3b7898d5576edd987b4George Mount                sharedElementExitBack();
11267d924341a1d0994ac68b3b7898d5576edd987b4George Mount                break;
11367d924341a1d0994ac68b3b7898d5576edd987b4George Mount        }
11467d924341a1d0994ac68b3b7898d5576edd987b4George Mount    }
11567d924341a1d0994ac68b3b7898d5576edd987b4George Mount
116fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    private void stopCancel() {
117fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        if (mHandler != null) {
118fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            mHandler.removeMessages(MSG_CANCEL);
119fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        }
120fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
121fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
122fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    private void delayCancel() {
123fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        if (mHandler != null) {
124fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            mHandler.sendEmptyMessageDelayed(MSG_CANCEL, MAX_WAIT_MS);
125fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        }
126fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
127fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
1281fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount    public void resetViews() {
129b694e080546316a27d22eba759027f6cb0a24705George Mount        if (mTransitioningViews != null) {
130b694e080546316a27d22eba759027f6cb0a24705George Mount            showViews(mTransitioningViews, true);
131b694e080546316a27d22eba759027f6cb0a24705George Mount        }
132ce2ee3d6de670e52abed7f432778701113ba9c07George Mount        showViews(mSharedElements, true);
1331fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount        mIsHidden = true;
13448bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        ViewGroup decorView = getDecor();
13548bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        if (!mIsReturning && decorView != null) {
13648bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            decorView.suppressLayout(false);
137f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu        }
138fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        moveSharedElementsFromOverlay();
1398d3cd2c8cf8ec355265941a8457ffd8e2e348648George Mount        clearState();
1401fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount    }
1411fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount
14267d924341a1d0994ac68b3b7898d5576edd987b4George Mount    private void sharedElementExitBack() {
14348bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        final ViewGroup decorView = getDecor();
14448bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        if (decorView != null) {
14548bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            decorView.suppressLayout(true);
146f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu        }
14748bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        if (decorView != null && mExitSharedElementBundle != null &&
14848bd13c9cb2627847cf1f7707a084eb354e9c303George Mount                !mExitSharedElementBundle.isEmpty() &&
149872efe45d5b3a4d6376cd15e118d5bb68ef334daDake Gu                !mSharedElements.isEmpty() && getSharedElementTransition() != null) {
15067d924341a1d0994ac68b3b7898d5576edd987b4George Mount            startTransition(new Runnable() {
15167d924341a1d0994ac68b3b7898d5576edd987b4George Mount                public void run() {
15248bd13c9cb2627847cf1f7707a084eb354e9c303George Mount                    startSharedElementExit(decorView);
153c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                }
15467d924341a1d0994ac68b3b7898d5576edd987b4George Mount            });
15500dde0bd469ba7a34369dcaaa701bd06fdf6c3adGeorge Mount        } else {
15600dde0bd469ba7a34369dcaaa701bd06fdf6c3adGeorge Mount            sharedElementTransitionComplete();
157c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
158c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
159c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
16048bd13c9cb2627847cf1f7707a084eb354e9c303George Mount    private void startSharedElementExit(final ViewGroup decorView) {
16167d924341a1d0994ac68b3b7898d5576edd987b4George Mount        Transition transition = getSharedElementExitTransition();
162fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        transition.addListener(new Transition.TransitionListenerAdapter() {
163fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            @Override
164fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            public void onTransitionEnd(Transition transition) {
165fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                transition.removeListener(this);
166fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                if (mExitComplete) {
167fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                    delayCancel();
168fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                }
169fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            }
170fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        });
17167d924341a1d0994ac68b3b7898d5576edd987b4George Mount        final ArrayList<View> sharedElementSnapshots = createSnapshots(mExitSharedElementBundle,
17267d924341a1d0994ac68b3b7898d5576edd987b4George Mount                mSharedElementNames);
1736e7fb60b93d3449d256282a9cc34ba3356add90eGeorge Mount        decorView.getViewTreeObserver()
17467d924341a1d0994ac68b3b7898d5576edd987b4George Mount                .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
17567d924341a1d0994ac68b3b7898d5576edd987b4George Mount                    @Override
17667d924341a1d0994ac68b3b7898d5576edd987b4George Mount                    public boolean onPreDraw() {
1776e7fb60b93d3449d256282a9cc34ba3356add90eGeorge Mount                        decorView.getViewTreeObserver().removeOnPreDrawListener(this);
17867d924341a1d0994ac68b3b7898d5576edd987b4George Mount                        setSharedElementState(mExitSharedElementBundle, sharedElementSnapshots);
17967d924341a1d0994ac68b3b7898d5576edd987b4George Mount                        return true;
18067d924341a1d0994ac68b3b7898d5576edd987b4George Mount                    }
18167d924341a1d0994ac68b3b7898d5576edd987b4George Mount                });
182fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        setGhostVisibility(View.INVISIBLE);
183fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        scheduleGhostVisibilityChange(View.INVISIBLE);
1846558056e8fccc32f9e1dc59e46d09f8d916b7538George Mount        mListener.onSharedElementEnd(mSharedElementNames, mSharedElements, sharedElementSnapshots);
18548bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        TransitionManager.beginDelayedTransition(decorView, transition);
186fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        scheduleGhostVisibilityChange(View.VISIBLE);
187fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        setGhostVisibility(View.VISIBLE);
18848bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        decorView.invalidate();
18967d924341a1d0994ac68b3b7898d5576edd987b4George Mount    }
19067d924341a1d0994ac68b3b7898d5576edd987b4George Mount
19162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private void hideSharedElements() {
192fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        moveSharedElementsFromOverlay();
19367d924341a1d0994ac68b3b7898d5576edd987b4George Mount        if (!mIsHidden) {
1940f0c473488f8e8becc8883d3cdd9610324610dc4George Mount            hideViews(mSharedElements);
19567d924341a1d0994ac68b3b7898d5576edd987b4George Mount        }
196b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount        mSharedElementsHidden = true;
197c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        finishIfNecessary();
19831a217290cf376d0573fc36e21c8940987485019George Mount    }
19931a217290cf376d0573fc36e21c8940987485019George Mount
20062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    public void startExit() {
201700db2a325bced35cebc403f272f988fad522892George Mount        if (!mIsExitStarted) {
202700db2a325bced35cebc403f272f988fad522892George Mount            mIsExitStarted = true;
20348bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            ViewGroup decorView = getDecor();
20448bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            if (decorView != null) {
20548bd13c9cb2627847cf1f7707a084eb354e9c303George Mount                decorView.suppressLayout(true);
206f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu            }
207fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            moveSharedElementsToOverlay();
208700db2a325bced35cebc403f272f988fad522892George Mount            startTransition(new Runnable() {
209700db2a325bced35cebc403f272f988fad522892George Mount                @Override
210700db2a325bced35cebc403f272f988fad522892George Mount                public void run() {
211700db2a325bced35cebc403f272f988fad522892George Mount                    beginTransitions();
212700db2a325bced35cebc403f272f988fad522892George Mount                }
213700db2a325bced35cebc403f272f988fad522892George Mount            });
214700db2a325bced35cebc403f272f988fad522892George Mount        }
21531a217290cf376d0573fc36e21c8940987485019George Mount    }
21631a217290cf376d0573fc36e21c8940987485019George Mount
21762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    public void startExit(int resultCode, Intent data) {
218700db2a325bced35cebc403f272f988fad522892George Mount        if (!mIsExitStarted) {
219700db2a325bced35cebc403f272f988fad522892George Mount            mIsExitStarted = true;
22048bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            ViewGroup decorView = getDecor();
22148bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            if (decorView != null) {
22248bd13c9cb2627847cf1f7707a084eb354e9c303George Mount                decorView.suppressLayout(true);
223f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu            }
224700db2a325bced35cebc403f272f988fad522892George Mount            mHandler = new Handler() {
225700db2a325bced35cebc403f272f988fad522892George Mount                @Override
226700db2a325bced35cebc403f272f988fad522892George Mount                public void handleMessage(Message msg) {
227700db2a325bced35cebc403f272f988fad522892George Mount                    mIsCanceled = true;
228700db2a325bced35cebc403f272f988fad522892George Mount                    finish();
22962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                }
230700db2a325bced35cebc403f272f988fad522892George Mount            };
231fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            delayCancel();
232fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            moveSharedElementsToOverlay();
23348bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            if (decorView != null && decorView.getBackground() == null) {
23485b764e22babfe5508286fbad5d7fee12345704fCraig Mautner                getWindow().setBackgroundDrawable(new ColorDrawable(Color.BLACK));
23562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            }
236700db2a325bced35cebc403f272f988fad522892George Mount            ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(mActivity, this,
237700db2a325bced35cebc403f272f988fad522892George Mount                    mAllSharedElementNames, resultCode, data);
238700db2a325bced35cebc403f272f988fad522892George Mount            mActivity.convertToTranslucent(new Activity.TranslucentConversionListener() {
239700db2a325bced35cebc403f272f988fad522892George Mount                @Override
240700db2a325bced35cebc403f272f988fad522892George Mount                public void onTranslucentConversionComplete(boolean drawComplete) {
241700db2a325bced35cebc403f272f988fad522892George Mount                    if (!mIsCanceled) {
242700db2a325bced35cebc403f272f988fad522892George Mount                        fadeOutBackground();
243700db2a325bced35cebc403f272f988fad522892George Mount                    }
244700db2a325bced35cebc403f272f988fad522892George Mount                }
245700db2a325bced35cebc403f272f988fad522892George Mount            }, options);
246700db2a325bced35cebc403f272f988fad522892George Mount            startTransition(new Runnable() {
247700db2a325bced35cebc403f272f988fad522892George Mount                @Override
248700db2a325bced35cebc403f272f988fad522892George Mount                public void run() {
249700db2a325bced35cebc403f272f988fad522892George Mount                    startExitTransition();
250700db2a325bced35cebc403f272f988fad522892George Mount                }
251700db2a325bced35cebc403f272f988fad522892George Mount            });
252700db2a325bced35cebc403f272f988fad522892George Mount        }
25367d924341a1d0994ac68b3b7898d5576edd987b4George Mount    }
25467d924341a1d0994ac68b3b7898d5576edd987b4George Mount
25567d924341a1d0994ac68b3b7898d5576edd987b4George Mount    private void startExitTransition() {
256f451d8a6d1a454f338e37f99c0867e17ce9e06f1George Mount        Transition transition = getExitTransition();
25748bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        ViewGroup decorView = getDecor();
258b694e080546316a27d22eba759027f6cb0a24705George Mount        if (transition != null && decorView != null && mTransitioningViews != null) {
25948bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            TransitionManager.beginDelayedTransition(decorView, transition);
260b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount            mTransitioningViews.get(0).invalidate();
261b4c5d7bf218865d28f030c852fd303e127d676dbGeorge Mount        } else {
262b4c5d7bf218865d28f030c852fd303e127d676dbGeorge Mount            transitionStarted();
263c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
26431a217290cf376d0573fc36e21c8940987485019George Mount    }
26531a217290cf376d0573fc36e21c8940987485019George Mount
26662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private void fadeOutBackground() {
2678cab50afda0d8485436f72a93d668697f549d3b3George Mount        if (mBackgroundAnimator == null) {
268700db2a325bced35cebc403f272f988fad522892George Mount            ViewGroup decor = getDecor();
269700db2a325bced35cebc403f272f988fad522892George Mount            Drawable background;
270700db2a325bced35cebc403f272f988fad522892George Mount            if (decor != null && (background = decor.getBackground()) != null) {
27199c82fd1de23deeb8cf640bb574c76af76429df6George Mount                background = background.mutate();
27299c82fd1de23deeb8cf640bb574c76af76429df6George Mount                getWindow().setBackgroundDrawable(background);
273700db2a325bced35cebc403f272f988fad522892George Mount                mBackgroundAnimator = ObjectAnimator.ofInt(background, "alpha", 0);
274700db2a325bced35cebc403f272f988fad522892George Mount                mBackgroundAnimator.addListener(new AnimatorListenerAdapter() {
275700db2a325bced35cebc403f272f988fad522892George Mount                    @Override
276700db2a325bced35cebc403f272f988fad522892George Mount                    public void onAnimationEnd(Animator animation) {
277700db2a325bced35cebc403f272f988fad522892George Mount                        mBackgroundAnimator = null;
278700db2a325bced35cebc403f272f988fad522892George Mount                        if (!mIsCanceled) {
279700db2a325bced35cebc403f272f988fad522892George Mount                            mIsBackgroundReady = true;
280700db2a325bced35cebc403f272f988fad522892George Mount                            notifyComplete();
281700db2a325bced35cebc403f272f988fad522892George Mount                        }
2828cab50afda0d8485436f72a93d668697f549d3b3George Mount                    }
283700db2a325bced35cebc403f272f988fad522892George Mount                });
284700db2a325bced35cebc403f272f988fad522892George Mount                mBackgroundAnimator.setDuration(getFadeDuration());
285700db2a325bced35cebc403f272f988fad522892George Mount                mBackgroundAnimator.start();
286b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount            } else {
287b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount                mIsBackgroundReady = true;
288700db2a325bced35cebc403f272f988fad522892George Mount            }
2898cab50afda0d8485436f72a93d668697f549d3b3George Mount        }
29031a217290cf376d0573fc36e21c8940987485019George Mount    }
29131a217290cf376d0573fc36e21c8940987485019George Mount
292c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    private Transition getExitTransition() {
293c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        Transition viewsTransition = null;
294b694e080546316a27d22eba759027f6cb0a24705George Mount        if (mTransitioningViews != null && !mTransitioningViews.isEmpty()) {
2958881502da5b319e139ab85c1825d2d2d239356a1George Mount            viewsTransition = configureTransition(getViewsTransition(), true);
296c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
297c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (viewsTransition == null) {
298c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            exitTransitionComplete();
29962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        } else {
300b694e080546316a27d22eba759027f6cb0a24705George Mount            final ArrayList<View> transitioningViews = mTransitioningViews;
30167d924341a1d0994ac68b3b7898d5576edd987b4George Mount            viewsTransition.addListener(new ContinueTransitionListener() {
30262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                @Override
30362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                public void onTransitionEnd(Transition transition) {
304a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount                    transition.removeListener(this);
305c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                    exitTransitionComplete();
306b694e080546316a27d22eba759027f6cb0a24705George Mount                    if (mIsHidden && transitioningViews != null) {
307b694e080546316a27d22eba759027f6cb0a24705George Mount                        showViews(transitioningViews, true);
308c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                    }
309fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                    if (mSharedElementBundle != null) {
310fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                        delayCancel();
311fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                    }
312fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                    super.onTransitionEnd(transition);
31362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                }
31462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            });
315b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount            viewsTransition.forceVisibility(View.INVISIBLE, false);
31662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        }
317c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        return viewsTransition;
318c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
319c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
320c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    private Transition getSharedElementExitTransition() {
321c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        Transition sharedElementTransition = null;
322c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (!mSharedElements.isEmpty()) {
3238881502da5b319e139ab85c1825d2d2d239356a1George Mount            sharedElementTransition = configureTransition(getSharedElementTransition(), false);
324c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
325c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (sharedElementTransition == null) {
326c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            sharedElementTransitionComplete();
32762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        } else {
32867d924341a1d0994ac68b3b7898d5576edd987b4George Mount            sharedElementTransition.addListener(new ContinueTransitionListener() {
32962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                @Override
33062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                public void onTransitionEnd(Transition transition) {
331a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount                    transition.removeListener(this);
332c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                    sharedElementTransitionComplete();
3338cab50afda0d8485436f72a93d668697f549d3b3George Mount                    if (mIsHidden) {
334ce2ee3d6de670e52abed7f432778701113ba9c07George Mount                        showViews(mSharedElements, true);
3358cab50afda0d8485436f72a93d668697f549d3b3George Mount                    }
33662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                }
33762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            });
338c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            mSharedElements.get(0).invalidate();
33962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        }
340c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        return sharedElementTransition;
341c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
342c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
343c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    private void beginTransitions() {
344c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        Transition sharedElementTransition = getSharedElementExitTransition();
345c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        Transition viewsTransition = getExitTransition();
34662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
34762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        Transition transition = mergeTransitions(sharedElementTransition, viewsTransition);
34848bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        ViewGroup decorView = getDecor();
34948bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        if (transition != null && decorView != null) {
350fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            setGhostVisibility(View.INVISIBLE);
351fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            scheduleGhostVisibilityChange(View.INVISIBLE);
35248bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            TransitionManager.beginDelayedTransition(decorView, transition);
353fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            scheduleGhostVisibilityChange(View.VISIBLE);
354fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            setGhostVisibility(View.VISIBLE);
35548bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            decorView.invalidate();
356b4c5d7bf218865d28f030c852fd303e127d676dbGeorge Mount        } else {
357b4c5d7bf218865d28f030c852fd303e127d676dbGeorge Mount            transitionStarted();
358a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        }
35962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    }
36062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
36162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private void exitTransitionComplete() {
36231a217290cf376d0573fc36e21c8940987485019George Mount        mExitComplete = true;
36362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        notifyComplete();
36431a217290cf376d0573fc36e21c8940987485019George Mount    }
36531a217290cf376d0573fc36e21c8940987485019George Mount
36662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    protected boolean isReadyToNotify() {
36767d924341a1d0994ac68b3b7898d5576edd987b4George Mount        return mSharedElementBundle != null && mResultReceiver != null && mIsBackgroundReady;
36831a217290cf376d0573fc36e21c8940987485019George Mount    }
36931a217290cf376d0573fc36e21c8940987485019George Mount
37062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private void sharedElementTransitionComplete() {
37167d924341a1d0994ac68b3b7898d5576edd987b4George Mount        mSharedElementBundle = mExitSharedElementBundle == null
37267d924341a1d0994ac68b3b7898d5576edd987b4George Mount                ? captureSharedElementState() : captureExitSharedElementsState();
37362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        notifyComplete();
37431a217290cf376d0573fc36e21c8940987485019George Mount    }
37531a217290cf376d0573fc36e21c8940987485019George Mount
37667d924341a1d0994ac68b3b7898d5576edd987b4George Mount    private Bundle captureExitSharedElementsState() {
37767d924341a1d0994ac68b3b7898d5576edd987b4George Mount        Bundle bundle = new Bundle();
3787bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        RectF bounds = new RectF();
3797bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        Matrix matrix = new Matrix();
38001e9a97fe68dbba42a0edd0ad965ccfe2b8efe7dGeorge Mount        for (int i = 0; i < mSharedElements.size(); i++) {
38167d924341a1d0994ac68b3b7898d5576edd987b4George Mount            String name = mSharedElementNames.get(i);
38267d924341a1d0994ac68b3b7898d5576edd987b4George Mount            Bundle sharedElementState = mExitSharedElementBundle.getBundle(name);
38367d924341a1d0994ac68b3b7898d5576edd987b4George Mount            if (sharedElementState != null) {
38467d924341a1d0994ac68b3b7898d5576edd987b4George Mount                bundle.putBundle(name, sharedElementState);
38567d924341a1d0994ac68b3b7898d5576edd987b4George Mount            } else {
38667d924341a1d0994ac68b3b7898d5576edd987b4George Mount                View view = mSharedElements.get(i);
3877bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu                captureSharedElementState(view, name, bundle, matrix, bounds);
38867d924341a1d0994ac68b3b7898d5576edd987b4George Mount            }
38967d924341a1d0994ac68b3b7898d5576edd987b4George Mount        }
39067d924341a1d0994ac68b3b7898d5576edd987b4George Mount        return bundle;
39167d924341a1d0994ac68b3b7898d5576edd987b4George Mount    }
39267d924341a1d0994ac68b3b7898d5576edd987b4George Mount
39362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    protected void notifyComplete() {
39462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        if (isReadyToNotify()) {
39562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            if (!mSharedElementNotified) {
39662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                mSharedElementNotified = true;
397fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                delayCancel();
39862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                mResultReceiver.send(MSG_TAKE_SHARED_ELEMENTS, mSharedElementBundle);
39962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            }
40062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            if (!mExitNotified && mExitComplete) {
40162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                mExitNotified = true;
40262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                mResultReceiver.send(MSG_EXIT_TRANSITION_COMPLETE, null);
40362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                mResultReceiver = null; // done talking
40448bd13c9cb2627847cf1f7707a084eb354e9c303George Mount                ViewGroup decorView = getDecor();
40548bd13c9cb2627847cf1f7707a084eb354e9c303George Mount                if (!mIsReturning && decorView != null) {
40648bd13c9cb2627847cf1f7707a084eb354e9c303George Mount                    decorView.suppressLayout(false);
407f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu                }
408c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                finishIfNecessary();
40962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            }
41031a217290cf376d0573fc36e21c8940987485019George Mount        }
41131a217290cf376d0573fc36e21c8940987485019George Mount    }
41231a217290cf376d0573fc36e21c8940987485019George Mount
413c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    private void finishIfNecessary() {
414e678ab686643127b4b297ae7a1e4869b4cfc6e53George Mount        if (mIsReturning && mExitNotified && mActivity != null && (mSharedElements.isEmpty() ||
415b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount                mSharedElementsHidden)) {
416a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount            finish();
417c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
418c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (!mIsReturning && mExitNotified) {
419c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            mActivity = null; // don't need it anymore
420c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
421c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
422c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
423a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount    private void finish() {
424fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        stopCancel();
425a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mActivity.mActivityTransitionState.clear();
426a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        // Clear the state so that we can't hold any references accidentally and leak memory.
427a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mHandler.removeMessages(MSG_CANCEL);
428a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mHandler = null;
429a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mActivity.finish();
430a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mActivity.overridePendingTransition(0, 0);
431a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mActivity = null;
432a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mSharedElementBundle = null;
433a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        if (mBackgroundAnimator != null) {
434a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount            mBackgroundAnimator.cancel();
435a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount            mBackgroundAnimator = null;
436a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        }
437a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mExitSharedElementBundle = null;
438a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        clearState();
439a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount    }
440a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount
441a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount    @Override
442fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    protected boolean moveSharedElementWithParent() {
443fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        return !mIsReturning;
444fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
445fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
446fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    @Override
447a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount    protected Transition getViewsTransition() {
448a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        if (mIsReturning) {
44968f96d8db5e5e701b6a12b5cddecc985e56a26c6George Mount            return getWindow().getReturnTransition();
450a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        } else {
451a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount            return getWindow().getExitTransition();
452a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        }
453a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount    }
454a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount
455a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount    protected Transition getSharedElementTransition() {
456a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        if (mIsReturning) {
45768f96d8db5e5e701b6a12b5cddecc985e56a26c6George Mount            return getWindow().getSharedElementReturnTransition();
458a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        } else {
459a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount            return getWindow().getSharedElementExitTransition();
460a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        }
461a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount    }
46231a217290cf376d0573fc36e21c8940987485019George Mount}
463