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