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
18c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.content.Context;
19c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.graphics.Matrix;
2031a217290cf376d0573fc36e21c8940987485019George Mountimport android.graphics.Rect;
217bf379c8af399626d5b8b568fe1d4f96f56badccDake Guimport android.graphics.RectF;
22c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.os.Bundle;
2331a217290cf376d0573fc36e21c8940987485019George Mountimport android.os.Handler;
24480ca829e2d3313740b4d14d30afbea6c98ff965George Mountimport android.os.Parcelable;
2531a217290cf376d0573fc36e21c8940987485019George Mountimport android.os.ResultReceiver;
2631a217290cf376d0573fc36e21c8940987485019George Mountimport android.transition.Transition;
27e0c37bdea37f78778f6c4f23f03604e59dfb0d55Ben Weissimport android.transition.TransitionListenerAdapter;
2831a217290cf376d0573fc36e21c8940987485019George Mountimport android.transition.TransitionSet;
291349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mountimport android.transition.Visibility;
3031a217290cf376d0573fc36e21c8940987485019George Mountimport android.util.ArrayMap;
31f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mountimport android.util.ArraySet;
32fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mountimport android.view.GhostView;
3331a217290cf376d0573fc36e21c8940987485019George Mountimport android.view.View;
3431a217290cf376d0573fc36e21c8940987485019George Mountimport android.view.ViewGroup;
35fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mountimport android.view.ViewGroupOverlay;
36fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mountimport android.view.ViewParent;
3741725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mountimport android.view.ViewRootImpl;
38c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.view.ViewTreeObserver;
3931a217290cf376d0573fc36e21c8940987485019George Mountimport android.view.Window;
40caa03107d4322b0e30f92e6dc1eb1ea73b1bf747George Mountimport android.widget.ImageView;
4131a217290cf376d0573fc36e21c8940987485019George Mount
42f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mountimport com.android.internal.view.OneShotPreDrawListener;
43f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount
4431a217290cf376d0573fc36e21c8940987485019George Mountimport java.util.ArrayList;
4531a217290cf376d0573fc36e21c8940987485019George Mountimport java.util.Collection;
4631a217290cf376d0573fc36e21c8940987485019George Mount
4731a217290cf376d0573fc36e21c8940987485019George Mount/**
4831a217290cf376d0573fc36e21c8940987485019George Mount * Base class for ExitTransitionCoordinator and EnterTransitionCoordinator, classes
4931a217290cf376d0573fc36e21c8940987485019George Mount * that manage activity transitions and the communications coordinating them between
5031a217290cf376d0573fc36e21c8940987485019George Mount * Activities. The ExitTransitionCoordinator is created in the
5131a217290cf376d0573fc36e21c8940987485019George Mount * ActivityOptions#makeSceneTransitionAnimation. The EnterTransitionCoordinator
5231a217290cf376d0573fc36e21c8940987485019George Mount * is created by ActivityOptions#createEnterActivityTransition by Activity when the window is
5331a217290cf376d0573fc36e21c8940987485019George Mount * attached.
5431a217290cf376d0573fc36e21c8940987485019George Mount *
5531a217290cf376d0573fc36e21c8940987485019George Mount * Typical startActivity goes like this:
5631a217290cf376d0573fc36e21c8940987485019George Mount * 1) ExitTransitionCoordinator created with ActivityOptions#makeSceneTransitionAnimation
5731a217290cf376d0573fc36e21c8940987485019George Mount * 2) Activity#startActivity called and that calls startExit() through
5831a217290cf376d0573fc36e21c8940987485019George Mount *    ActivityOptions#dispatchStartExit
5931a217290cf376d0573fc36e21c8940987485019George Mount *    - Exit transition starts by setting transitioning Views to INVISIBLE
6031a217290cf376d0573fc36e21c8940987485019George Mount * 3) Launched Activity starts, creating an EnterTransitionCoordinator.
6131a217290cf376d0573fc36e21c8940987485019George Mount *    - The Window is made translucent
6231a217290cf376d0573fc36e21c8940987485019George Mount *    - The Window background alpha is set to 0
6331a217290cf376d0573fc36e21c8940987485019George Mount *    - The transitioning views are made INVISIBLE
6431a217290cf376d0573fc36e21c8940987485019George Mount *    - MSG_SET_LISTENER is sent back to the ExitTransitionCoordinator.
6531a217290cf376d0573fc36e21c8940987485019George Mount * 4) The shared element transition completes.
6631a217290cf376d0573fc36e21c8940987485019George Mount *    - MSG_TAKE_SHARED_ELEMENTS is sent to the EnterTransitionCoordinator
6731a217290cf376d0573fc36e21c8940987485019George Mount * 5) The MSG_TAKE_SHARED_ELEMENTS is received by the EnterTransitionCoordinator.
6831a217290cf376d0573fc36e21c8940987485019George Mount *    - Shared elements are made VISIBLE
6931a217290cf376d0573fc36e21c8940987485019George Mount *    - Shared elements positions and size are set to match the end state of the calling
7031a217290cf376d0573fc36e21c8940987485019George Mount *      Activity.
7131a217290cf376d0573fc36e21c8940987485019George Mount *    - The shared element transition is started
7231a217290cf376d0573fc36e21c8940987485019George Mount *    - If the window allows overlapping transitions, the views transition is started by setting
7331a217290cf376d0573fc36e21c8940987485019George Mount *      the entering Views to VISIBLE and the background alpha is animated to opaque.
7431a217290cf376d0573fc36e21c8940987485019George Mount *    - MSG_HIDE_SHARED_ELEMENTS is sent to the ExitTransitionCoordinator
7531a217290cf376d0573fc36e21c8940987485019George Mount * 6) MSG_HIDE_SHARED_ELEMENTS is received by the ExitTransitionCoordinator
7631a217290cf376d0573fc36e21c8940987485019George Mount *    - The shared elements are made INVISIBLE
7731a217290cf376d0573fc36e21c8940987485019George Mount * 7) The exit transition completes in the calling Activity.
7831a217290cf376d0573fc36e21c8940987485019George Mount *    - MSG_EXIT_TRANSITION_COMPLETE is sent to the EnterTransitionCoordinator.
7931a217290cf376d0573fc36e21c8940987485019George Mount * 8) The MSG_EXIT_TRANSITION_COMPLETE is received by the EnterTransitionCoordinator.
8031a217290cf376d0573fc36e21c8940987485019George Mount *    - If the window doesn't allow overlapping enter transitions, the enter transition is started
8131a217290cf376d0573fc36e21c8940987485019George Mount *      by setting entering views to VISIBLE and the background is animated to opaque.
8231a217290cf376d0573fc36e21c8940987485019George Mount * 9) The background opacity animation completes.
8331a217290cf376d0573fc36e21c8940987485019George Mount *    - The window is made opaque
8431a217290cf376d0573fc36e21c8940987485019George Mount * 10) The calling Activity gets an onStop() call
8531a217290cf376d0573fc36e21c8940987485019George Mount *    - onActivityStopped() is called and all exited Views are made VISIBLE.
8631a217290cf376d0573fc36e21c8940987485019George Mount *
8773f843de4b65772c624ca8ebb8c976a279e37ce9Craig Mautner * Typical finishAfterTransition goes like this:
8873f843de4b65772c624ca8ebb8c976a279e37ce9Craig Mautner * 1) finishAfterTransition() creates an ExitTransitionCoordinator and calls startExit()
8962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount *    - The Window start transitioning to Translucent with a new ActivityOptions.
9031a217290cf376d0573fc36e21c8940987485019George Mount *    - If no background exists, a black background is substituted
9131a217290cf376d0573fc36e21c8940987485019George Mount *    - The shared elements in the scene are matched against those shared elements
9231a217290cf376d0573fc36e21c8940987485019George Mount *      that were sent by comparing the names.
9331a217290cf376d0573fc36e21c8940987485019George Mount *    - The exit transition is started by setting Views to INVISIBLE.
9462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * 2) The ActivityOptions is received by the Activity and an EnterTransitionCoordinator is created.
9531a217290cf376d0573fc36e21c8940987485019George Mount *    - All transitioning views are made VISIBLE to reverse what was done when onActivityStopped()
9631a217290cf376d0573fc36e21c8940987485019George Mount *      was called
9731a217290cf376d0573fc36e21c8940987485019George Mount * 3) The Window is made translucent and a callback is received
9831a217290cf376d0573fc36e21c8940987485019George Mount *    - The background alpha is animated to 0
9931a217290cf376d0573fc36e21c8940987485019George Mount * 4) The background alpha animation completes
10031a217290cf376d0573fc36e21c8940987485019George Mount * 5) The shared element transition completes
10131a217290cf376d0573fc36e21c8940987485019George Mount *    - After both 4 & 5 complete, MSG_TAKE_SHARED_ELEMENTS is sent to the
10262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount *      EnterTransitionCoordinator
10362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * 6) MSG_TAKE_SHARED_ELEMENTS is received by EnterTransitionCoordinator
10431a217290cf376d0573fc36e21c8940987485019George Mount *    - Shared elements are made VISIBLE
10531a217290cf376d0573fc36e21c8940987485019George Mount *    - Shared elements positions and size are set to match the end state of the calling
10631a217290cf376d0573fc36e21c8940987485019George Mount *      Activity.
10731a217290cf376d0573fc36e21c8940987485019George Mount *    - The shared element transition is started
10831a217290cf376d0573fc36e21c8940987485019George Mount *    - If the window allows overlapping transitions, the views transition is started by setting
10931a217290cf376d0573fc36e21c8940987485019George Mount *      the entering Views to VISIBLE.
11062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount *    - MSG_HIDE_SHARED_ELEMENTS is sent to the ExitTransitionCoordinator
11162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * 7) MSG_HIDE_SHARED_ELEMENTS is received by the ExitTransitionCoordinator
11231a217290cf376d0573fc36e21c8940987485019George Mount *    - The shared elements are made INVISIBLE
11331a217290cf376d0573fc36e21c8940987485019George Mount * 8) The exit transition completes in the finishing Activity.
11462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount *    - MSG_EXIT_TRANSITION_COMPLETE is sent to the EnterTransitionCoordinator.
11531a217290cf376d0573fc36e21c8940987485019George Mount *    - finish() is called on the exiting Activity
11662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * 9) The MSG_EXIT_TRANSITION_COMPLETE is received by the EnterTransitionCoordinator.
11731a217290cf376d0573fc36e21c8940987485019George Mount *    - If the window doesn't allow overlapping enter transitions, the enter transition is started
11831a217290cf376d0573fc36e21c8940987485019George Mount *      by setting entering views to VISIBLE.
11931a217290cf376d0573fc36e21c8940987485019George Mount */
12031a217290cf376d0573fc36e21c8940987485019George Mountabstract class ActivityTransitionCoordinator extends ResultReceiver {
12131a217290cf376d0573fc36e21c8940987485019George Mount    private static final String TAG = "ActivityTransitionCoordinator";
12231a217290cf376d0573fc36e21c8940987485019George Mount
12331a217290cf376d0573fc36e21c8940987485019George Mount    /**
12431a217290cf376d0573fc36e21c8940987485019George Mount     * For Activity transitions, the called Activity's listener to receive calls
12531a217290cf376d0573fc36e21c8940987485019George Mount     * when transitions complete.
12631a217290cf376d0573fc36e21c8940987485019George Mount     */
12762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    static final String KEY_REMOTE_RECEIVER = "android:remoteReceiver";
12862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
1297bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu    protected static final String KEY_SCREEN_LEFT = "shared_element:screenLeft";
1307bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu    protected static final String KEY_SCREEN_TOP = "shared_element:screenTop";
1317bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu    protected static final String KEY_SCREEN_RIGHT = "shared_element:screenRight";
1327bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu    protected static final String KEY_SCREEN_BOTTOM= "shared_element:screenBottom";
13362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    protected static final String KEY_TRANSLATION_Z = "shared_element:translationZ";
134480ca829e2d3313740b4d14d30afbea6c98ff965George Mount    protected static final String KEY_SNAPSHOT = "shared_element:bitmap";
13562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    protected static final String KEY_SCALE_TYPE = "shared_element:scaleType";
13662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    protected static final String KEY_IMAGE_MATRIX = "shared_element:imageMatrix";
13726c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount    protected static final String KEY_ELEVATION = "shared_element:elevation";
13831a217290cf376d0573fc36e21c8940987485019George Mount
13962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    protected static final ImageView.ScaleType[] SCALE_TYPE_VALUES = ImageView.ScaleType.values();
14031a217290cf376d0573fc36e21c8940987485019George Mount
14131a217290cf376d0573fc36e21c8940987485019George Mount    /**
14231a217290cf376d0573fc36e21c8940987485019George Mount     * Sent by the exiting coordinator (either EnterTransitionCoordinator
14331a217290cf376d0573fc36e21c8940987485019George Mount     * or ExitTransitionCoordinator) after the shared elements have
14431a217290cf376d0573fc36e21c8940987485019George Mount     * become stationary (shared element transition completes). This tells
14531a217290cf376d0573fc36e21c8940987485019George Mount     * the remote coordinator to take control of the shared elements and
14631a217290cf376d0573fc36e21c8940987485019George Mount     * that animations may begin. The remote Activity won't start entering
14731a217290cf376d0573fc36e21c8940987485019George Mount     * until this message is received, but may wait for
14831a217290cf376d0573fc36e21c8940987485019George Mount     * MSG_EXIT_TRANSITION_COMPLETE if allowOverlappingTransitions() is true.
14931a217290cf376d0573fc36e21c8940987485019George Mount     */
15062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    public static final int MSG_SET_REMOTE_RECEIVER = 100;
15131a217290cf376d0573fc36e21c8940987485019George Mount
15231a217290cf376d0573fc36e21c8940987485019George Mount    /**
15331a217290cf376d0573fc36e21c8940987485019George Mount     * Sent by the entering coordinator to tell the exiting coordinator
15431a217290cf376d0573fc36e21c8940987485019George Mount     * to hide its shared elements after it has started its shared
15531a217290cf376d0573fc36e21c8940987485019George Mount     * element transition. This is temporary until the
15631a217290cf376d0573fc36e21c8940987485019George Mount     * interlock of shared elements is figured out.
15731a217290cf376d0573fc36e21c8940987485019George Mount     */
15831a217290cf376d0573fc36e21c8940987485019George Mount    public static final int MSG_HIDE_SHARED_ELEMENTS = 101;
15931a217290cf376d0573fc36e21c8940987485019George Mount
16031a217290cf376d0573fc36e21c8940987485019George Mount    /**
16131a217290cf376d0573fc36e21c8940987485019George Mount     * Sent by the exiting coordinator (either EnterTransitionCoordinator
16231a217290cf376d0573fc36e21c8940987485019George Mount     * or ExitTransitionCoordinator) after the shared elements have
16331a217290cf376d0573fc36e21c8940987485019George Mount     * become stationary (shared element transition completes). This tells
16431a217290cf376d0573fc36e21c8940987485019George Mount     * the remote coordinator to take control of the shared elements and
16531a217290cf376d0573fc36e21c8940987485019George Mount     * that animations may begin. The remote Activity won't start entering
16631a217290cf376d0573fc36e21c8940987485019George Mount     * until this message is received, but may wait for
16731a217290cf376d0573fc36e21c8940987485019George Mount     * MSG_EXIT_TRANSITION_COMPLETE if allowOverlappingTransitions() is true.
16831a217290cf376d0573fc36e21c8940987485019George Mount     */
16962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    public static final int MSG_TAKE_SHARED_ELEMENTS = 103;
17031a217290cf376d0573fc36e21c8940987485019George Mount
17131a217290cf376d0573fc36e21c8940987485019George Mount    /**
17231a217290cf376d0573fc36e21c8940987485019George Mount     * Sent by the exiting coordinator (either
17331a217290cf376d0573fc36e21c8940987485019George Mount     * EnterTransitionCoordinator or ExitTransitionCoordinator) after
17431a217290cf376d0573fc36e21c8940987485019George Mount     * the exiting Views have finished leaving the scene. This will
17531a217290cf376d0573fc36e21c8940987485019George Mount     * be ignored if allowOverlappingTransitions() is true on the
17631a217290cf376d0573fc36e21c8940987485019George Mount     * remote coordinator. If it is false, it will trigger the enter
17731a217290cf376d0573fc36e21c8940987485019George Mount     * transition to start.
17831a217290cf376d0573fc36e21c8940987485019George Mount     */
17962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    public static final int MSG_EXIT_TRANSITION_COMPLETE = 104;
18031a217290cf376d0573fc36e21c8940987485019George Mount
18131a217290cf376d0573fc36e21c8940987485019George Mount    /**
18231a217290cf376d0573fc36e21c8940987485019George Mount     * Sent by Activity#startActivity to begin the exit transition.
18331a217290cf376d0573fc36e21c8940987485019George Mount     */
18462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    public static final int MSG_START_EXIT_TRANSITION = 105;
18531a217290cf376d0573fc36e21c8940987485019George Mount
18631a217290cf376d0573fc36e21c8940987485019George Mount    /**
18762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount     * It took too long for a message from the entering Activity, so we canceled the transition.
18831a217290cf376d0573fc36e21c8940987485019George Mount     */
18962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    public static final int MSG_CANCEL = 106;
19062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
191c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    /**
192c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount     * When returning, this is the destination location for the shared element.
193c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount     */
194c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    public static final int MSG_SHARED_ELEMENT_DESTINATION = 107;
195c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
196a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount    private Window mWindow;
19762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    final protected ArrayList<String> mAllSharedElementNames;
19862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    final protected ArrayList<View> mSharedElements = new ArrayList<View>();
19962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    final protected ArrayList<String> mSharedElementNames = new ArrayList<String>();
200b694e080546316a27d22eba759027f6cb0a24705George Mount    protected ArrayList<View> mTransitioningViews = new ArrayList<View>();
2016558056e8fccc32f9e1dc59e46d09f8d916b7538George Mount    protected SharedElementCallback mListener;
20262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    protected ResultReceiver mResultReceiver;
20362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    final private FixedEpicenterCallback mEpicenterCallback = new FixedEpicenterCallback();
204c9b6df8fa4df3968b2420a52c5281b4765478f68George Mount    final protected boolean mIsReturning;
20567d924341a1d0994ac68b3b7898d5576edd987b4George Mount    private Runnable mPendingTransition;
20667d924341a1d0994ac68b3b7898d5576edd987b4George Mount    private boolean mIsStartingTransition;
207fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    private ArrayList<GhostViewListeners> mGhostViewListeners =
208fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            new ArrayList<GhostViewListeners>();
2090f0c473488f8e8becc8883d3cdd9610324610dc4George Mount    private ArrayMap<View, Float> mOriginalAlphas = new ArrayMap<View, Float>();
210333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount    private ArrayList<Matrix> mSharedElementParentMatrices;
21141725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount    private boolean mSharedElementTransitionComplete;
21241725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount    private boolean mViewsTransitionComplete;
213b64e777f6c14d862f221f4da814079df22663db1Chet Haase    private boolean mBackgroundAnimatorComplete;
214aae763e692810fb411b83fdda57567e1b66577ddGeorge Mount    private ArrayList<View> mStrippedTransitioningViews = new ArrayList<>();
21567d924341a1d0994ac68b3b7898d5576edd987b4George Mount
2168c2614ce4328640642d8e8be437859e0508a39b4George Mount    public ActivityTransitionCoordinator(Window window,
2178c2614ce4328640642d8e8be437859e0508a39b4George Mount            ArrayList<String> allSharedElementNames,
2186558056e8fccc32f9e1dc59e46d09f8d916b7538George Mount            SharedElementCallback listener, boolean isReturning) {
21962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        super(new Handler());
22062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        mWindow = window;
22162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        mListener = listener;
22262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        mAllSharedElementNames = allSharedElementNames;
223c9b6df8fa4df3968b2420a52c5281b4765478f68George Mount        mIsReturning = isReturning;
2248c2614ce4328640642d8e8be437859e0508a39b4George Mount    }
2258c2614ce4328640642d8e8be437859e0508a39b4George Mount
2261fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount    protected void viewsReady(ArrayMap<String, View> sharedElements) {
227ce725a47f6eee75a6ef86397e9b9fe471aeb1f84George Mount        sharedElements.retainAll(mAllSharedElementNames);
2281732f528952ea2df0bfd503fabb958af03dbfc81George Mount        if (mListener != null) {
2291732f528952ea2df0bfd503fabb958af03dbfc81George Mount            mListener.onMapSharedElements(mAllSharedElementNames, sharedElements);
2301732f528952ea2df0bfd503fabb958af03dbfc81George Mount        }
231333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        setSharedElements(sharedElements);
232b694e080546316a27d22eba759027f6cb0a24705George Mount        if (getViewsTransition() != null && mTransitioningViews != null) {
23348bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            ViewGroup decorView = getDecor();
23448bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            if (decorView != null) {
23548bd13c9cb2627847cf1f7707a084eb354e9c303George Mount                decorView.captureTransitioningViews(mTransitioningViews);
23648bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            }
23762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            mTransitioningViews.removeAll(mSharedElements);
23831a217290cf376d0573fc36e21c8940987485019George Mount        }
23962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        setEpicenter();
24031a217290cf376d0573fc36e21c8940987485019George Mount    }
24131a217290cf376d0573fc36e21c8940987485019George Mount
242333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount    /**
243333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount     * Iterates over the shared elements and adds them to the members in order.
244333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount     * Shared elements that are nested in other shared elements are placed after the
245333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount     * elements that they are nested in. This means that layout ordering can be done
246333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount     * from first to last.
247333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount     *
248333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount     * @param sharedElements The map of transition names to shared elements to set into
249333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount     *                       the member fields.
250333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount     */
251333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount    private void setSharedElements(ArrayMap<String, View> sharedElements) {
252333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        boolean isFirstRun = true;
253333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        while (!sharedElements.isEmpty()) {
254333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            final int numSharedElements = sharedElements.size();
255333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            for (int i = numSharedElements - 1; i >= 0; i--) {
256333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount                final View view = sharedElements.valueAt(i);
257333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount                final String name = sharedElements.keyAt(i);
258333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount                if (isFirstRun && (view == null || !view.isAttachedToWindow() || name == null)) {
259333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount                    sharedElements.removeAt(i);
26042161c5cb4f5f36cf83c8af3f20db70a70850a88George Mount                } else if (!isNested(view, sharedElements)) {
26142161c5cb4f5f36cf83c8af3f20db70a70850a88George Mount                    mSharedElementNames.add(name);
26242161c5cb4f5f36cf83c8af3f20db70a70850a88George Mount                    mSharedElements.add(view);
26342161c5cb4f5f36cf83c8af3f20db70a70850a88George Mount                    sharedElements.removeAt(i);
264333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount                }
265333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            }
266333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            isFirstRun = false;
267333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        }
268333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount    }
269333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount
270333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount    /**
271333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount     * Returns true when view is nested in any of the values of sharedElements.
272333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount     */
273333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount    private static boolean isNested(View view, ArrayMap<String, View> sharedElements) {
274333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        ViewParent parent = view.getParent();
275333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        boolean isNested = false;
276333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        while (parent instanceof View) {
277333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            View parentView = (View) parent;
278333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            if (sharedElements.containsValue(parentView)) {
279333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount                isNested = true;
280333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount                break;
281333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            }
282333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            parent = parentView.getParent();
283333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        }
284333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        return isNested;
285333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount    }
286333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount
28760625b02ac099bacc96a387ec270751745dafae0George Mount    protected void stripOffscreenViews() {
288b694e080546316a27d22eba759027f6cb0a24705George Mount        if (mTransitioningViews == null) {
289b694e080546316a27d22eba759027f6cb0a24705George Mount            return;
290b694e080546316a27d22eba759027f6cb0a24705George Mount        }
29160625b02ac099bacc96a387ec270751745dafae0George Mount        Rect r = new Rect();
29260625b02ac099bacc96a387ec270751745dafae0George Mount        for (int i = mTransitioningViews.size() - 1; i >= 0; i--) {
29360625b02ac099bacc96a387ec270751745dafae0George Mount            View view = mTransitioningViews.get(i);
29460625b02ac099bacc96a387ec270751745dafae0George Mount            if (!view.getGlobalVisibleRect(r)) {
29560625b02ac099bacc96a387ec270751745dafae0George Mount                mTransitioningViews.remove(i);
296aae763e692810fb411b83fdda57567e1b66577ddGeorge Mount                mStrippedTransitioningViews.add(view);
29760625b02ac099bacc96a387ec270751745dafae0George Mount            }
29860625b02ac099bacc96a387ec270751745dafae0George Mount        }
29960625b02ac099bacc96a387ec270751745dafae0George Mount    }
30060625b02ac099bacc96a387ec270751745dafae0George Mount
30131a217290cf376d0573fc36e21c8940987485019George Mount    protected Window getWindow() {
30231a217290cf376d0573fc36e21c8940987485019George Mount        return mWindow;
30331a217290cf376d0573fc36e21c8940987485019George Mount    }
30431a217290cf376d0573fc36e21c8940987485019George Mount
305a2bbbb3bac464c3a52e33008401fed4a7542744cGeorge Mount    public ViewGroup getDecor() {
30631a217290cf376d0573fc36e21c8940987485019George Mount        return (mWindow == null) ? null : (ViewGroup) mWindow.getDecorView();
30731a217290cf376d0573fc36e21c8940987485019George Mount    }
30831a217290cf376d0573fc36e21c8940987485019George Mount
30962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    /**
31062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount     * Sets the transition epicenter to the position of the first shared element.
31162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount     */
31262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    protected void setEpicenter() {
31362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        View epicenter = null;
314c6186bffe477b996e388046e8761908b813fd07fGeorge Mount        if (!mAllSharedElementNames.isEmpty() && !mSharedElementNames.isEmpty()) {
315c6186bffe477b996e388046e8761908b813fd07fGeorge Mount            int index = mSharedElementNames.indexOf(mAllSharedElementNames.get(0));
316c6186bffe477b996e388046e8761908b813fd07fGeorge Mount            if (index >= 0) {
317c6186bffe477b996e388046e8761908b813fd07fGeorge Mount                epicenter = mSharedElements.get(index);
318c6186bffe477b996e388046e8761908b813fd07fGeorge Mount            }
31931a217290cf376d0573fc36e21c8940987485019George Mount        }
32062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        setEpicenter(epicenter);
32131a217290cf376d0573fc36e21c8940987485019George Mount    }
32231a217290cf376d0573fc36e21c8940987485019George Mount
32362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private void setEpicenter(View view) {
32462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        if (view == null) {
32562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            mEpicenterCallback.setEpicenter(null);
32631a217290cf376d0573fc36e21c8940987485019George Mount        } else {
3278e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount            Rect epicenter = new Rect();
3288e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount            view.getBoundsOnScreen(epicenter);
32962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            mEpicenterCallback.setEpicenter(epicenter);
33031a217290cf376d0573fc36e21c8940987485019George Mount        }
33131a217290cf376d0573fc36e21c8940987485019George Mount    }
33231a217290cf376d0573fc36e21c8940987485019George Mount
33362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    public ArrayList<String> getAcceptedNames() {
33462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        return mSharedElementNames;
33531a217290cf376d0573fc36e21c8940987485019George Mount    }
33631a217290cf376d0573fc36e21c8940987485019George Mount
33762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    public ArrayList<String> getMappedNames() {
33862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        ArrayList<String> names = new ArrayList<String>(mSharedElements.size());
33962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        for (int i = 0; i < mSharedElements.size(); i++) {
3400a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount            names.add(mSharedElements.get(i).getTransitionName());
341080443bcb63418245c2408500db735fece5e7083George Mount        }
34262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        return names;
34331a217290cf376d0573fc36e21c8940987485019George Mount    }
34431a217290cf376d0573fc36e21c8940987485019George Mount
345700db2a325bced35cebc403f272f988fad522892George Mount    public ArrayList<View> copyMappedViews() {
346700db2a325bced35cebc403f272f988fad522892George Mount        return new ArrayList<View>(mSharedElements);
3471fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount    }
3481fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount
3498c2614ce4328640642d8e8be437859e0508a39b4George Mount    public ArrayList<String> getAllSharedElementNames() { return mAllSharedElementNames; }
3508c2614ce4328640642d8e8be437859e0508a39b4George Mount
3518881502da5b319e139ab85c1825d2d2d239356a1George Mount    protected Transition setTargets(Transition transition, boolean add) {
3528881502da5b319e139ab85c1825d2d2d239356a1George Mount        if (transition == null || (add &&
3538881502da5b319e139ab85c1825d2d2d239356a1George Mount                (mTransitioningViews == null || mTransitioningViews.isEmpty()))) {
35431a217290cf376d0573fc36e21c8940987485019George Mount            return null;
35531a217290cf376d0573fc36e21c8940987485019George Mount        }
356d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        // Add the targets to a set containing transition so that transition
357d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        // remains unaffected. We don't want to modify the targets of transition itself.
35831a217290cf376d0573fc36e21c8940987485019George Mount        TransitionSet set = new TransitionSet();
3598881502da5b319e139ab85c1825d2d2d239356a1George Mount        if (mTransitioningViews != null) {
3608881502da5b319e139ab85c1825d2d2d239356a1George Mount            for (int i = mTransitioningViews.size() - 1; i >= 0; i--) {
3618881502da5b319e139ab85c1825d2d2d239356a1George Mount                View view = mTransitioningViews.get(i);
3628881502da5b319e139ab85c1825d2d2d239356a1George Mount                if (add) {
3638881502da5b319e139ab85c1825d2d2d239356a1George Mount                    set.addTarget(view);
3648881502da5b319e139ab85c1825d2d2d239356a1George Mount                } else {
3658881502da5b319e139ab85c1825d2d2d239356a1George Mount                    set.excludeTarget(view, true);
3668881502da5b319e139ab85c1825d2d2d239356a1George Mount                }
36731a217290cf376d0573fc36e21c8940987485019George Mount            }
36831a217290cf376d0573fc36e21c8940987485019George Mount        }
369aae763e692810fb411b83fdda57567e1b66577ddGeorge Mount        if (mStrippedTransitioningViews != null) {
370aae763e692810fb411b83fdda57567e1b66577ddGeorge Mount            for (int i = mStrippedTransitioningViews.size() - 1; i >= 0; i--) {
371aae763e692810fb411b83fdda57567e1b66577ddGeorge Mount                View view = mStrippedTransitioningViews.get(i);
372aae763e692810fb411b83fdda57567e1b66577ddGeorge Mount                set.excludeTarget(view, true);
373aae763e692810fb411b83fdda57567e1b66577ddGeorge Mount            }
374aae763e692810fb411b83fdda57567e1b66577ddGeorge Mount        }
375d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        // By adding the transition after addTarget, we prevent addTarget from
376d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        // affecting transition.
377d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        set.addTransition(transition);
378fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
379fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        if (!add && mTransitioningViews != null && !mTransitioningViews.isEmpty()) {
380fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            // Allow children of excluded transitioning views, but not the views themselves
381fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            set = new TransitionSet().addTransition(set);
382fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        }
383fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
38431a217290cf376d0573fc36e21c8940987485019George Mount        return set;
38531a217290cf376d0573fc36e21c8940987485019George Mount    }
38631a217290cf376d0573fc36e21c8940987485019George Mount
3878881502da5b319e139ab85c1825d2d2d239356a1George Mount    protected Transition configureTransition(Transition transition,
3888881502da5b319e139ab85c1825d2d2d239356a1George Mount            boolean includeTransitioningViews) {
38931a217290cf376d0573fc36e21c8940987485019George Mount        if (transition != null) {
39062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            transition = transition.clone();
39162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            transition.setEpicenterCallback(mEpicenterCallback);
3928881502da5b319e139ab85c1825d2d2d239356a1George Mount            transition = setTargets(transition, includeTransitioningViews);
39331a217290cf376d0573fc36e21c8940987485019George Mount        }
3941349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount        noLayoutSuppressionForVisibilityTransitions(transition);
39531a217290cf376d0573fc36e21c8940987485019George Mount        return transition;
39631a217290cf376d0573fc36e21c8940987485019George Mount    }
39731a217290cf376d0573fc36e21c8940987485019George Mount
398f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount    /**
399f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     * Looks through the transition to see which Views have been included and which have been
400f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     * excluded. {@code views} will be modified to contain only those Views that are included
401f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     * in the transition. If {@code transition} is a TransitionSet, it will search through all
402f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     * contained Transitions to find targeted Views.
403f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     *
404f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     * @param transition The transition to look through for inclusion of Views
405f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     * @param views The list of Views that are to be checked for inclusion. Will be modified
406f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     *              to remove all excluded Views, possibly leaving an empty list.
407f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     */
408f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount    protected static void removeExcludedViews(Transition transition, ArrayList<View> views) {
409f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount        ArraySet<View> included = new ArraySet<>();
410f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount        findIncludedViews(transition, views, included);
411f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount        views.clear();
412f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount        views.addAll(included);
413f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount    }
414f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount
415f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount    /**
416f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     * Looks through the transition to see which Views have been included. Only {@code views}
417f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     * will be examined for inclusion. If {@code transition} is a TransitionSet, it will search
418f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     * through all contained Transitions to find targeted Views.
419f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     *
420f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     * @param transition The transition to look through for inclusion of Views
421f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     * @param views The list of Views that are to be checked for inclusion.
422f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     * @param included Modified to contain all Views in views that have at least one Transition
423f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     *                 that affects it.
424f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount     */
425f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount    private static void findIncludedViews(Transition transition, ArrayList<View> views,
426f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount            ArraySet<View> included) {
427f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount        if (transition instanceof TransitionSet) {
428f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount            TransitionSet set = (TransitionSet) transition;
429f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount            ArrayList<View> includedViews = new ArrayList<>();
430f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount            final int numViews = views.size();
431f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount            for (int i = 0; i < numViews; i++) {
432f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount                final View view = views.get(i);
433f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount                if (transition.isValidTarget(view)) {
434f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount                    includedViews.add(view);
435f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount                }
436f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount            }
437f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount            final int count = set.getTransitionCount();
438f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount            for (int i = 0; i < count; i++) {
439f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount                findIncludedViews(set.getTransitionAt(i), includedViews, included);
440f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount            }
441f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount        } else {
442f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount            final int numViews = views.size();
443f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount            for (int i = 0; i < numViews; i++) {
444f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount                final View view = views.get(i);
445f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount                if (transition.isValidTarget(view)) {
446f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount                    included.add(view);
447f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount                }
448f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount            }
449f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount        }
450f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount    }
451f85b3d48d692e60af0b01ce75424ccb68e11b2bbGeorge Mount
45262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    protected static Transition mergeTransitions(Transition transition1, Transition transition2) {
45362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        if (transition1 == null) {
45462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            return transition2;
45562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        } else if (transition2 == null) {
45662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            return transition1;
45762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        } else {
45862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            TransitionSet transitionSet = new TransitionSet();
45962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            transitionSet.addTransition(transition1);
46062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            transitionSet.addTransition(transition2);
46162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            return transitionSet;
46262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        }
46362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    }
46462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
4651fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount    protected ArrayMap<String, View> mapSharedElements(ArrayList<String> accepted,
4661fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount            ArrayList<View> localViews) {
4671fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount        ArrayMap<String, View> sharedElements = new ArrayMap<String, View>();
468ce725a47f6eee75a6ef86397e9b9fe471aeb1f84George Mount        if (accepted != null) {
469ce725a47f6eee75a6ef86397e9b9fe471aeb1f84George Mount            for (int i = 0; i < accepted.size(); i++) {
470ce725a47f6eee75a6ef86397e9b9fe471aeb1f84George Mount                sharedElements.put(accepted.get(i), localViews.get(i));
471caa03107d4322b0e30f92e6dc1eb1ea73b1bf747George Mount            }
472ce725a47f6eee75a6ef86397e9b9fe471aeb1f84George Mount        } else {
47348bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            ViewGroup decorView = getDecor();
47448bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            if (decorView != null) {
47548bd13c9cb2627847cf1f7707a084eb354e9c303George Mount                decorView.findNamedViews(sharedElements);
47648bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            }
4771fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount        }
4781fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount        return sharedElements;
4791fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount    }
4801fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount
48162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    protected void setResultReceiver(ResultReceiver resultReceiver) {
48262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        mResultReceiver = resultReceiver;
483080443bcb63418245c2408500db735fece5e7083George Mount    }
484080443bcb63418245c2408500db735fece5e7083George Mount
485a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount    protected abstract Transition getViewsTransition();
486080443bcb63418245c2408500db735fece5e7083George Mount
487fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    private void setSharedElementState(View view, String name, Bundle transitionArgs,
4887bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            Matrix tempMatrix, RectF tempRect, int[] decorLoc) {
489c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        Bundle sharedElementBundle = transitionArgs.getBundle(name);
490c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (sharedElementBundle == null) {
491c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            return;
492c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
493c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
494c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (view instanceof ImageView) {
495c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            int scaleTypeInt = sharedElementBundle.getInt(KEY_SCALE_TYPE, -1);
496c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            if (scaleTypeInt >= 0) {
497c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                ImageView imageView = (ImageView) view;
498c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                ImageView.ScaleType scaleType = SCALE_TYPE_VALUES[scaleTypeInt];
499c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                imageView.setScaleType(scaleType);
500c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                if (scaleType == ImageView.ScaleType.MATRIX) {
501c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                    float[] matrixValues = sharedElementBundle.getFloatArray(KEY_IMAGE_MATRIX);
5027bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu                    tempMatrix.setValues(matrixValues);
5037bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu                    imageView.setImageMatrix(tempMatrix);
504c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                }
505c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            }
506c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
507c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
508c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        float z = sharedElementBundle.getFloat(KEY_TRANSLATION_Z);
509c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        view.setTranslationZ(z);
51026c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount        float elevation = sharedElementBundle.getFloat(KEY_ELEVATION);
51126c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount        view.setElevation(elevation);
512c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
5137bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        float left = sharedElementBundle.getFloat(KEY_SCREEN_LEFT);
5147bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        float top = sharedElementBundle.getFloat(KEY_SCREEN_TOP);
5157bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        float right = sharedElementBundle.getFloat(KEY_SCREEN_RIGHT);
5167bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        float bottom = sharedElementBundle.getFloat(KEY_SCREEN_BOTTOM);
517c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
5187bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        if (decorLoc != null) {
5197bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            left -= decorLoc[0];
5207bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            top -= decorLoc[1];
521480ca829e2d3313740b4d14d30afbea6c98ff965George Mount            right -= decorLoc[0];
522480ca829e2d3313740b4d14d30afbea6c98ff965George Mount            bottom -= decorLoc[1];
5237bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        } else {
5247bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            // Find the location in the view's parent
525fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            getSharedElementParentMatrix(view, tempMatrix);
5267bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            tempRect.set(left, top, right, bottom);
5277bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            tempMatrix.mapRect(tempRect);
5287bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu
5297bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            float leftInParent = tempRect.left;
5307bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            float topInParent = tempRect.top;
5317bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu
5327bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            // Find the size of the view
5337bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            view.getInverseMatrix().mapRect(tempRect);
5347bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            float width = tempRect.width();
5357bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            float height = tempRect.height();
5367bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu
5377bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            // Now determine the offset due to view transform:
5387bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            view.setLeft(0);
5397bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            view.setTop(0);
5407bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            view.setRight(Math.round(width));
5417bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            view.setBottom(Math.round(height));
5427bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            tempRect.set(0, 0, width, height);
5437bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            view.getMatrix().mapRect(tempRect);
5447bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu
54518c2b0ef36400f4af6ee38dd84e2d65d18474b20Doris Liu            left = leftInParent - tempRect.left;
54618c2b0ef36400f4af6ee38dd84e2d65d18474b20Doris Liu            top = topInParent - tempRect.top;
5477bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            right = left + width;
5487bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            bottom = top + height;
5497bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        }
5507bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu
5517bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        int x = Math.round(left);
5527bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        int y = Math.round(top);
5537bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        int width = Math.round(right) - x;
5547bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        int height = Math.round(bottom) - y;
555c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        int widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
556c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        int heightSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
557c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        view.measure(widthSpec, heightSpec);
558c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
5597bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        view.layout(x, y, x + width, y + height);
560c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
561c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
562333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount    private void setSharedElementMatrices() {
563333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        int numSharedElements = mSharedElements.size();
564333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        if (numSharedElements > 0) {
565333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            mSharedElementParentMatrices = new ArrayList<Matrix>(numSharedElements);
566333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        }
567333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        for (int i = 0; i < numSharedElements; i++) {
568333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            View view = mSharedElements.get(i);
569333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount
570333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            // Find the location in the view's parent
571333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            ViewGroup parent = (ViewGroup) view.getParent();
572333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            Matrix matrix = new Matrix();
573e06b816e0ec64bac284d44c543166e88c9167889George Mount            if (parent != null) {
574e06b816e0ec64bac284d44c543166e88c9167889George Mount                parent.transformMatrixToLocal(matrix);
575e06b816e0ec64bac284d44c543166e88c9167889George Mount                matrix.postTranslate(parent.getScrollX(), parent.getScrollY());
576e06b816e0ec64bac284d44c543166e88c9167889George Mount            }
577333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            mSharedElementParentMatrices.add(matrix);
578333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        }
579333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount    }
580333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount
581333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount    private void getSharedElementParentMatrix(View view, Matrix matrix) {
58242161c5cb4f5f36cf83c8af3f20db70a70850a88George Mount        final int index = mSharedElementParentMatrices == null ? -1
58342161c5cb4f5f36cf83c8af3f20db70a70850a88George Mount                : mSharedElements.indexOf(view);
58442161c5cb4f5f36cf83c8af3f20db70a70850a88George Mount        if (index < 0) {
585333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            matrix.reset();
586333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            ViewParent viewParent = view.getParent();
587333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            if (viewParent instanceof ViewGroup) {
588333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount                // Find the location in the view's parent
589333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount                ViewGroup parent = (ViewGroup) viewParent;
590333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount                parent.transformMatrixToLocal(matrix);
59118c2b0ef36400f4af6ee38dd84e2d65d18474b20Doris Liu                matrix.postTranslate(parent.getScrollX(), parent.getScrollY());
592333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount            }
59342161c5cb4f5f36cf83c8af3f20db70a70850a88George Mount        } else {
59442161c5cb4f5f36cf83c8af3f20db70a70850a88George Mount            // The indices of mSharedElementParentMatrices matches the
59542161c5cb4f5f36cf83c8af3f20db70a70850a88George Mount            // mSharedElement matrices.
59642161c5cb4f5f36cf83c8af3f20db70a70850a88George Mount            Matrix parentMatrix = mSharedElementParentMatrices.get(index);
59742161c5cb4f5f36cf83c8af3f20db70a70850a88George Mount            matrix.set(parentMatrix);
598333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        }
599fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
600fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
601c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu    protected ArrayList<SharedElementOriginalState> setSharedElementState(
602c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            Bundle sharedElementState, final ArrayList<View> snapshots) {
603c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        ArrayList<SharedElementOriginalState> originalImageState =
604c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu                new ArrayList<SharedElementOriginalState>();
605c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (sharedElementState != null) {
6067bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            Matrix tempMatrix = new Matrix();
6077bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            RectF tempRect = new RectF();
6081732f528952ea2df0bfd503fabb958af03dbfc81George Mount            final int numSharedElements = mSharedElements.size();
6091732f528952ea2df0bfd503fabb958af03dbfc81George Mount            for (int i = 0; i < numSharedElements; i++) {
610c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                View sharedElement = mSharedElements.get(i);
611c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                String name = mSharedElementNames.get(i);
612c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu                SharedElementOriginalState originalState = getOldSharedElementState(sharedElement,
613c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                        name, sharedElementState);
614c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu                originalImageState.add(originalState);
6157bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu                setSharedElementState(sharedElement, name, sharedElementState,
6167bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu                        tempMatrix, tempRect, null);
617c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            }
618c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
6191732f528952ea2df0bfd503fabb958af03dbfc81George Mount        if (mListener != null) {
6201732f528952ea2df0bfd503fabb958af03dbfc81George Mount            mListener.onSharedElementStart(mSharedElementNames, mSharedElements, snapshots);
6211732f528952ea2df0bfd503fabb958af03dbfc81George Mount        }
622fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        return originalImageState;
623fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
624fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
625fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    protected void notifySharedElementEnd(ArrayList<View> snapshots) {
6261732f528952ea2df0bfd503fabb958af03dbfc81George Mount        if (mListener != null) {
6271732f528952ea2df0bfd503fabb958af03dbfc81George Mount            mListener.onSharedElementEnd(mSharedElementNames, mSharedElements, snapshots);
6281732f528952ea2df0bfd503fabb958af03dbfc81George Mount        }
629fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
630c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
631fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    protected void scheduleSetSharedElementEnd(final ArrayList<View> snapshots) {
6326e7fb60b93d3449d256282a9cc34ba3356add90eGeorge Mount        final View decorView = getDecor();
63348bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        if (decorView != null) {
634f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount            OneShotPreDrawListener.add(decorView, () -> {
635f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount                notifySharedElementEnd(snapshots);
636f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount            });
63748bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        }
638c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
639c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
640c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu    private static SharedElementOriginalState getOldSharedElementState(View view, String name,
641c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            Bundle transitionArgs) {
642c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu
643c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        SharedElementOriginalState state = new SharedElementOriginalState();
644c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        state.mLeft = view.getLeft();
645c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        state.mTop = view.getTop();
646c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        state.mRight = view.getRight();
647c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        state.mBottom = view.getBottom();
648c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        state.mMeasuredWidth = view.getMeasuredWidth();
649c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        state.mMeasuredHeight = view.getMeasuredHeight();
65026c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount        state.mTranslationZ = view.getTranslationZ();
65126c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount        state.mElevation = view.getElevation();
652c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (!(view instanceof ImageView)) {
653c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu            return state;
654c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
655c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        Bundle bundle = transitionArgs.getBundle(name);
656c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (bundle == null) {
657c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu            return state;
658c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
659c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        int scaleTypeInt = bundle.getInt(KEY_SCALE_TYPE, -1);
660c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (scaleTypeInt < 0) {
661c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu            return state;
662c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
663c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
664c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        ImageView imageView = (ImageView) view;
665c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        state.mScaleType = imageView.getScaleType();
666c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        if (state.mScaleType == ImageView.ScaleType.MATRIX) {
667c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu            state.mMatrix = new Matrix(imageView.getImageMatrix());
668c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
669c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        return state;
670c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
671c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
672c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    protected ArrayList<View> createSnapshots(Bundle state, Collection<String> names) {
673c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        int numSharedElements = names.size();
6747c479f5a013fb5544be45cd3a952190fc3a923fcGeorge Mount        ArrayList<View> snapshots = new ArrayList<View>(numSharedElements);
675c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (numSharedElements == 0) {
6767c479f5a013fb5544be45cd3a952190fc3a923fcGeorge Mount            return snapshots;
677c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
678c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        Context context = getWindow().getContext();
6797bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        int[] decorLoc = new int[2];
68048bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        ViewGroup decorView = getDecor();
68148bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        if (decorView != null) {
68248bd13c9cb2627847cf1f7707a084eb354e9c303George Mount            decorView.getLocationOnScreen(decorLoc);
68348bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        }
684ca5094a05ce177c586f873ad556e7afc2656fe12George Mount        Matrix tempMatrix = new Matrix();
685c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        for (String name: names) {
686c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            Bundle sharedElementBundle = state.getBundle(name);
68792692c0284c2249e9a5381f7f19ec97f6b76d12fGeorge Mount            View snapshot = null;
688c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            if (sharedElementBundle != null) {
689480ca829e2d3313740b4d14d30afbea6c98ff965George Mount                Parcelable parcelable = sharedElementBundle.getParcelable(KEY_SNAPSHOT);
6901732f528952ea2df0bfd503fabb958af03dbfc81George Mount                if (parcelable != null && mListener != null) {
6916558056e8fccc32f9e1dc59e46d09f8d916b7538George Mount                    snapshot = mListener.onCreateSnapshotView(context, parcelable);
692480ca829e2d3313740b4d14d30afbea6c98ff965George Mount                }
693480ca829e2d3313740b4d14d30afbea6c98ff965George Mount                if (snapshot != null) {
694ca5094a05ce177c586f873ad556e7afc2656fe12George Mount                    setSharedElementState(snapshot, name, state, tempMatrix, null, decorLoc);
695c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                }
696c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            }
69792692c0284c2249e9a5381f7f19ec97f6b76d12fGeorge Mount            // Even null snapshots are added so they remain in the same order as shared elements.
69892692c0284c2249e9a5381f7f19ec97f6b76d12fGeorge Mount            snapshots.add(snapshot);
699c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
700c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        return snapshots;
701c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
702c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
703c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu    protected static void setOriginalSharedElementState(ArrayList<View> sharedElements,
704c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu            ArrayList<SharedElementOriginalState> originalState) {
705c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        for (int i = 0; i < originalState.size(); i++) {
706c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu            View view = sharedElements.get(i);
707c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu            SharedElementOriginalState state = originalState.get(i);
708c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu            if (view instanceof ImageView && state.mScaleType != null) {
709c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu                ImageView imageView = (ImageView) view;
710c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu                imageView.setScaleType(state.mScaleType);
711c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu                if (state.mScaleType == ImageView.ScaleType.MATRIX) {
712c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu                  imageView.setImageMatrix(state.mMatrix);
713c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu                }
714c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu            }
71526c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount            view.setElevation(state.mElevation);
71626c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount            view.setTranslationZ(state.mTranslationZ);
71726c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount            int widthSpec = View.MeasureSpec.makeMeasureSpec(state.mMeasuredWidth,
718c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu                    View.MeasureSpec.EXACTLY);
719c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu            int heightSpec = View.MeasureSpec.makeMeasureSpec(state.mMeasuredHeight,
720c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu                    View.MeasureSpec.EXACTLY);
721c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu            view.measure(widthSpec, heightSpec);
722c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu            view.layout(state.mLeft, state.mTop, state.mRight, state.mBottom);
723c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
724c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
725c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
726c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    protected Bundle captureSharedElementState() {
727c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        Bundle bundle = new Bundle();
7287bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        RectF tempBounds = new RectF();
7297bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        Matrix tempMatrix = new Matrix();
730f03c139018dd5b6f1ea53ac902caec7b6ee9ddd3Dake Gu        for (int i = 0; i < mSharedElements.size(); i++) {
731c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            View sharedElement = mSharedElements.get(i);
732c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            String name = mSharedElementNames.get(i);
7337bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            captureSharedElementState(sharedElement, name, bundle, tempMatrix, tempBounds);
734c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
735c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        return bundle;
736c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
737c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
738a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount    protected void clearState() {
739a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        // Clear the state so that we can't hold any references accidentally and leak memory.
740a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mWindow = null;
741a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mSharedElements.clear();
742b694e080546316a27d22eba759027f6cb0a24705George Mount        mTransitioningViews = null;
743aae763e692810fb411b83fdda57567e1b66577ddGeorge Mount        mStrippedTransitioningViews = null;
7440f0c473488f8e8becc8883d3cdd9610324610dc4George Mount        mOriginalAlphas.clear();
745a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mResultReceiver = null;
746a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mPendingTransition = null;
747fc0fc0e341f2a2d707d5a8eafd65db34bdffb35cDake Gu        mListener = null;
748333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        mSharedElementParentMatrices = null;
749a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount    }
750a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount
751ed1e01d7e431edbcaab983b4b240418f2b090facGeorge Mount    protected long getFadeDuration() {
752ed1e01d7e431edbcaab983b4b240418f2b090facGeorge Mount        return getWindow().getTransitionBackgroundFadeDuration();
753ed1e01d7e431edbcaab983b4b240418f2b090facGeorge Mount    }
754ed1e01d7e431edbcaab983b4b240418f2b090facGeorge Mount
7550f0c473488f8e8becc8883d3cdd9610324610dc4George Mount    protected void hideViews(ArrayList<View> views) {
756fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        int count = views.size();
757fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        for (int i = 0; i < count; i++) {
7580f0c473488f8e8becc8883d3cdd9610324610dc4George Mount            View view = views.get(i);
7590f0c473488f8e8becc8883d3cdd9610324610dc4George Mount            if (!mOriginalAlphas.containsKey(view)) {
7600f0c473488f8e8becc8883d3cdd9610324610dc4George Mount                mOriginalAlphas.put(view, view.getAlpha());
7610f0c473488f8e8becc8883d3cdd9610324610dc4George Mount            }
7620f0c473488f8e8becc8883d3cdd9610324610dc4George Mount            view.setAlpha(0f);
7630f0c473488f8e8becc8883d3cdd9610324610dc4George Mount        }
7640f0c473488f8e8becc8883d3cdd9610324610dc4George Mount    }
7650f0c473488f8e8becc8883d3cdd9610324610dc4George Mount
766ce2ee3d6de670e52abed7f432778701113ba9c07George Mount    protected void showViews(ArrayList<View> views, boolean setTransitionAlpha) {
7670f0c473488f8e8becc8883d3cdd9610324610dc4George Mount        int count = views.size();
7680f0c473488f8e8becc8883d3cdd9610324610dc4George Mount        for (int i = 0; i < count; i++) {
769653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount            showView(views.get(i), setTransitionAlpha);
770653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount        }
771653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount    }
772653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount
773653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount    private void showView(View view, boolean setTransitionAlpha) {
774653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount        Float alpha = mOriginalAlphas.remove(view);
775653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount        if (alpha != null) {
776653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount            view.setAlpha(alpha);
777653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount        }
778653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount        if (setTransitionAlpha) {
779653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount            view.setTransitionAlpha(1f);
780b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount        }
781b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount    }
782b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount
783c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    /**
784c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount     * Captures placement information for Views with a shared element name for
785c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount     * Activity Transitions.
786c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount     *
787c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount     * @param view           The View to capture the placement information for.
788c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount     * @param name           The shared element name in the target Activity to apply the placement
789c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount     *                       information for.
790c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount     * @param transitionArgs Bundle to store shared element placement information.
7918e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount     * @param tempBounds     A temporary Rect for capturing the current location of views.
792c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount     */
793480ca829e2d3313740b4d14d30afbea6c98ff965George Mount    protected void captureSharedElementState(View view, String name, Bundle transitionArgs,
7947bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu            Matrix tempMatrix, RectF tempBounds) {
795c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        Bundle sharedElementBundle = new Bundle();
7967bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        tempMatrix.reset();
7977bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        view.transformMatrixToGlobal(tempMatrix);
7988e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount        tempBounds.set(0, 0, view.getWidth(), view.getHeight());
7997bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        tempMatrix.mapRect(tempBounds);
800c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
8017bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        sharedElementBundle.putFloat(KEY_SCREEN_LEFT, tempBounds.left);
8027bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        sharedElementBundle.putFloat(KEY_SCREEN_RIGHT, tempBounds.right);
8037bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        sharedElementBundle.putFloat(KEY_SCREEN_TOP, tempBounds.top);
8047bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        sharedElementBundle.putFloat(KEY_SCREEN_BOTTOM, tempBounds.bottom);
805c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        sharedElementBundle.putFloat(KEY_TRANSLATION_Z, view.getTranslationZ());
80626c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount        sharedElementBundle.putFloat(KEY_ELEVATION, view.getElevation());
807c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
8081732f528952ea2df0bfd503fabb958af03dbfc81George Mount        Parcelable bitmap = null;
8091732f528952ea2df0bfd503fabb958af03dbfc81George Mount        if (mListener != null) {
8101732f528952ea2df0bfd503fabb958af03dbfc81George Mount            bitmap = mListener.onCaptureSharedElementSnapshot(view, tempMatrix, tempBounds);
8111732f528952ea2df0bfd503fabb958af03dbfc81George Mount        }
8121732f528952ea2df0bfd503fabb958af03dbfc81George Mount
813480ca829e2d3313740b4d14d30afbea6c98ff965George Mount        if (bitmap != null) {
814480ca829e2d3313740b4d14d30afbea6c98ff965George Mount            sharedElementBundle.putParcelable(KEY_SNAPSHOT, bitmap);
815c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
816c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
817c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (view instanceof ImageView) {
818c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            ImageView imageView = (ImageView) view;
819c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            int scaleTypeInt = scaleTypeToInt(imageView.getScaleType());
820c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            sharedElementBundle.putInt(KEY_SCALE_TYPE, scaleTypeInt);
821c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            if (imageView.getScaleType() == ImageView.ScaleType.MATRIX) {
822c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                float[] matrix = new float[9];
823c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                imageView.getImageMatrix().getValues(matrix);
824c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                sharedElementBundle.putFloatArray(KEY_IMAGE_MATRIX, matrix);
825c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            }
826c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
827c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
828c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        transitionArgs.putBundle(name, sharedElementBundle);
829c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
830c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
83167d924341a1d0994ac68b3b7898d5576edd987b4George Mount
83267d924341a1d0994ac68b3b7898d5576edd987b4George Mount    protected void startTransition(Runnable runnable) {
83367d924341a1d0994ac68b3b7898d5576edd987b4George Mount        if (mIsStartingTransition) {
83467d924341a1d0994ac68b3b7898d5576edd987b4George Mount            mPendingTransition = runnable;
83567d924341a1d0994ac68b3b7898d5576edd987b4George Mount        } else {
83667d924341a1d0994ac68b3b7898d5576edd987b4George Mount            mIsStartingTransition = true;
83767d924341a1d0994ac68b3b7898d5576edd987b4George Mount            runnable.run();
83867d924341a1d0994ac68b3b7898d5576edd987b4George Mount        }
83967d924341a1d0994ac68b3b7898d5576edd987b4George Mount    }
84067d924341a1d0994ac68b3b7898d5576edd987b4George Mount
84113ccb79b34f6db1580714ea980c8490121d7e5aeGeorge Mount    protected void transitionStarted() {
84213ccb79b34f6db1580714ea980c8490121d7e5aeGeorge Mount        mIsStartingTransition = false;
84313ccb79b34f6db1580714ea980c8490121d7e5aeGeorge Mount    }
84413ccb79b34f6db1580714ea980c8490121d7e5aeGeorge Mount
845fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount    /**
846fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount     * Cancels any pending transitions and returns true if there is a transition is in
847fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount     * the middle of starting.
848fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount     */
849fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount    protected boolean cancelPendingTransitions() {
850fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount        mPendingTransition = null;
851fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount        return mIsStartingTransition;
852fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount    }
853fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount
854fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    protected void moveSharedElementsToOverlay() {
855eca1ae5e442bf5f13617ab823343730619512632George Mount        if (mWindow == null || !mWindow.getSharedElementsUseOverlay()) {
856b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount            return;
857b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount        }
858333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount        setSharedElementMatrices();
859fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        int numSharedElements = mSharedElements.size();
860fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        ViewGroup decor = getDecor();
861fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        if (decor != null) {
862fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            boolean moveWithParent = moveSharedElementWithParent();
86342161c5cb4f5f36cf83c8af3f20db70a70850a88George Mount            Matrix tempMatrix = new Matrix();
864fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            for (int i = 0; i < numSharedElements; i++) {
865fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                View view = mSharedElements.get(i);
866e06b816e0ec64bac284d44c543166e88c9167889George Mount                if (view.isAttachedToWindow()) {
867e06b816e0ec64bac284d44c543166e88c9167889George Mount                    tempMatrix.reset();
868e06b816e0ec64bac284d44c543166e88c9167889George Mount                    mSharedElementParentMatrices.get(i).invert(tempMatrix);
869e06b816e0ec64bac284d44c543166e88c9167889George Mount                    GhostView.addGhost(view, decor, tempMatrix);
870e06b816e0ec64bac284d44c543166e88c9167889George Mount                    ViewGroup parent = (ViewGroup) view.getParent();
871e06b816e0ec64bac284d44c543166e88c9167889George Mount                    if (moveWithParent && !isInTransitionGroup(parent, decor)) {
872e06b816e0ec64bac284d44c543166e88c9167889George Mount                        GhostViewListeners listener = new GhostViewListeners(view, parent, decor);
873e06b816e0ec64bac284d44c543166e88c9167889George Mount                        parent.getViewTreeObserver().addOnPreDrawListener(listener);
874e06b816e0ec64bac284d44c543166e88c9167889George Mount                        parent.addOnAttachStateChangeListener(listener);
875e06b816e0ec64bac284d44c543166e88c9167889George Mount                        mGhostViewListeners.add(listener);
876e06b816e0ec64bac284d44c543166e88c9167889George Mount                    }
877fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                }
878fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            }
879fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        }
880fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
881fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
882fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    protected boolean moveSharedElementWithParent() {
883fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        return true;
884fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
885fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
886fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    public static boolean isInTransitionGroup(ViewParent viewParent, ViewGroup decor) {
887fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        if (viewParent == decor || !(viewParent instanceof ViewGroup)) {
888fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            return false;
889fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        }
890fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        ViewGroup parent = (ViewGroup) viewParent;
891fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        if (parent.isTransitionGroup()) {
892fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            return true;
893fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        } else {
894fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            return isInTransitionGroup(parent.getParent(), decor);
895fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        }
896fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
897fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
898fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    protected void moveSharedElementsFromOverlay() {
899b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount        int numListeners = mGhostViewListeners.size();
900b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount        for (int i = 0; i < numListeners; i++) {
901b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount            GhostViewListeners listener = mGhostViewListeners.get(i);
902f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount            listener.removeListener();
903b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount        }
904b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount        mGhostViewListeners.clear();
905b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount
906b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount        if (mWindow == null || !mWindow.getSharedElementsUseOverlay()) {
907b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount            return;
908b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount        }
909fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        ViewGroup decor = getDecor();
910fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        if (decor != null) {
911fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            ViewGroupOverlay overlay = decor.getOverlay();
912fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            int count = mSharedElements.size();
913fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            for (int i = 0; i < count; i++) {
914fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                View sharedElement = mSharedElements.get(i);
915fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                GhostView.removeGhost(sharedElement);
916fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            }
917fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        }
918fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
919fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
920fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    protected void setGhostVisibility(int visibility) {
921fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        int numSharedElements = mSharedElements.size();
922fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        for (int i = 0; i < numSharedElements; i++) {
923fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            GhostView ghostView = GhostView.getGhost(mSharedElements.get(i));
924fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            if (ghostView != null) {
925fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                ghostView.setVisibility(visibility);
926fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            }
927fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        }
928fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
929fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
930fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    protected void scheduleGhostVisibilityChange(final int visibility) {
9316e7fb60b93d3449d256282a9cc34ba3356add90eGeorge Mount        final View decorView = getDecor();
93248bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        if (decorView != null) {
933f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount            OneShotPreDrawListener.add(decorView, () -> {
934f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount                setGhostVisibility(visibility);
935f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount            });
93648bd13c9cb2627847cf1f7707a084eb354e9c303George Mount        }
937fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
938fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
93941725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount    protected boolean isViewsTransitionComplete() {
94041725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount        return mViewsTransitionComplete;
94141725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount    }
94241725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount
94341725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount    protected void viewsTransitionComplete() {
94441725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount        mViewsTransitionComplete = true;
94541725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount        startInputWhenTransitionsComplete();
94641725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount    }
94741725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount
948b64e777f6c14d862f221f4da814079df22663db1Chet Haase    protected void backgroundAnimatorComplete() {
949b64e777f6c14d862f221f4da814079df22663db1Chet Haase        mBackgroundAnimatorComplete = true;
950b64e777f6c14d862f221f4da814079df22663db1Chet Haase    }
951b64e777f6c14d862f221f4da814079df22663db1Chet Haase
95241725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount    protected void sharedElementTransitionComplete() {
95341725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount        mSharedElementTransitionComplete = true;
95441725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount        startInputWhenTransitionsComplete();
95541725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount    }
95641725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount    private void startInputWhenTransitionsComplete() {
95741725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount        if (mViewsTransitionComplete && mSharedElementTransitionComplete) {
95841725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount            final View decor = getDecor();
95941725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount            if (decor != null) {
96041725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount                final ViewRootImpl viewRoot = decor.getViewRootImpl();
9615fddd4ca581aeb7c6b526628cfbf7915a2e20574George Mount                if (viewRoot != null) {
9625fddd4ca581aeb7c6b526628cfbf7915a2e20574George Mount                    viewRoot.setPausedForTransition(false);
9635fddd4ca581aeb7c6b526628cfbf7915a2e20574George Mount                }
96441725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount            }
96541725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount            onTransitionsComplete();
96641725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount        }
96741725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount    }
96841725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount
96980141d1c8b799cf7669a29b8837037cf3934ddb9George Mount    protected void pauseInput() {
97080141d1c8b799cf7669a29b8837037cf3934ddb9George Mount        final View decor = getDecor();
97180141d1c8b799cf7669a29b8837037cf3934ddb9George Mount        final ViewRootImpl viewRoot = decor == null ? null : decor.getViewRootImpl();
97280141d1c8b799cf7669a29b8837037cf3934ddb9George Mount        if (viewRoot != null) {
97380141d1c8b799cf7669a29b8837037cf3934ddb9George Mount            viewRoot.setPausedForTransition(true);
97480141d1c8b799cf7669a29b8837037cf3934ddb9George Mount        }
97580141d1c8b799cf7669a29b8837037cf3934ddb9George Mount    }
97680141d1c8b799cf7669a29b8837037cf3934ddb9George Mount
97741725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount    protected void onTransitionsComplete() {}
97841725dedc33906aaafee36b2d6523596e2a8a52eGeorge Mount
979e0c37bdea37f78778f6c4f23f03604e59dfb0d55Ben Weiss    protected class ContinueTransitionListener extends TransitionListenerAdapter {
98067d924341a1d0994ac68b3b7898d5576edd987b4George Mount        @Override
98167d924341a1d0994ac68b3b7898d5576edd987b4George Mount        public void onTransitionStart(Transition transition) {
98267d924341a1d0994ac68b3b7898d5576edd987b4George Mount            mIsStartingTransition = false;
98367d924341a1d0994ac68b3b7898d5576edd987b4George Mount            Runnable pending = mPendingTransition;
98467d924341a1d0994ac68b3b7898d5576edd987b4George Mount            mPendingTransition = null;
98567d924341a1d0994ac68b3b7898d5576edd987b4George Mount            if (pending != null) {
98667d924341a1d0994ac68b3b7898d5576edd987b4George Mount                startTransition(pending);
98767d924341a1d0994ac68b3b7898d5576edd987b4George Mount            }
98867d924341a1d0994ac68b3b7898d5576edd987b4George Mount        }
98925f98a4c0156ec40d1d92cfe5a24459d9ffa6f91George Mount
99025f98a4c0156ec40d1d92cfe5a24459d9ffa6f91George Mount        @Override
99125f98a4c0156ec40d1d92cfe5a24459d9ffa6f91George Mount        public void onTransitionEnd(Transition transition) {
99225f98a4c0156ec40d1d92cfe5a24459d9ffa6f91George Mount            transition.removeListener(this);
99325f98a4c0156ec40d1d92cfe5a24459d9ffa6f91George Mount        }
99467d924341a1d0994ac68b3b7898d5576edd987b4George Mount    }
99567d924341a1d0994ac68b3b7898d5576edd987b4George Mount
996c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    private static int scaleTypeToInt(ImageView.ScaleType scaleType) {
997c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        for (int i = 0; i < SCALE_TYPE_VALUES.length; i++) {
998c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            if (scaleType == SCALE_TYPE_VALUES[i]) {
999c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                return i;
1000c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            }
1001c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
1002c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        return -1;
1003c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
1004c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
1005629767288a7f551d651f0405fdd9ed04e807d56bGeorge Mount    protected void setTransitioningViewsVisiblity(int visiblity, boolean invalidate) {
1006629767288a7f551d651f0405fdd9ed04e807d56bGeorge Mount        final int numElements = mTransitioningViews == null ? 0 : mTransitioningViews.size();
1007629767288a7f551d651f0405fdd9ed04e807d56bGeorge Mount        for (int i = 0; i < numElements; i++) {
1008629767288a7f551d651f0405fdd9ed04e807d56bGeorge Mount            final View view = mTransitioningViews.get(i);
1009629767288a7f551d651f0405fdd9ed04e807d56bGeorge Mount            view.setTransitionVisibility(visiblity);
1010629767288a7f551d651f0405fdd9ed04e807d56bGeorge Mount            if (invalidate) {
1011629767288a7f551d651f0405fdd9ed04e807d56bGeorge Mount                view.invalidate();
1012629767288a7f551d651f0405fdd9ed04e807d56bGeorge Mount            }
1013629767288a7f551d651f0405fdd9ed04e807d56bGeorge Mount        }
1014629767288a7f551d651f0405fdd9ed04e807d56bGeorge Mount    }
1015629767288a7f551d651f0405fdd9ed04e807d56bGeorge Mount
10161349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount    /**
10171349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount     * Blocks suppressLayout from Visibility transitions. It is ok to suppress the layout,
10181349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount     * but we don't want to force the layout when suppressLayout becomes false. This leads
10191349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount     * to visual glitches.
10201349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount     */
10211349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount    private static void noLayoutSuppressionForVisibilityTransitions(Transition transition) {
10221349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount        if (transition instanceof Visibility) {
10231349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount            final Visibility visibility = (Visibility) transition;
10241349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount            visibility.setSuppressLayout(false);
10251349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount        } else if (transition instanceof TransitionSet) {
10261349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount            final TransitionSet set = (TransitionSet) transition;
10271349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount            final int count = set.getTransitionCount();
10281349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount            for (int i = 0; i < count; i++) {
10291349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount                noLayoutSuppressionForVisibilityTransitions(set.getTransitionAt(i));
10301349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount            }
10311349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount        }
10321349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount    }
10331349bb9c336e33bdb8a7edd3fdec9a7ecf8015d0George Mount
1034b64e777f6c14d862f221f4da814079df22663db1Chet Haase    public boolean isTransitionRunning() {
1035b64e777f6c14d862f221f4da814079df22663db1Chet Haase        return !(mViewsTransitionComplete && mSharedElementTransitionComplete &&
1036b64e777f6c14d862f221f4da814079df22663db1Chet Haase                mBackgroundAnimatorComplete);
1037b64e777f6c14d862f221f4da814079df22663db1Chet Haase    }
1038b64e777f6c14d862f221f4da814079df22663db1Chet Haase
103931a217290cf376d0573fc36e21c8940987485019George Mount    private static class FixedEpicenterCallback extends Transition.EpicenterCallback {
104031a217290cf376d0573fc36e21c8940987485019George Mount        private Rect mEpicenter;
104131a217290cf376d0573fc36e21c8940987485019George Mount
104231a217290cf376d0573fc36e21c8940987485019George Mount        public void setEpicenter(Rect epicenter) { mEpicenter = epicenter; }
104331a217290cf376d0573fc36e21c8940987485019George Mount
104431a217290cf376d0573fc36e21c8940987485019George Mount        @Override
1045dc21d3b2804c24fe29ec860796d11185901364c4George Mount        public Rect onGetEpicenter(Transition transition) {
104631a217290cf376d0573fc36e21c8940987485019George Mount            return mEpicenter;
104731a217290cf376d0573fc36e21c8940987485019George Mount        }
104831a217290cf376d0573fc36e21c8940987485019George Mount    }
1049800d72b0e05049e4a8f90ea96ec165fc975264ceGeorge Mount
1050f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount    private static class GhostViewListeners implements ViewTreeObserver.OnPreDrawListener,
1051f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount            View.OnAttachStateChangeListener {
1052fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        private View mView;
1053fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        private ViewGroup mDecor;
10546e7fb60b93d3449d256282a9cc34ba3356add90eGeorge Mount        private View mParent;
1055fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        private Matrix mMatrix = new Matrix();
1056f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount        private ViewTreeObserver mViewTreeObserver;
1057fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
10586e7fb60b93d3449d256282a9cc34ba3356add90eGeorge Mount        public GhostViewListeners(View view, View parent, ViewGroup decor) {
1059fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            mView = view;
10606e7fb60b93d3449d256282a9cc34ba3356add90eGeorge Mount            mParent = parent;
1061fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            mDecor = decor;
1062f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount            mViewTreeObserver = parent.getViewTreeObserver();
1063fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        }
1064fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
1065fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        public View getView() {
1066fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            return mView;
1067fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        }
1068fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
1069fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        @Override
1070fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        public boolean onPreDraw() {
1071fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            GhostView ghostView = GhostView.getGhost(mView);
1072e06b816e0ec64bac284d44c543166e88c9167889George Mount            if (ghostView == null || !mView.isAttachedToWindow()) {
1073f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount                removeListener();
1074fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            } else {
1075fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                GhostView.calculateMatrix(mView, mDecor, mMatrix);
1076fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                ghostView.setMatrix(mMatrix);
1077fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            }
1078fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            return true;
1079fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        }
1080f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount
1081f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount        public void removeListener() {
1082f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount            if (mViewTreeObserver.isAlive()) {
1083f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount                mViewTreeObserver.removeOnPreDrawListener(this);
1084f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount            } else {
1085f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount                mParent.getViewTreeObserver().removeOnPreDrawListener(this);
1086f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount            }
1087f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount            mParent.removeOnAttachStateChangeListener(this);
1088f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount        }
1089f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount
1090f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount        @Override
1091f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount        public void onViewAttachedToWindow(View v) {
1092f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount            mViewTreeObserver = v.getViewTreeObserver();
1093f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount        }
1094f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount
1095f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount        @Override
1096f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount        public void onViewDetachedFromWindow(View v) {
1097f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount            removeListener();
1098f0b46b9540b48448c1f1fbe55ca2930770bd72e2George Mount        }
1099fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
1100fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
1101c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu    static class SharedElementOriginalState {
1102c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        int mLeft;
1103c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        int mTop;
1104c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        int mRight;
1105c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        int mBottom;
1106c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        int mMeasuredWidth;
1107c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        int mMeasuredHeight;
1108c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        ImageView.ScaleType mScaleType;
1109c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu        Matrix mMatrix;
111026c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount        float mTranslationZ;
111126c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount        float mElevation;
1112c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu    }
111331a217290cf376d0573fc36e21c8940987485019George Mount}
1114