ActivityOptions.java revision 1fecfb2ddcdf4335ff543bdd549b8e4d36139da8
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.app;
18
19import android.content.Context;
20import android.content.Intent;
21import android.graphics.Bitmap;
22import android.os.Bundle;
23import android.os.Handler;
24import android.os.IRemoteCallback;
25import android.os.RemoteException;
26import android.os.ResultReceiver;
27import android.util.Pair;
28import android.view.View;
29import android.view.Window;
30
31import java.util.ArrayList;
32
33/**
34 * Helper class for building an options Bundle that can be used with
35 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
36 * Context.startActivity(Intent, Bundle)} and related methods.
37 */
38public class ActivityOptions {
39    private static final String TAG = "ActivityOptions";
40
41    /**
42     * The package name that created the options.
43     * @hide
44     */
45    public static final String KEY_PACKAGE_NAME = "android:packageName";
46
47    /**
48     * Type of animation that arguments specify.
49     * @hide
50     */
51    public static final String KEY_ANIM_TYPE = "android:animType";
52
53    /**
54     * Custom enter animation resource ID.
55     * @hide
56     */
57    public static final String KEY_ANIM_ENTER_RES_ID = "android:animEnterRes";
58
59    /**
60     * Custom exit animation resource ID.
61     * @hide
62     */
63    public static final String KEY_ANIM_EXIT_RES_ID = "android:animExitRes";
64
65    /**
66     * Bitmap for thumbnail animation.
67     * @hide
68     */
69    public static final String KEY_ANIM_THUMBNAIL = "android:animThumbnail";
70
71    /**
72     * Start X position of thumbnail animation.
73     * @hide
74     */
75    public static final String KEY_ANIM_START_X = "android:animStartX";
76
77    /**
78     * Start Y position of thumbnail animation.
79     * @hide
80     */
81    public static final String KEY_ANIM_START_Y = "android:animStartY";
82
83    /**
84     * Initial width of the animation.
85     * @hide
86     */
87    public static final String KEY_ANIM_START_WIDTH = "android:animStartWidth";
88
89    /**
90     * Initial height of the animation.
91     * @hide
92     */
93    public static final String KEY_ANIM_START_HEIGHT = "android:animStartHeight";
94
95    /**
96     * Callback for when animation is started.
97     * @hide
98     */
99    public static final String KEY_ANIM_START_LISTENER = "android:animStartListener";
100
101    /**
102     * For Activity transitions, the calling Activity's TransitionListener used to
103     * notify the called Activity when the shared element and the exit transitions
104     * complete.
105     */
106    private static final String KEY_TRANSITION_COMPLETE_LISTENER
107            = "android:transitionCompleteListener";
108
109    private static final String KEY_TRANSITION_IS_RETURNING = "android:transitionIsReturning";
110    private static final String KEY_TRANSITION_SHARED_ELEMENTS = "android:sharedElementNames";
111    private static final String KEY_RESULT_DATA = "android:resultData";
112    private static final String KEY_RESULT_CODE = "android:resultCode";
113    private static final String KEY_EXIT_COORDINATOR_INDEX = "android:exitCoordinatorIndex";
114
115    /** @hide */
116    public static final int ANIM_NONE = 0;
117    /** @hide */
118    public static final int ANIM_CUSTOM = 1;
119    /** @hide */
120    public static final int ANIM_SCALE_UP = 2;
121    /** @hide */
122    public static final int ANIM_THUMBNAIL_SCALE_UP = 3;
123    /** @hide */
124    public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4;
125    /** @hide */
126    public static final int ANIM_SCENE_TRANSITION = 5;
127
128    private String mPackageName;
129    private int mAnimationType = ANIM_NONE;
130    private int mCustomEnterResId;
131    private int mCustomExitResId;
132    private Bitmap mThumbnail;
133    private int mStartX;
134    private int mStartY;
135    private int mStartWidth;
136    private int mStartHeight;
137    private IRemoteCallback mAnimationStartedListener;
138    private ResultReceiver mTransitionReceiver;
139    private boolean mIsReturning;
140    private ArrayList<String> mSharedElementNames;
141    private Intent mResultData;
142    private int mResultCode;
143    private int mExitCoordinatorIndex;
144
145    /**
146     * Create an ActivityOptions specifying a custom animation to run when
147     * the activity is displayed.
148     *
149     * @param context Who is defining this.  This is the application that the
150     * animation resources will be loaded from.
151     * @param enterResId A resource ID of the animation resource to use for
152     * the incoming activity.  Use 0 for no animation.
153     * @param exitResId A resource ID of the animation resource to use for
154     * the outgoing activity.  Use 0 for no animation.
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 ActivityOptions makeCustomAnimation(Context context,
159            int enterResId, int exitResId) {
160        return makeCustomAnimation(context, enterResId, exitResId, null, null);
161    }
162
163    /**
164     * Create an ActivityOptions specifying a custom animation to run when
165     * the activity is displayed.
166     *
167     * @param context Who is defining this.  This is the application that the
168     * animation resources will be loaded from.
169     * @param enterResId A resource ID of the animation resource to use for
170     * the incoming activity.  Use 0 for no animation.
171     * @param exitResId A resource ID of the animation resource to use for
172     * the outgoing activity.  Use 0 for no animation.
173     * @param handler If <var>listener</var> is non-null this must be a valid
174     * Handler on which to dispatch the callback; otherwise it should be null.
175     * @param listener Optional OnAnimationStartedListener to find out when the
176     * requested animation has started running.  If for some reason the animation
177     * is not executed, the callback will happen immediately.
178     * @return Returns a new ActivityOptions object that you can use to
179     * supply these options as the options Bundle when starting an activity.
180     * @hide
181     */
182    public static ActivityOptions makeCustomAnimation(Context context,
183            int enterResId, int exitResId, Handler handler, OnAnimationStartedListener listener) {
184        ActivityOptions opts = new ActivityOptions();
185        opts.mPackageName = context.getPackageName();
186        opts.mAnimationType = ANIM_CUSTOM;
187        opts.mCustomEnterResId = enterResId;
188        opts.mCustomExitResId = exitResId;
189        opts.setOnAnimationStartedListener(handler, listener);
190        return opts;
191    }
192
193    private void setOnAnimationStartedListener(Handler handler,
194            OnAnimationStartedListener listener) {
195        if (listener != null) {
196            final Handler h = handler;
197            final OnAnimationStartedListener finalListener = listener;
198            mAnimationStartedListener = new IRemoteCallback.Stub() {
199                @Override public void sendResult(Bundle data) throws RemoteException {
200                    h.post(new Runnable() {
201                        @Override public void run() {
202                            finalListener.onAnimationStarted();
203                        }
204                    });
205                }
206            };
207        }
208    }
209
210    /**
211     * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation}
212     * to find out when the given animation has started running.
213     * @hide
214     */
215    public interface OnAnimationStartedListener {
216        void onAnimationStarted();
217    }
218
219    /**
220     * Create an ActivityOptions specifying an animation where the new
221     * activity is scaled from a small originating area of the screen to
222     * its final full representation.
223     *
224     * <p>If the Intent this is being used with has not set its
225     * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds},
226     * those bounds will be filled in for you based on the initial
227     * bounds passed in here.
228     *
229     * @param source The View that the new activity is animating from.  This
230     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
231     * @param startX The x starting location of the new activity, relative to <var>source</var>.
232     * @param startY The y starting location of the activity, relative to <var>source</var>.
233     * @param startWidth The initial width of the new activity.
234     * @param startHeight The initial height of the new activity.
235     * @return Returns a new ActivityOptions object that you can use to
236     * supply these options as the options Bundle when starting an activity.
237     */
238    public static ActivityOptions makeScaleUpAnimation(View source,
239            int startX, int startY, int startWidth, int startHeight) {
240        ActivityOptions opts = new ActivityOptions();
241        opts.mPackageName = source.getContext().getPackageName();
242        opts.mAnimationType = ANIM_SCALE_UP;
243        int[] pts = new int[2];
244        source.getLocationOnScreen(pts);
245        opts.mStartX = pts[0] + startX;
246        opts.mStartY = pts[1] + startY;
247        opts.mStartWidth = startWidth;
248        opts.mStartHeight = startHeight;
249        return opts;
250    }
251
252    /**
253     * Create an ActivityOptions specifying an animation where a thumbnail
254     * is scaled from a given position to the new activity window that is
255     * being started.
256     *
257     * <p>If the Intent this is being used with has not set its
258     * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds},
259     * those bounds will be filled in for you based on the initial
260     * thumbnail location and size provided here.
261     *
262     * @param source The View that this thumbnail is animating from.  This
263     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
264     * @param thumbnail The bitmap that will be shown as the initial thumbnail
265     * of the animation.
266     * @param startX The x starting location of the bitmap, relative to <var>source</var>.
267     * @param startY The y starting location of the bitmap, relative to <var>source</var>.
268     * @return Returns a new ActivityOptions object that you can use to
269     * supply these options as the options Bundle when starting an activity.
270     */
271    public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
272            Bitmap thumbnail, int startX, int startY) {
273        return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, null);
274    }
275
276    /**
277     * Create an ActivityOptions specifying an animation where a thumbnail
278     * is scaled from a given position to the new activity window that is
279     * being started.
280     *
281     * @param source The View that this thumbnail is animating from.  This
282     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
283     * @param thumbnail The bitmap that will be shown as the initial thumbnail
284     * of the animation.
285     * @param startX The x starting location of the bitmap, relative to <var>source</var>.
286     * @param startY The y starting location of the bitmap, relative to <var>source</var>.
287     * @param listener Optional OnAnimationStartedListener to find out when the
288     * requested animation has started running.  If for some reason the animation
289     * is not executed, the callback will happen immediately.
290     * @return Returns a new ActivityOptions object that you can use to
291     * supply these options as the options Bundle when starting an activity.
292     * @hide
293     */
294    public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
295            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
296        return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, true);
297    }
298
299    /**
300     * Create an ActivityOptions specifying an animation where an activity window
301     * is scaled from a given position to a thumbnail at a specified location.
302     *
303     * @param source The View that this thumbnail is animating to.  This
304     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
305     * @param thumbnail The bitmap that will be shown as the final thumbnail
306     * of the animation.
307     * @param startX The x end location of the bitmap, relative to <var>source</var>.
308     * @param startY The y end location of the bitmap, relative to <var>source</var>.
309     * @param listener Optional OnAnimationStartedListener to find out when the
310     * requested animation has started running.  If for some reason the animation
311     * is not executed, the callback will happen immediately.
312     * @return Returns a new ActivityOptions object that you can use to
313     * supply these options as the options Bundle when starting an activity.
314     * @hide
315     */
316    public static ActivityOptions makeThumbnailScaleDownAnimation(View source,
317            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
318        return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, false);
319    }
320
321    private static ActivityOptions makeThumbnailAnimation(View source,
322            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener,
323            boolean scaleUp) {
324        ActivityOptions opts = new ActivityOptions();
325        opts.mPackageName = source.getContext().getPackageName();
326        opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN;
327        opts.mThumbnail = thumbnail;
328        int[] pts = new int[2];
329        source.getLocationOnScreen(pts);
330        opts.mStartX = pts[0] + startX;
331        opts.mStartY = pts[1] + startY;
332        opts.setOnAnimationStartedListener(source.getHandler(), listener);
333        return opts;
334    }
335
336    /**
337     * Create an ActivityOptions to transition between Activities using cross-Activity scene
338     * animations. This method carries the position of one shared element to the started Activity.
339     * The position of <code>sharedElement</code> will be used as the epicenter for the
340     * exit Transition. The position of the shared element in the launched Activity will be the
341     * epicenter of its entering Transition.
342     *
343     * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be
344     * enabled on the calling Activity to cause an exit transition. The same must be in
345     * the called Activity to get an entering transition.</p>
346     * @param activity The Activity whose window contains the shared elements.
347     * @param sharedElement The View to transition to the started Activity. sharedElement must
348     *                      have a non-null sharedElementName.
349     * @param sharedElementName The shared element name as used in the target Activity. This may
350     *                          be null if it has the same name as sharedElement.
351     * @return Returns a new ActivityOptions object that you can use to
352     *         supply these options as the options Bundle when starting an activity.
353     * @see android.transition.Transition#setEpicenterCallback(
354     *          android.transition.Transition.EpicenterCallback)
355     */
356    public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
357            View sharedElement, String sharedElementName) {
358        return makeSceneTransitionAnimation(activity, Pair.create(sharedElement, sharedElementName));
359    }
360
361    /**
362     * Create an ActivityOptions to transition between Activities using cross-Activity scene
363     * animations. This method carries the position of multiple shared elements to the started
364     * Activity. The position of the first element in sharedElements
365     * will be used as the epicenter for the exit Transition. The position of the associated
366     * shared element in the launched Activity will be the epicenter of its entering Transition.
367     *
368     * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be
369     * enabled on the calling Activity to cause an exit transition. The same must be in
370     * the called Activity to get an entering transition.</p>
371     * @param activity The Activity whose window contains the shared elements.
372     * @param sharedElements The names of the shared elements to transfer to the called
373     *                       Activity and their associated Views. The Views must each have
374     *                       a unique shared element name.
375     * @return Returns a new ActivityOptions object that you can use to
376     *         supply these options as the options Bundle when starting an activity.
377     *         Returns null if the Window does not have {@link Window#FEATURE_CONTENT_TRANSITIONS}.
378     * @see android.transition.Transition#setEpicenterCallback(
379     *          android.transition.Transition.EpicenterCallback)
380     */
381    public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
382            Pair<View, String>... sharedElements) {
383        if (!activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) {
384            return null;
385        }
386        ActivityOptions opts = new ActivityOptions();
387        opts.mAnimationType = ANIM_SCENE_TRANSITION;
388
389        ArrayList<String> names = new ArrayList<String>();
390        ArrayList<View> views = new ArrayList<View>();
391
392        if (sharedElements != null) {
393            for (int i = 0; i < sharedElements.length; i++) {
394                Pair<View, String> sharedElement = sharedElements[i];
395                String sharedElementName = sharedElement.second;
396                if (sharedElementName == null) {
397                    throw new IllegalArgumentException("Shared element name must not be null");
398                }
399                names.add(sharedElementName);
400                View view = sharedElement.first;
401                if (view == null) {
402                    throw new IllegalArgumentException("Shared element must not be null");
403                }
404                views.add(sharedElement.first);
405            }
406        }
407
408        ExitTransitionCoordinator exit = new ExitTransitionCoordinator(activity, names, names,
409                views, false);
410        opts.mTransitionReceiver = exit;
411        opts.mSharedElementNames = names;
412        opts.mIsReturning = false;
413        opts.mExitCoordinatorIndex =
414                activity.mActivityTransitionState.addExitTransitionCoordinator(exit);
415        return opts;
416    }
417
418    /** @hide */
419    public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
420            ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames,
421            int resultCode, Intent resultData) {
422        ActivityOptions opts = new ActivityOptions();
423        opts.mAnimationType = ANIM_SCENE_TRANSITION;
424        opts.mSharedElementNames = sharedElementNames;
425        opts.mTransitionReceiver = exitCoordinator;
426        opts.mIsReturning = true;
427        opts.mResultCode = resultCode;
428        opts.mResultData = resultData;
429        opts.mExitCoordinatorIndex =
430                activity.mActivityTransitionState.addExitTransitionCoordinator(exitCoordinator);
431        return opts;
432    }
433
434    private ActivityOptions() {
435    }
436
437    /** @hide */
438    public ActivityOptions(Bundle opts) {
439        mPackageName = opts.getString(KEY_PACKAGE_NAME);
440        mAnimationType = opts.getInt(KEY_ANIM_TYPE);
441        switch (mAnimationType) {
442            case ANIM_CUSTOM:
443                mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
444                mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
445                mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
446                        opts.getBinder(KEY_ANIM_START_LISTENER));
447                break;
448
449            case ANIM_SCALE_UP:
450                mStartX = opts.getInt(KEY_ANIM_START_X, 0);
451                mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
452                mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0);
453                mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0);
454                break;
455
456            case ANIM_THUMBNAIL_SCALE_UP:
457            case ANIM_THUMBNAIL_SCALE_DOWN:
458                mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL);
459                mStartX = opts.getInt(KEY_ANIM_START_X, 0);
460                mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
461                mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
462                        opts.getBinder(KEY_ANIM_START_LISTENER));
463                break;
464
465            case ANIM_SCENE_TRANSITION:
466                mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER);
467                mIsReturning = opts.getBoolean(KEY_TRANSITION_IS_RETURNING, false);
468                mSharedElementNames = opts.getStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS);
469                mResultData = opts.getParcelable(KEY_RESULT_DATA);
470                mResultCode = opts.getInt(KEY_RESULT_CODE);
471                mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX);
472                break;
473        }
474    }
475
476    /** @hide */
477    public String getPackageName() {
478        return mPackageName;
479    }
480
481    /** @hide */
482    public int getAnimationType() {
483        return mAnimationType;
484    }
485
486    /** @hide */
487    public int getCustomEnterResId() {
488        return mCustomEnterResId;
489    }
490
491    /** @hide */
492    public int getCustomExitResId() {
493        return mCustomExitResId;
494    }
495
496    /** @hide */
497    public Bitmap getThumbnail() {
498        return mThumbnail;
499    }
500
501    /** @hide */
502    public int getStartX() {
503        return mStartX;
504    }
505
506    /** @hide */
507    public int getStartY() {
508        return mStartY;
509    }
510
511    /** @hide */
512    public int getStartWidth() {
513        return mStartWidth;
514    }
515
516    /** @hide */
517    public int getStartHeight() {
518        return mStartHeight;
519    }
520
521    /** @hide */
522    public IRemoteCallback getOnAnimationStartListener() {
523        return mAnimationStartedListener;
524    }
525
526    /** @hide */
527    public int getExitCoordinatorKey() { return mExitCoordinatorIndex; }
528
529    /** @hide */
530    public void abort() {
531        if (mAnimationStartedListener != null) {
532            try {
533                mAnimationStartedListener.sendResult(null);
534            } catch (RemoteException e) {
535            }
536        }
537    }
538
539    /** @hide */
540    public boolean isReturning() {
541        return mIsReturning;
542    }
543
544    /** @hide */
545    public ArrayList<String> getSharedElementNames() {
546        return mSharedElementNames;
547    }
548
549    /** @hide */
550    public ResultReceiver getResultReceiver() { return mTransitionReceiver; }
551
552    /** @hide */
553    public int getResultCode() { return mResultCode; }
554
555    /** @hide */
556    public Intent getResultData() { return mResultData; }
557
558    /** @hide */
559    public static void abort(Bundle options) {
560        if (options != null) {
561            (new ActivityOptions(options)).abort();
562        }
563    }
564
565    /**
566     * Update the current values in this ActivityOptions from those supplied
567     * in <var>otherOptions</var>.  Any values
568     * defined in <var>otherOptions</var> replace those in the base options.
569     */
570    public void update(ActivityOptions otherOptions) {
571        if (otherOptions.mPackageName != null) {
572            mPackageName = otherOptions.mPackageName;
573        }
574        mTransitionReceiver = null;
575        mSharedElementNames = null;
576        mIsReturning = false;
577        mResultData = null;
578        mResultCode = 0;
579        mExitCoordinatorIndex = 0;
580        switch (otherOptions.mAnimationType) {
581            case ANIM_CUSTOM:
582                mAnimationType = otherOptions.mAnimationType;
583                mCustomEnterResId = otherOptions.mCustomEnterResId;
584                mCustomExitResId = otherOptions.mCustomExitResId;
585                mThumbnail = null;
586                if (mAnimationStartedListener != null) {
587                    try {
588                        mAnimationStartedListener.sendResult(null);
589                    } catch (RemoteException e) {
590                    }
591                }
592                mAnimationStartedListener = otherOptions.mAnimationStartedListener;
593                break;
594            case ANIM_SCALE_UP:
595                mAnimationType = otherOptions.mAnimationType;
596                mStartX = otherOptions.mStartX;
597                mStartY = otherOptions.mStartY;
598                mStartWidth = otherOptions.mStartWidth;
599                mStartHeight = otherOptions.mStartHeight;
600                if (mAnimationStartedListener != null) {
601                    try {
602                        mAnimationStartedListener.sendResult(null);
603                    } catch (RemoteException e) {
604                    }
605                }
606                mAnimationStartedListener = null;
607                break;
608            case ANIM_THUMBNAIL_SCALE_UP:
609            case ANIM_THUMBNAIL_SCALE_DOWN:
610                mAnimationType = otherOptions.mAnimationType;
611                mThumbnail = otherOptions.mThumbnail;
612                mStartX = otherOptions.mStartX;
613                mStartY = otherOptions.mStartY;
614                if (mAnimationStartedListener != null) {
615                    try {
616                        mAnimationStartedListener.sendResult(null);
617                    } catch (RemoteException e) {
618                    }
619                }
620                mAnimationStartedListener = otherOptions.mAnimationStartedListener;
621                break;
622            case ANIM_SCENE_TRANSITION:
623                mAnimationType = otherOptions.mAnimationType;
624                mTransitionReceiver = otherOptions.mTransitionReceiver;
625                mSharedElementNames = otherOptions.mSharedElementNames;
626                mIsReturning = otherOptions.mIsReturning;
627                mThumbnail = null;
628                mAnimationStartedListener = null;
629                mResultData = otherOptions.mResultData;
630                mResultCode = otherOptions.mResultCode;
631                mExitCoordinatorIndex = otherOptions.mExitCoordinatorIndex;
632                break;
633        }
634    }
635
636    /**
637     * Returns the created options as a Bundle, which can be passed to
638     * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
639     * Context.startActivity(Intent, Bundle)} and related methods.
640     * Note that the returned Bundle is still owned by the ActivityOptions
641     * object; you must not modify it, but can supply it to the startActivity
642     * methods that take an options Bundle.
643     */
644    public Bundle toBundle() {
645        Bundle b = new Bundle();
646        if (mPackageName != null) {
647            b.putString(KEY_PACKAGE_NAME, mPackageName);
648        }
649        switch (mAnimationType) {
650            case ANIM_CUSTOM:
651                b.putInt(KEY_ANIM_TYPE, mAnimationType);
652                b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
653                b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
654                b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
655                        != null ? mAnimationStartedListener.asBinder() : null);
656                break;
657            case ANIM_SCALE_UP:
658                b.putInt(KEY_ANIM_TYPE, mAnimationType);
659                b.putInt(KEY_ANIM_START_X, mStartX);
660                b.putInt(KEY_ANIM_START_Y, mStartY);
661                b.putInt(KEY_ANIM_START_WIDTH, mStartWidth);
662                b.putInt(KEY_ANIM_START_HEIGHT, mStartHeight);
663                break;
664            case ANIM_THUMBNAIL_SCALE_UP:
665            case ANIM_THUMBNAIL_SCALE_DOWN:
666                b.putInt(KEY_ANIM_TYPE, mAnimationType);
667                b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
668                b.putInt(KEY_ANIM_START_X, mStartX);
669                b.putInt(KEY_ANIM_START_Y, mStartY);
670                b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
671                        != null ? mAnimationStartedListener.asBinder() : null);
672                break;
673            case ANIM_SCENE_TRANSITION:
674                b.putInt(KEY_ANIM_TYPE, mAnimationType);
675                if (mTransitionReceiver != null) {
676                    b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionReceiver);
677                }
678                b.putBoolean(KEY_TRANSITION_IS_RETURNING, mIsReturning);
679                b.putStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS, mSharedElementNames);
680                b.putParcelable(KEY_RESULT_DATA, mResultData);
681                b.putInt(KEY_RESULT_CODE, mResultCode);
682                b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
683                break;
684        }
685        return b;
686    }
687
688    /**
689     * Return the filtered options only meant to be seen by the target activity itself
690     * @hide
691     */
692    public ActivityOptions forTargetActivity() {
693        if (mAnimationType == ANIM_SCENE_TRANSITION) {
694            final ActivityOptions result = new ActivityOptions();
695            result.update(this);
696            return result;
697        }
698
699        return null;
700    }
701
702}
703