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); 1841732f528952ea2df0bfd503fabb958af03dbfc81George Mount if (mListener != null) { 1851732f528952ea2df0bfd503fabb958af03dbfc81George Mount mListener.onSharedElementEnd(mSharedElementNames, mSharedElements, 1861732f528952ea2df0bfd503fabb958af03dbfc81George Mount sharedElementSnapshots); 1871732f528952ea2df0bfd503fabb958af03dbfc81George Mount } 18848bd13c9cb2627847cf1f7707a084eb354e9c303George Mount TransitionManager.beginDelayedTransition(decorView, transition); 189fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount scheduleGhostVisibilityChange(View.VISIBLE); 190fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount setGhostVisibility(View.VISIBLE); 19148bd13c9cb2627847cf1f7707a084eb354e9c303George Mount decorView.invalidate(); 19267d924341a1d0994ac68b3b7898d5576edd987b4George Mount } 19367d924341a1d0994ac68b3b7898d5576edd987b4George Mount 19462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount private void hideSharedElements() { 195fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount moveSharedElementsFromOverlay(); 19667d924341a1d0994ac68b3b7898d5576edd987b4George Mount if (!mIsHidden) { 1970f0c473488f8e8becc8883d3cdd9610324610dc4George Mount hideViews(mSharedElements); 19867d924341a1d0994ac68b3b7898d5576edd987b4George Mount } 199b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount mSharedElementsHidden = true; 200c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount finishIfNecessary(); 20131a217290cf376d0573fc36e21c8940987485019George Mount } 20231a217290cf376d0573fc36e21c8940987485019George Mount 20362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public void startExit() { 204700db2a325bced35cebc403f272f988fad522892George Mount if (!mIsExitStarted) { 205700db2a325bced35cebc403f272f988fad522892George Mount mIsExitStarted = true; 20648bd13c9cb2627847cf1f7707a084eb354e9c303George Mount ViewGroup decorView = getDecor(); 20748bd13c9cb2627847cf1f7707a084eb354e9c303George Mount if (decorView != null) { 20848bd13c9cb2627847cf1f7707a084eb354e9c303George Mount decorView.suppressLayout(true); 209f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu } 210fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount moveSharedElementsToOverlay(); 211700db2a325bced35cebc403f272f988fad522892George Mount startTransition(new Runnable() { 212700db2a325bced35cebc403f272f988fad522892George Mount @Override 213700db2a325bced35cebc403f272f988fad522892George Mount public void run() { 214700db2a325bced35cebc403f272f988fad522892George Mount beginTransitions(); 215700db2a325bced35cebc403f272f988fad522892George Mount } 216700db2a325bced35cebc403f272f988fad522892George Mount }); 217700db2a325bced35cebc403f272f988fad522892George Mount } 21831a217290cf376d0573fc36e21c8940987485019George Mount } 21931a217290cf376d0573fc36e21c8940987485019George Mount 22062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public void startExit(int resultCode, Intent data) { 221700db2a325bced35cebc403f272f988fad522892George Mount if (!mIsExitStarted) { 222700db2a325bced35cebc403f272f988fad522892George Mount mIsExitStarted = true; 22348bd13c9cb2627847cf1f7707a084eb354e9c303George Mount ViewGroup decorView = getDecor(); 22448bd13c9cb2627847cf1f7707a084eb354e9c303George Mount if (decorView != null) { 22548bd13c9cb2627847cf1f7707a084eb354e9c303George Mount decorView.suppressLayout(true); 226f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu } 227700db2a325bced35cebc403f272f988fad522892George Mount mHandler = new Handler() { 228700db2a325bced35cebc403f272f988fad522892George Mount @Override 229700db2a325bced35cebc403f272f988fad522892George Mount public void handleMessage(Message msg) { 230700db2a325bced35cebc403f272f988fad522892George Mount mIsCanceled = true; 231700db2a325bced35cebc403f272f988fad522892George Mount finish(); 23262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 233700db2a325bced35cebc403f272f988fad522892George Mount }; 234fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount delayCancel(); 235fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount moveSharedElementsToOverlay(); 23648bd13c9cb2627847cf1f7707a084eb354e9c303George Mount if (decorView != null && decorView.getBackground() == null) { 23785b764e22babfe5508286fbad5d7fee12345704fCraig Mautner getWindow().setBackgroundDrawable(new ColorDrawable(Color.BLACK)); 23862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 239700db2a325bced35cebc403f272f988fad522892George Mount ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(mActivity, this, 240700db2a325bced35cebc403f272f988fad522892George Mount mAllSharedElementNames, resultCode, data); 241700db2a325bced35cebc403f272f988fad522892George Mount mActivity.convertToTranslucent(new Activity.TranslucentConversionListener() { 242700db2a325bced35cebc403f272f988fad522892George Mount @Override 243700db2a325bced35cebc403f272f988fad522892George Mount public void onTranslucentConversionComplete(boolean drawComplete) { 244700db2a325bced35cebc403f272f988fad522892George Mount if (!mIsCanceled) { 245700db2a325bced35cebc403f272f988fad522892George Mount fadeOutBackground(); 246700db2a325bced35cebc403f272f988fad522892George Mount } 247700db2a325bced35cebc403f272f988fad522892George Mount } 248700db2a325bced35cebc403f272f988fad522892George Mount }, options); 249700db2a325bced35cebc403f272f988fad522892George Mount startTransition(new Runnable() { 250700db2a325bced35cebc403f272f988fad522892George Mount @Override 251700db2a325bced35cebc403f272f988fad522892George Mount public void run() { 252700db2a325bced35cebc403f272f988fad522892George Mount startExitTransition(); 253700db2a325bced35cebc403f272f988fad522892George Mount } 254700db2a325bced35cebc403f272f988fad522892George Mount }); 255700db2a325bced35cebc403f272f988fad522892George Mount } 25667d924341a1d0994ac68b3b7898d5576edd987b4George Mount } 25767d924341a1d0994ac68b3b7898d5576edd987b4George Mount 258f1abef6fc2194e72af521202ee4b17c10e03c935George Mount public void stop() { 259f1abef6fc2194e72af521202ee4b17c10e03c935George Mount if (mIsReturning && mActivity != null) { 260f1abef6fc2194e72af521202ee4b17c10e03c935George Mount // Override the previous ActivityOptions. We don't want the 261f1abef6fc2194e72af521202ee4b17c10e03c935George Mount // activity to have options since we're essentially canceling the 262f1abef6fc2194e72af521202ee4b17c10e03c935George Mount // transition and finishing right now. 263f1abef6fc2194e72af521202ee4b17c10e03c935George Mount mActivity.convertToTranslucent(null, null); 264f1abef6fc2194e72af521202ee4b17c10e03c935George Mount finish(); 265f1abef6fc2194e72af521202ee4b17c10e03c935George Mount } 266f1abef6fc2194e72af521202ee4b17c10e03c935George Mount } 267f1abef6fc2194e72af521202ee4b17c10e03c935George Mount 26867d924341a1d0994ac68b3b7898d5576edd987b4George Mount private void startExitTransition() { 269f451d8a6d1a454f338e37f99c0867e17ce9e06f1George Mount Transition transition = getExitTransition(); 27048bd13c9cb2627847cf1f7707a084eb354e9c303George Mount ViewGroup decorView = getDecor(); 271b694e080546316a27d22eba759027f6cb0a24705George Mount if (transition != null && decorView != null && mTransitioningViews != null) { 27248bd13c9cb2627847cf1f7707a084eb354e9c303George Mount TransitionManager.beginDelayedTransition(decorView, transition); 273b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount mTransitioningViews.get(0).invalidate(); 274b4c5d7bf218865d28f030c852fd303e127d676dbGeorge Mount } else { 275b4c5d7bf218865d28f030c852fd303e127d676dbGeorge Mount transitionStarted(); 276c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 27731a217290cf376d0573fc36e21c8940987485019George Mount } 27831a217290cf376d0573fc36e21c8940987485019George Mount 27962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount private void fadeOutBackground() { 2808cab50afda0d8485436f72a93d668697f549d3b3George Mount if (mBackgroundAnimator == null) { 281700db2a325bced35cebc403f272f988fad522892George Mount ViewGroup decor = getDecor(); 282700db2a325bced35cebc403f272f988fad522892George Mount Drawable background; 283700db2a325bced35cebc403f272f988fad522892George Mount if (decor != null && (background = decor.getBackground()) != null) { 28499c82fd1de23deeb8cf640bb574c76af76429df6George Mount background = background.mutate(); 28599c82fd1de23deeb8cf640bb574c76af76429df6George Mount getWindow().setBackgroundDrawable(background); 286700db2a325bced35cebc403f272f988fad522892George Mount mBackgroundAnimator = ObjectAnimator.ofInt(background, "alpha", 0); 287700db2a325bced35cebc403f272f988fad522892George Mount mBackgroundAnimator.addListener(new AnimatorListenerAdapter() { 288700db2a325bced35cebc403f272f988fad522892George Mount @Override 289700db2a325bced35cebc403f272f988fad522892George Mount public void onAnimationEnd(Animator animation) { 290700db2a325bced35cebc403f272f988fad522892George Mount mBackgroundAnimator = null; 291700db2a325bced35cebc403f272f988fad522892George Mount if (!mIsCanceled) { 292700db2a325bced35cebc403f272f988fad522892George Mount mIsBackgroundReady = true; 293700db2a325bced35cebc403f272f988fad522892George Mount notifyComplete(); 294700db2a325bced35cebc403f272f988fad522892George Mount } 2958cab50afda0d8485436f72a93d668697f549d3b3George Mount } 296700db2a325bced35cebc403f272f988fad522892George Mount }); 297700db2a325bced35cebc403f272f988fad522892George Mount mBackgroundAnimator.setDuration(getFadeDuration()); 298700db2a325bced35cebc403f272f988fad522892George Mount mBackgroundAnimator.start(); 299b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount } else { 300b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount mIsBackgroundReady = true; 301700db2a325bced35cebc403f272f988fad522892George Mount } 3028cab50afda0d8485436f72a93d668697f549d3b3George Mount } 30331a217290cf376d0573fc36e21c8940987485019George Mount } 30431a217290cf376d0573fc36e21c8940987485019George Mount 305c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount private Transition getExitTransition() { 306c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Transition viewsTransition = null; 307b694e080546316a27d22eba759027f6cb0a24705George Mount if (mTransitioningViews != null && !mTransitioningViews.isEmpty()) { 3088881502da5b319e139ab85c1825d2d2d239356a1George Mount viewsTransition = configureTransition(getViewsTransition(), true); 309c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 310c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (viewsTransition == null) { 311c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount exitTransitionComplete(); 31262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } else { 313b694e080546316a27d22eba759027f6cb0a24705George Mount final ArrayList<View> transitioningViews = mTransitioningViews; 31467d924341a1d0994ac68b3b7898d5576edd987b4George Mount viewsTransition.addListener(new ContinueTransitionListener() { 31562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount @Override 31662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public void onTransitionEnd(Transition transition) { 317a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount transition.removeListener(this); 318c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount exitTransitionComplete(); 319b694e080546316a27d22eba759027f6cb0a24705George Mount if (mIsHidden && transitioningViews != null) { 320b694e080546316a27d22eba759027f6cb0a24705George Mount showViews(transitioningViews, true); 321c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 322fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount if (mSharedElementBundle != null) { 323fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount delayCancel(); 324fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 325fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount super.onTransitionEnd(transition); 32662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 32762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount }); 328b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount viewsTransition.forceVisibility(View.INVISIBLE, false); 32962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 330c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return viewsTransition; 331c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 332c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 333c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount private Transition getSharedElementExitTransition() { 334c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Transition sharedElementTransition = null; 335c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (!mSharedElements.isEmpty()) { 3368881502da5b319e139ab85c1825d2d2d239356a1George Mount sharedElementTransition = configureTransition(getSharedElementTransition(), false); 337c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 338c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (sharedElementTransition == null) { 339c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount sharedElementTransitionComplete(); 34062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } else { 34167d924341a1d0994ac68b3b7898d5576edd987b4George Mount sharedElementTransition.addListener(new ContinueTransitionListener() { 34262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount @Override 34362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public void onTransitionEnd(Transition transition) { 344a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount transition.removeListener(this); 345c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount sharedElementTransitionComplete(); 3468cab50afda0d8485436f72a93d668697f549d3b3George Mount if (mIsHidden) { 347ce2ee3d6de670e52abed7f432778701113ba9c07George Mount showViews(mSharedElements, true); 3488cab50afda0d8485436f72a93d668697f549d3b3George Mount } 34962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 35062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount }); 351c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount mSharedElements.get(0).invalidate(); 35262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 353c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return sharedElementTransition; 354c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 355c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 356c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount private void beginTransitions() { 357c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Transition sharedElementTransition = getSharedElementExitTransition(); 358c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Transition viewsTransition = getExitTransition(); 35962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount 36062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount Transition transition = mergeTransitions(sharedElementTransition, viewsTransition); 36148bd13c9cb2627847cf1f7707a084eb354e9c303George Mount ViewGroup decorView = getDecor(); 36248bd13c9cb2627847cf1f7707a084eb354e9c303George Mount if (transition != null && decorView != null) { 363fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount setGhostVisibility(View.INVISIBLE); 364fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount scheduleGhostVisibilityChange(View.INVISIBLE); 36548bd13c9cb2627847cf1f7707a084eb354e9c303George Mount TransitionManager.beginDelayedTransition(decorView, transition); 366fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount scheduleGhostVisibilityChange(View.VISIBLE); 367fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount setGhostVisibility(View.VISIBLE); 36848bd13c9cb2627847cf1f7707a084eb354e9c303George Mount decorView.invalidate(); 369b4c5d7bf218865d28f030c852fd303e127d676dbGeorge Mount } else { 370b4c5d7bf218865d28f030c852fd303e127d676dbGeorge Mount transitionStarted(); 371a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount } 37262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 37362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount 37462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount private void exitTransitionComplete() { 37531a217290cf376d0573fc36e21c8940987485019George Mount mExitComplete = true; 37662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount notifyComplete(); 37731a217290cf376d0573fc36e21c8940987485019George Mount } 37831a217290cf376d0573fc36e21c8940987485019George Mount 37962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected boolean isReadyToNotify() { 38067d924341a1d0994ac68b3b7898d5576edd987b4George Mount return mSharedElementBundle != null && mResultReceiver != null && mIsBackgroundReady; 38131a217290cf376d0573fc36e21c8940987485019George Mount } 38231a217290cf376d0573fc36e21c8940987485019George Mount 38362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount private void sharedElementTransitionComplete() { 38467d924341a1d0994ac68b3b7898d5576edd987b4George Mount mSharedElementBundle = mExitSharedElementBundle == null 38567d924341a1d0994ac68b3b7898d5576edd987b4George Mount ? captureSharedElementState() : captureExitSharedElementsState(); 38662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount notifyComplete(); 38731a217290cf376d0573fc36e21c8940987485019George Mount } 38831a217290cf376d0573fc36e21c8940987485019George Mount 38967d924341a1d0994ac68b3b7898d5576edd987b4George Mount private Bundle captureExitSharedElementsState() { 39067d924341a1d0994ac68b3b7898d5576edd987b4George Mount Bundle bundle = new Bundle(); 3917bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu RectF bounds = new RectF(); 3927bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu Matrix matrix = new Matrix(); 39301e9a97fe68dbba42a0edd0ad965ccfe2b8efe7dGeorge Mount for (int i = 0; i < mSharedElements.size(); i++) { 39467d924341a1d0994ac68b3b7898d5576edd987b4George Mount String name = mSharedElementNames.get(i); 39567d924341a1d0994ac68b3b7898d5576edd987b4George Mount Bundle sharedElementState = mExitSharedElementBundle.getBundle(name); 39667d924341a1d0994ac68b3b7898d5576edd987b4George Mount if (sharedElementState != null) { 39767d924341a1d0994ac68b3b7898d5576edd987b4George Mount bundle.putBundle(name, sharedElementState); 39867d924341a1d0994ac68b3b7898d5576edd987b4George Mount } else { 39967d924341a1d0994ac68b3b7898d5576edd987b4George Mount View view = mSharedElements.get(i); 4007bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu captureSharedElementState(view, name, bundle, matrix, bounds); 40167d924341a1d0994ac68b3b7898d5576edd987b4George Mount } 40267d924341a1d0994ac68b3b7898d5576edd987b4George Mount } 40367d924341a1d0994ac68b3b7898d5576edd987b4George Mount return bundle; 40467d924341a1d0994ac68b3b7898d5576edd987b4George Mount } 40567d924341a1d0994ac68b3b7898d5576edd987b4George Mount 40662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected void notifyComplete() { 40762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount if (isReadyToNotify()) { 40862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount if (!mSharedElementNotified) { 40962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mSharedElementNotified = true; 410fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount delayCancel(); 41162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mResultReceiver.send(MSG_TAKE_SHARED_ELEMENTS, mSharedElementBundle); 41262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 41362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount if (!mExitNotified && mExitComplete) { 41462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mExitNotified = true; 41562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mResultReceiver.send(MSG_EXIT_TRANSITION_COMPLETE, null); 41662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mResultReceiver = null; // done talking 41748bd13c9cb2627847cf1f7707a084eb354e9c303George Mount ViewGroup decorView = getDecor(); 41848bd13c9cb2627847cf1f7707a084eb354e9c303George Mount if (!mIsReturning && decorView != null) { 41948bd13c9cb2627847cf1f7707a084eb354e9c303George Mount decorView.suppressLayout(false); 420f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu } 421c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount finishIfNecessary(); 42262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 42331a217290cf376d0573fc36e21c8940987485019George Mount } 42431a217290cf376d0573fc36e21c8940987485019George Mount } 42531a217290cf376d0573fc36e21c8940987485019George Mount 426c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount private void finishIfNecessary() { 427e678ab686643127b4b297ae7a1e4869b4cfc6e53George Mount if (mIsReturning && mExitNotified && mActivity != null && (mSharedElements.isEmpty() || 428b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount mSharedElementsHidden)) { 429a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount finish(); 430c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 431c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (!mIsReturning && mExitNotified) { 432c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount mActivity = null; // don't need it anymore 433c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 434c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 435c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 436a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount private void finish() { 437fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount stopCancel(); 438f1abef6fc2194e72af521202ee4b17c10e03c935George Mount if (mActivity != null) { 439f1abef6fc2194e72af521202ee4b17c10e03c935George Mount mActivity.mActivityTransitionState.clear(); 440f1abef6fc2194e72af521202ee4b17c10e03c935George Mount mActivity.finish(); 441f1abef6fc2194e72af521202ee4b17c10e03c935George Mount mActivity.overridePendingTransition(0, 0); 442f1abef6fc2194e72af521202ee4b17c10e03c935George Mount mActivity = null; 443f1abef6fc2194e72af521202ee4b17c10e03c935George Mount } 444a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount // Clear the state so that we can't hold any references accidentally and leak memory. 445a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount mHandler = null; 446a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount mSharedElementBundle = null; 447a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount if (mBackgroundAnimator != null) { 448a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount mBackgroundAnimator.cancel(); 449a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount mBackgroundAnimator = null; 450a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount } 451a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount mExitSharedElementBundle = null; 452a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount clearState(); 453a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount } 454a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount 455a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount @Override 456fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount protected boolean moveSharedElementWithParent() { 457fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount return !mIsReturning; 458fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 459fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 460fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount @Override 461a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount protected Transition getViewsTransition() { 462a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount if (mIsReturning) { 46368f96d8db5e5e701b6a12b5cddecc985e56a26c6George Mount return getWindow().getReturnTransition(); 464a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount } else { 465a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount return getWindow().getExitTransition(); 466a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount } 467a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount } 468a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount 469a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount protected Transition getSharedElementTransition() { 470a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount if (mIsReturning) { 47168f96d8db5e5e701b6a12b5cddecc985e56a26c6George Mount return getWindow().getSharedElementReturnTransition(); 472a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount } else { 473a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount return getWindow().getSharedElementExitTransition(); 474a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount } 475a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount } 47631a217290cf376d0573fc36e21c8940987485019George Mount} 477