1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.support.v4.app;
18
19import android.app.Activity;
20import android.content.Context;
21import android.graphics.Bitmap;
22import android.os.Build;
23import android.os.Bundle;
24import android.support.v4.util.Pair;
25import android.view.View;
26
27/**
28 * Helper for accessing features in {@link android.app.ActivityOptions}
29 * introduced in API level 16 in a backwards compatible fashion.
30 */
31public class ActivityOptionsCompat {
32    /**
33     * Create an ActivityOptions specifying a custom animation to run when the
34     * activity is displayed.
35     *
36     * @param context Who is defining this. This is the application that the
37     * animation resources will be loaded from.
38     * @param enterResId A resource ID of the animation resource to use for the
39     * incoming activity. Use 0 for no animation.
40     * @param exitResId A resource ID of the animation resource to use for the
41     * outgoing activity. Use 0 for no animation.
42     * @return Returns a new ActivityOptions object that you can use to supply
43     * these options as the options Bundle when starting an activity.
44     */
45    public static ActivityOptionsCompat makeCustomAnimation(Context context,
46            int enterResId, int exitResId) {
47        if (Build.VERSION.SDK_INT >= 16) {
48            return new ActivityOptionsImplJB(
49                ActivityOptionsCompatJB.makeCustomAnimation(context, enterResId, exitResId));
50        }
51        return new ActivityOptionsCompat();
52    }
53
54    /**
55     * Create an ActivityOptions specifying an animation where the new activity is
56     * scaled from a small originating area of the screen to its final full
57     * representation.
58     * <p/>
59     * If the Intent this is being used with has not set its
60     * {@link android.content.Intent#setSourceBounds(android.graphics.Rect)},
61     * those bounds will be filled in for you based on the initial bounds passed
62     * in here.
63     *
64     * @param source The View that the new activity is animating from. This
65     * defines the coordinate space for startX and startY.
66     * @param startX The x starting location of the new activity, relative to
67     * source.
68     * @param startY The y starting location of the activity, relative to source.
69     * @param startWidth The initial width of the new activity.
70     * @param startHeight The initial height of the new activity.
71     * @return Returns a new ActivityOptions object that you can use to supply
72     * these options as the options Bundle when starting an activity.
73     */
74    public static ActivityOptionsCompat makeScaleUpAnimation(View source,
75            int startX, int startY, int startWidth, int startHeight) {
76        if (Build.VERSION.SDK_INT >= 16) {
77            return new ActivityOptionsImplJB(
78                ActivityOptionsCompatJB.makeScaleUpAnimation(source, startX, startY,
79                        startWidth, startHeight));
80        }
81        return new ActivityOptionsCompat();
82    }
83
84    /**
85     * Create an ActivityOptions specifying an animation where a thumbnail is
86     * scaled from a given position to the new activity window that is being
87     * started.
88     * <p/>
89     * If the Intent this is being used with has not set its
90     * {@link android.content.Intent#setSourceBounds(android.graphics.Rect)},
91     * those bounds will be filled in for you based on the initial thumbnail
92     * location and size provided here.
93     *
94     * @param source The View that this thumbnail is animating from. This
95     * defines the coordinate space for startX and startY.
96     * @param thumbnail The bitmap that will be shown as the initial thumbnail
97     * of the animation.
98     * @param startX The x starting location of the bitmap, relative to source.
99     * @param startY The y starting location of the bitmap, relative to source.
100     * @return Returns a new ActivityOptions object that you can use to supply
101     * these options as the options Bundle when starting an activity.
102     */
103    public static ActivityOptionsCompat makeThumbnailScaleUpAnimation(View source,
104            Bitmap thumbnail, int startX, int startY) {
105        if (Build.VERSION.SDK_INT >= 16) {
106            return new ActivityOptionsImplJB(
107                ActivityOptionsCompatJB.makeThumbnailScaleUpAnimation(source, thumbnail,
108                        startX, startY));
109        }
110        return new ActivityOptionsCompat();
111    }
112
113    /**
114     * Create an ActivityOptions to transition between Activities using cross-Activity scene
115     * animations. This method carries the position of one shared element to the started Activity.
116     * The position of <code>sharedElement</code> will be used as the epicenter for the
117     * exit Transition. The position of the shared element in the launched Activity will be the
118     * epicenter of its entering Transition.
119     *
120     * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be
121     * enabled on the calling Activity to cause an exit transition. The same must be in
122     * the called Activity to get an entering transition.</p>
123     * @param activity The Activity whose window contains the shared elements.
124     * @param sharedElement The View to transition to the started Activity. sharedElement must
125     *                      have a non-null sharedElementName.
126     * @param sharedElementName The shared element name as used in the target Activity. This may
127     *                          be null if it has the same name as sharedElement.
128     * @return Returns a new ActivityOptions object that you can use to
129     *         supply these options as the options Bundle when starting an activity.
130     */
131    public static ActivityOptionsCompat makeSceneTransitionAnimation(Activity activity,
132            View sharedElement, String sharedElementName) {
133        if (Build.VERSION.SDK_INT >= 21) {
134            return new ActivityOptionsCompat.ActivityOptionsImpl21(
135                    ActivityOptionsCompat21.makeSceneTransitionAnimation(activity,
136                            sharedElement, sharedElementName));
137        }
138        return new ActivityOptionsCompat();
139    }
140
141    /**
142     * Create an ActivityOptions to transition between Activities using cross-Activity scene
143     * animations. This method carries the position of multiple shared elements to the started
144     * Activity. The position of the first element in sharedElements
145     * will be used as the epicenter for the exit Transition. The position of the associated
146     * shared element in the launched Activity will be the epicenter of its entering Transition.
147     *
148     * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be
149     * enabled on the calling Activity to cause an exit transition. The same must be in
150     * the called Activity to get an entering transition.</p>
151     * @param activity The Activity whose window contains the shared elements.
152     * @param sharedElements The names of the shared elements to transfer to the called
153     *                       Activity and their associated Views. The Views must each have
154     *                       a unique shared element name.
155     * @return Returns a new ActivityOptions object that you can use to
156     *         supply these options as the options Bundle when starting an activity.
157     */
158    public static ActivityOptionsCompat makeSceneTransitionAnimation(Activity activity,
159            Pair<View, String>... sharedElements) {
160        if (Build.VERSION.SDK_INT >= 21) {
161            View[] views = null;
162            String[] names = null;
163            if (sharedElements != null) {
164                views = new View[sharedElements.length];
165                names = new String[sharedElements.length];
166                for (int i = 0; i < sharedElements.length; i++) {
167                    views[i] = sharedElements[i].first;
168                    names[i] = sharedElements[i].second;
169                }
170            }
171            return new ActivityOptionsCompat.ActivityOptionsImpl21(
172                    ActivityOptionsCompat21.makeSceneTransitionAnimation(activity, views, names));
173        }
174        return new ActivityOptionsCompat();
175    }
176
177    private static class ActivityOptionsImplJB extends ActivityOptionsCompat {
178        private final ActivityOptionsCompatJB mImpl;
179
180        ActivityOptionsImplJB(ActivityOptionsCompatJB impl) {
181            mImpl = impl;
182        }
183
184        @Override
185        public Bundle toBundle() {
186            return mImpl.toBundle();
187        }
188
189        @Override
190        public void update(ActivityOptionsCompat otherOptions) {
191            if (otherOptions instanceof ActivityOptionsImplJB) {
192                ActivityOptionsImplJB otherImpl = (ActivityOptionsImplJB)otherOptions;
193                mImpl.update(otherImpl.mImpl);
194            }
195        }
196    }
197
198    private static class ActivityOptionsImpl21 extends ActivityOptionsCompat {
199        private final ActivityOptionsCompat21 mImpl;
200
201        ActivityOptionsImpl21(ActivityOptionsCompat21 impl) {
202            mImpl = impl;
203        }
204
205        @Override
206        public Bundle toBundle() {
207            return mImpl.toBundle();
208        }
209
210        @Override
211        public void update(ActivityOptionsCompat otherOptions) {
212            if (otherOptions instanceof ActivityOptionsCompat.ActivityOptionsImpl21) {
213                ActivityOptionsCompat.ActivityOptionsImpl21
214                        otherImpl = (ActivityOptionsCompat.ActivityOptionsImpl21)otherOptions;
215                mImpl.update(otherImpl.mImpl);
216            }
217        }
218    }
219
220    protected ActivityOptionsCompat() {
221    }
222
223    /**
224     * Returns the created options as a Bundle, which can be passed to
225     * {@link ActivityCompat#startActivity(android.app.Activity, android.content.Intent, android.os.Bundle)}.
226     * Note that the returned Bundle is still owned by the ActivityOptions
227     * object; you must not modify it, but can supply it to the startActivity
228     * methods that take an options Bundle.
229     */
230    public Bundle toBundle() {
231        return null;
232    }
233
234    /**
235     * Update the current values in this ActivityOptions from those supplied in
236     * otherOptions. Any values defined in otherOptions replace those in the
237     * base options.
238     */
239    public void update(ActivityOptionsCompat otherOptions) {
240        // Do nothing.
241    }
242}
243