ActivityOptions.java revision 345d4f4f14038c2225cd599f9c432b25e572dc2c
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_WIDTH = "android:animWidth";
88
89    /**
90     * Initial height of the animation.
91     * @hide
92     */
93    public static final String KEY_ANIM_HEIGHT = "android:animHeight";
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    /** @hide */
128    public static final int ANIM_DEFAULT = 6;
129    /** @hide */
130    public static final int ANIM_LAUNCH_TASK_BEHIND = 7;
131    /** @hide */
132    public static final int ANIM_THUMBNAIL_ASPECT_SCALE_UP = 8;
133    /** @hide */
134    public static final int ANIM_THUMBNAIL_ASPECT_SCALE_DOWN = 9;
135
136    private String mPackageName;
137    private int mAnimationType = ANIM_NONE;
138    private int mCustomEnterResId;
139    private int mCustomExitResId;
140    private Bitmap mThumbnail;
141    private int mStartX;
142    private int mStartY;
143    private int mWidth;
144    private int mHeight;
145    private IRemoteCallback mAnimationStartedListener;
146    private ResultReceiver mTransitionReceiver;
147    private boolean mIsReturning;
148    private ArrayList<String> mSharedElementNames;
149    private Intent mResultData;
150    private int mResultCode;
151    private int mExitCoordinatorIndex;
152
153    /**
154     * Create an ActivityOptions specifying a custom animation to run when
155     * the activity is displayed.
156     *
157     * @param context Who is defining this.  This is the application that the
158     * animation resources will be loaded from.
159     * @param enterResId A resource ID of the animation resource to use for
160     * the incoming activity.  Use 0 for no animation.
161     * @param exitResId A resource ID of the animation resource to use for
162     * the outgoing activity.  Use 0 for no animation.
163     * @return Returns a new ActivityOptions object that you can use to
164     * supply these options as the options Bundle when starting an activity.
165     */
166    public static ActivityOptions makeCustomAnimation(Context context,
167            int enterResId, int exitResId) {
168        return makeCustomAnimation(context, enterResId, exitResId, null, null);
169    }
170
171    /**
172     * Create an ActivityOptions specifying a custom animation to run when
173     * the activity is displayed.
174     *
175     * @param context Who is defining this.  This is the application that the
176     * animation resources will be loaded from.
177     * @param enterResId A resource ID of the animation resource to use for
178     * the incoming activity.  Use 0 for no animation.
179     * @param exitResId A resource ID of the animation resource to use for
180     * the outgoing activity.  Use 0 for no animation.
181     * @param handler If <var>listener</var> is non-null this must be a valid
182     * Handler on which to dispatch the callback; otherwise it should be null.
183     * @param listener Optional OnAnimationStartedListener to find out when the
184     * requested animation has started running.  If for some reason the animation
185     * is not executed, the callback will happen immediately.
186     * @return Returns a new ActivityOptions object that you can use to
187     * supply these options as the options Bundle when starting an activity.
188     * @hide
189     */
190    public static ActivityOptions makeCustomAnimation(Context context,
191            int enterResId, int exitResId, Handler handler, OnAnimationStartedListener listener) {
192        ActivityOptions opts = new ActivityOptions();
193        opts.mPackageName = context.getPackageName();
194        opts.mAnimationType = ANIM_CUSTOM;
195        opts.mCustomEnterResId = enterResId;
196        opts.mCustomExitResId = exitResId;
197        opts.setOnAnimationStartedListener(handler, listener);
198        return opts;
199    }
200
201    private void setOnAnimationStartedListener(Handler handler,
202            OnAnimationStartedListener listener) {
203        if (listener != null) {
204            final Handler h = handler;
205            final OnAnimationStartedListener finalListener = listener;
206            mAnimationStartedListener = new IRemoteCallback.Stub() {
207                @Override public void sendResult(Bundle data) throws RemoteException {
208                    h.post(new Runnable() {
209                        @Override public void run() {
210                            finalListener.onAnimationStarted();
211                        }
212                    });
213                }
214            };
215        }
216    }
217
218    /**
219     * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation}
220     * to find out when the given animation has started running.
221     * @hide
222     */
223    public interface OnAnimationStartedListener {
224        void onAnimationStarted();
225    }
226
227    /**
228     * Create an ActivityOptions specifying an animation where the new
229     * activity is scaled from a small originating area of the screen to
230     * its final full representation.
231     *
232     * <p>If the Intent this is being used with has not set its
233     * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds},
234     * those bounds will be filled in for you based on the initial
235     * bounds passed in here.
236     *
237     * @param source The View that the new activity is animating from.  This
238     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
239     * @param startX The x starting location of the new activity, relative to <var>source</var>.
240     * @param startY The y starting location of the activity, relative to <var>source</var>.
241     * @param width The initial width of the new activity.
242     * @param height The initial height of the new activity.
243     * @return Returns a new ActivityOptions object that you can use to
244     * supply these options as the options Bundle when starting an activity.
245     */
246    public static ActivityOptions makeScaleUpAnimation(View source,
247            int startX, int startY, int width, int height) {
248        ActivityOptions opts = new ActivityOptions();
249        opts.mPackageName = source.getContext().getPackageName();
250        opts.mAnimationType = ANIM_SCALE_UP;
251        int[] pts = new int[2];
252        source.getLocationOnScreen(pts);
253        opts.mStartX = pts[0] + startX;
254        opts.mStartY = pts[1] + startY;
255        opts.mWidth = width;
256        opts.mHeight = height;
257        return opts;
258    }
259
260    /**
261     * Create an ActivityOptions specifying an animation where a thumbnail
262     * is scaled from a given position to the new activity window that is
263     * being started.
264     *
265     * <p>If the Intent this is being used with has not set its
266     * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds},
267     * those bounds will be filled in for you based on the initial
268     * thumbnail location and size provided here.
269     *
270     * @param source The View that this thumbnail is animating from.  This
271     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
272     * @param thumbnail The bitmap that will be shown as the initial thumbnail
273     * of the animation.
274     * @param startX The x starting location of the bitmap, relative to <var>source</var>.
275     * @param startY The y starting location of the bitmap, relative to <var>source</var>.
276     * @return Returns a new ActivityOptions object that you can use to
277     * supply these options as the options Bundle when starting an activity.
278     */
279    public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
280            Bitmap thumbnail, int startX, int startY) {
281        return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, null);
282    }
283
284    /**
285     * Create an ActivityOptions specifying an animation where a thumbnail
286     * is scaled from a given position to the new activity window that is
287     * being started.
288     *
289     * @param source The View that this thumbnail is animating from.  This
290     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
291     * @param thumbnail The bitmap that will be shown as the initial thumbnail
292     * of the animation.
293     * @param startX The x starting location of the bitmap, relative to <var>source</var>.
294     * @param startY The y starting location of the bitmap, relative to <var>source</var>.
295     * @param listener Optional OnAnimationStartedListener to find out when the
296     * requested animation has started running.  If for some reason the animation
297     * is not executed, the callback will happen immediately.
298     * @return Returns a new ActivityOptions object that you can use to
299     * supply these options as the options Bundle when starting an activity.
300     * @hide
301     */
302    public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
303            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
304        return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, true);
305    }
306
307    /**
308     * Create an ActivityOptions specifying an animation where an activity window
309     * is scaled from a given position to a thumbnail at a specified location.
310     *
311     * @param source The View that this thumbnail is animating to.  This
312     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
313     * @param thumbnail The bitmap that will be shown as the final thumbnail
314     * of the animation.
315     * @param startX The x end location of the bitmap, relative to <var>source</var>.
316     * @param startY The y end location of the bitmap, relative to <var>source</var>.
317     * @param listener Optional OnAnimationStartedListener to find out when the
318     * requested animation has started running.  If for some reason the animation
319     * is not executed, the callback will happen immediately.
320     * @return Returns a new ActivityOptions object that you can use to
321     * supply these options as the options Bundle when starting an activity.
322     * @hide
323     */
324    public static ActivityOptions makeThumbnailScaleDownAnimation(View source,
325            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
326        return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, false);
327    }
328
329    private static ActivityOptions makeThumbnailAnimation(View source,
330            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener,
331            boolean scaleUp) {
332        ActivityOptions opts = new ActivityOptions();
333        opts.mPackageName = source.getContext().getPackageName();
334        opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN;
335        opts.mThumbnail = thumbnail;
336        int[] pts = new int[2];
337        source.getLocationOnScreen(pts);
338        opts.mStartX = pts[0] + startX;
339        opts.mStartY = pts[1] + startY;
340        opts.setOnAnimationStartedListener(source.getHandler(), listener);
341        return opts;
342    }
343
344    /**
345     * Create an ActivityOptions specifying an animation where the new activity
346     * window and a thumbnail is aspect-scaled to a new location.
347     *
348     * @param source The View that this thumbnail is animating from.  This
349     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
350     * @param thumbnail The bitmap that will be shown as the initial thumbnail
351     * of the animation.
352     * @param startX The x starting location of the bitmap, relative to <var>source</var>.
353     * @param startY The y starting location of the bitmap, relative to <var>source</var>.
354     * @param listener Optional OnAnimationStartedListener to find out when the
355     * requested animation has started running.  If for some reason the animation
356     * is not executed, the callback will happen immediately.
357     * @return Returns a new ActivityOptions object that you can use to
358     * supply these options as the options Bundle when starting an activity.
359     * @hide
360     */
361    public static ActivityOptions makeThumbnailAspectScaleUpAnimation(View source,
362            Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight,
363            OnAnimationStartedListener listener) {
364        return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY,
365                targetWidth, targetHeight, listener, true);
366    }
367
368    /**
369     * Create an ActivityOptions specifying an animation where the new activity
370     * window and a thumbnail is aspect-scaled to a new location.
371     *
372     * @param source The View that this thumbnail is animating to.  This
373     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
374     * @param thumbnail The bitmap that will be shown as the final thumbnail
375     * of the animation.
376     * @param startX The x end location of the bitmap, relative to <var>source</var>.
377     * @param startY The y end location of the bitmap, relative to <var>source</var>.
378     * @param listener Optional OnAnimationStartedListener to find out when the
379     * requested animation has started running.  If for some reason the animation
380     * is not executed, the callback will happen immediately.
381     * @return Returns a new ActivityOptions object that you can use to
382     * supply these options as the options Bundle when starting an activity.
383     * @hide
384     */
385    public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source,
386            Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight,
387            OnAnimationStartedListener listener) {
388        return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY,
389                targetWidth, targetHeight, listener, false);
390    }
391
392    private static ActivityOptions makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail,
393            int startX, int startY, int targetWidth, int targetHeight,
394            OnAnimationStartedListener listener, boolean scaleUp) {
395        ActivityOptions opts = new ActivityOptions();
396        opts.mPackageName = source.getContext().getPackageName();
397        opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_ASPECT_SCALE_UP :
398                ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
399        opts.mThumbnail = thumbnail;
400        int[] pts = new int[2];
401        source.getLocationOnScreen(pts);
402        opts.mStartX = pts[0] + startX;
403        opts.mStartY = pts[1] + startY;
404        opts.mWidth = targetWidth;
405        opts.mHeight = targetHeight;
406        opts.setOnAnimationStartedListener(source.getHandler(), listener);
407        return opts;
408    }
409
410    /**
411     * Create an ActivityOptions to transition between Activities using cross-Activity scene
412     * animations. This method carries the position of one shared element to the started Activity.
413     * The position of <code>sharedElement</code> will be used as the epicenter for the
414     * exit Transition. The position of the shared element in the launched Activity will be the
415     * epicenter of its entering Transition.
416     *
417     * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be
418     * enabled on the calling Activity to cause an exit transition. The same must be in
419     * the called Activity to get an entering transition.</p>
420     * @param activity The Activity whose window contains the shared elements.
421     * @param sharedElement The View to transition to the started Activity.
422     * @param sharedElementName The shared element name as used in the target Activity. This
423     *                          must not be null.
424     * @return Returns a new ActivityOptions object that you can use to
425     *         supply these options as the options Bundle when starting an activity.
426     * @see android.transition.Transition#setEpicenterCallback(
427     *          android.transition.Transition.EpicenterCallback)
428     */
429    public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
430            View sharedElement, String sharedElementName) {
431        return makeSceneTransitionAnimation(activity, Pair.create(sharedElement, sharedElementName));
432    }
433
434    /**
435     * Create an ActivityOptions to transition between Activities using cross-Activity scene
436     * animations. This method carries the position of multiple shared elements to the started
437     * Activity. The position of the first element in sharedElements
438     * will be used as the epicenter for the exit Transition. The position of the associated
439     * shared element in the launched Activity will be the epicenter of its entering Transition.
440     *
441     * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be
442     * enabled on the calling Activity to cause an exit transition. The same must be in
443     * the called Activity to get an entering transition.</p>
444     * @param activity The Activity whose window contains the shared elements.
445     * @param sharedElements The names of the shared elements to transfer to the called
446     *                       Activity and their associated Views. The Views must each have
447     *                       a unique shared element name.
448     * @return Returns a new ActivityOptions object that you can use to
449     *         supply these options as the options Bundle when starting an activity.
450     * @see android.transition.Transition#setEpicenterCallback(
451     *          android.transition.Transition.EpicenterCallback)
452     */
453    public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
454            Pair<View, String>... sharedElements) {
455        ActivityOptions opts = new ActivityOptions();
456        if (!activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) {
457            opts.mAnimationType = ANIM_DEFAULT;
458            return opts;
459        }
460        opts.mAnimationType = ANIM_SCENE_TRANSITION;
461
462        ArrayList<String> names = new ArrayList<String>();
463        ArrayList<View> views = new ArrayList<View>();
464
465        if (sharedElements != null) {
466            for (int i = 0; i < sharedElements.length; i++) {
467                Pair<View, String> sharedElement = sharedElements[i];
468                String sharedElementName = sharedElement.second;
469                if (sharedElementName == null) {
470                    throw new IllegalArgumentException("Shared element name must not be null");
471                }
472                names.add(sharedElementName);
473                View view = sharedElement.first;
474                if (view == null) {
475                    throw new IllegalArgumentException("Shared element must not be null");
476                }
477                views.add(sharedElement.first);
478            }
479        }
480
481        ExitTransitionCoordinator exit = new ExitTransitionCoordinator(activity, names, names,
482                views, false);
483        opts.mTransitionReceiver = exit;
484        opts.mSharedElementNames = names;
485        opts.mIsReturning = false;
486        opts.mExitCoordinatorIndex =
487                activity.mActivityTransitionState.addExitTransitionCoordinator(exit);
488        return opts;
489    }
490
491    /** @hide */
492    public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
493            ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames,
494            int resultCode, Intent resultData) {
495        ActivityOptions opts = new ActivityOptions();
496        opts.mAnimationType = ANIM_SCENE_TRANSITION;
497        opts.mSharedElementNames = sharedElementNames;
498        opts.mTransitionReceiver = exitCoordinator;
499        opts.mIsReturning = true;
500        opts.mResultCode = resultCode;
501        opts.mResultData = resultData;
502        opts.mExitCoordinatorIndex =
503                activity.mActivityTransitionState.addExitTransitionCoordinator(exitCoordinator);
504        return opts;
505    }
506
507    /**
508     * If set along with Intent.FLAG_ACTIVITY_NEW_DOCUMENT then the task being launched will not be
509     * presented to the user but will instead be only available through the recents task list.
510     * In addition, the new task wil be affiliated with the launching activity's task.
511     * Affiliated tasks are grouped together in the recents task list.
512     *
513     * <p>This behavior is not supported for activities with {@link
514     * android.R.styleable#AndroidManifestActivity_launchMode launchMode} values of
515     * <code>singleInstance</code> or <code>singleTask</code>.
516     */
517    public static ActivityOptions makeTaskLaunchBehind() {
518        final ActivityOptions opts = new ActivityOptions();
519        opts.mAnimationType = ANIM_LAUNCH_TASK_BEHIND;
520        return opts;
521    }
522
523    /** @hide */
524    public boolean getLaunchTaskBehind() {
525        return mAnimationType == ANIM_LAUNCH_TASK_BEHIND;
526    }
527
528    private ActivityOptions() {
529    }
530
531    /** @hide */
532    public ActivityOptions(Bundle opts) {
533        mPackageName = opts.getString(KEY_PACKAGE_NAME);
534        mAnimationType = opts.getInt(KEY_ANIM_TYPE);
535        switch (mAnimationType) {
536            case ANIM_CUSTOM:
537                mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
538                mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
539                mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
540                        opts.getBinder(KEY_ANIM_START_LISTENER));
541                break;
542
543            case ANIM_SCALE_UP:
544                mStartX = opts.getInt(KEY_ANIM_START_X, 0);
545                mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
546                mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
547                mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
548                break;
549
550            case ANIM_THUMBNAIL_SCALE_UP:
551            case ANIM_THUMBNAIL_SCALE_DOWN:
552            case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
553            case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
554                mThumbnail = (Bitmap) opts.getParcelable(KEY_ANIM_THUMBNAIL);
555                mStartX = opts.getInt(KEY_ANIM_START_X, 0);
556                mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
557                mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
558                mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
559                mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
560                        opts.getBinder(KEY_ANIM_START_LISTENER));
561                break;
562
563            case ANIM_SCENE_TRANSITION:
564                mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER);
565                mIsReturning = opts.getBoolean(KEY_TRANSITION_IS_RETURNING, false);
566                mSharedElementNames = opts.getStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS);
567                mResultData = opts.getParcelable(KEY_RESULT_DATA);
568                mResultCode = opts.getInt(KEY_RESULT_CODE);
569                mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX);
570                break;
571        }
572    }
573
574    /** @hide */
575    public String getPackageName() {
576        return mPackageName;
577    }
578
579    /** @hide */
580    public int getAnimationType() {
581        return mAnimationType;
582    }
583
584    /** @hide */
585    public int getCustomEnterResId() {
586        return mCustomEnterResId;
587    }
588
589    /** @hide */
590    public int getCustomExitResId() {
591        return mCustomExitResId;
592    }
593
594    /** @hide */
595    public Bitmap getThumbnail() {
596        return mThumbnail;
597    }
598
599    /** @hide */
600    public int getStartX() {
601        return mStartX;
602    }
603
604    /** @hide */
605    public int getStartY() {
606        return mStartY;
607    }
608
609    /** @hide */
610    public int getWidth() {
611        return mWidth;
612    }
613
614    /** @hide */
615    public int getHeight() {
616        return mHeight;
617    }
618
619    /** @hide */
620    public IRemoteCallback getOnAnimationStartListener() {
621        return mAnimationStartedListener;
622    }
623
624    /** @hide */
625    public int getExitCoordinatorKey() { return mExitCoordinatorIndex; }
626
627    /** @hide */
628    public void abort() {
629        if (mAnimationStartedListener != null) {
630            try {
631                mAnimationStartedListener.sendResult(null);
632            } catch (RemoteException e) {
633            }
634        }
635    }
636
637    /** @hide */
638    public boolean isReturning() {
639        return mIsReturning;
640    }
641
642    /** @hide */
643    public ArrayList<String> getSharedElementNames() {
644        return mSharedElementNames;
645    }
646
647    /** @hide */
648    public ResultReceiver getResultReceiver() { return mTransitionReceiver; }
649
650    /** @hide */
651    public int getResultCode() { return mResultCode; }
652
653    /** @hide */
654    public Intent getResultData() { return mResultData; }
655
656    /** @hide */
657    public static void abort(Bundle options) {
658        if (options != null) {
659            (new ActivityOptions(options)).abort();
660        }
661    }
662
663    /**
664     * Update the current values in this ActivityOptions from those supplied
665     * in <var>otherOptions</var>.  Any values
666     * defined in <var>otherOptions</var> replace those in the base options.
667     */
668    public void update(ActivityOptions otherOptions) {
669        if (otherOptions.mPackageName != null) {
670            mPackageName = otherOptions.mPackageName;
671        }
672        mTransitionReceiver = null;
673        mSharedElementNames = null;
674        mIsReturning = false;
675        mResultData = null;
676        mResultCode = 0;
677        mExitCoordinatorIndex = 0;
678        mAnimationType = otherOptions.mAnimationType;
679        switch (otherOptions.mAnimationType) {
680            case ANIM_CUSTOM:
681                mCustomEnterResId = otherOptions.mCustomEnterResId;
682                mCustomExitResId = otherOptions.mCustomExitResId;
683                mThumbnail = null;
684                if (mAnimationStartedListener != null) {
685                    try {
686                        mAnimationStartedListener.sendResult(null);
687                    } catch (RemoteException e) {
688                    }
689                }
690                mAnimationStartedListener = otherOptions.mAnimationStartedListener;
691                break;
692            case ANIM_SCALE_UP:
693                mStartX = otherOptions.mStartX;
694                mStartY = otherOptions.mStartY;
695                mWidth = otherOptions.mWidth;
696                mHeight = otherOptions.mHeight;
697                if (mAnimationStartedListener != null) {
698                    try {
699                        mAnimationStartedListener.sendResult(null);
700                    } catch (RemoteException e) {
701                    }
702                }
703                mAnimationStartedListener = null;
704                break;
705            case ANIM_THUMBNAIL_SCALE_UP:
706            case ANIM_THUMBNAIL_SCALE_DOWN:
707            case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
708            case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
709                mThumbnail = otherOptions.mThumbnail;
710                mStartX = otherOptions.mStartX;
711                mStartY = otherOptions.mStartY;
712                mWidth = otherOptions.mWidth;
713                mHeight = otherOptions.mHeight;
714                if (mAnimationStartedListener != null) {
715                    try {
716                        mAnimationStartedListener.sendResult(null);
717                    } catch (RemoteException e) {
718                    }
719                }
720                mAnimationStartedListener = otherOptions.mAnimationStartedListener;
721                break;
722            case ANIM_SCENE_TRANSITION:
723                mTransitionReceiver = otherOptions.mTransitionReceiver;
724                mSharedElementNames = otherOptions.mSharedElementNames;
725                mIsReturning = otherOptions.mIsReturning;
726                mThumbnail = null;
727                mAnimationStartedListener = null;
728                mResultData = otherOptions.mResultData;
729                mResultCode = otherOptions.mResultCode;
730                mExitCoordinatorIndex = otherOptions.mExitCoordinatorIndex;
731                break;
732        }
733    }
734
735    /**
736     * Returns the created options as a Bundle, which can be passed to
737     * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
738     * Context.startActivity(Intent, Bundle)} and related methods.
739     * Note that the returned Bundle is still owned by the ActivityOptions
740     * object; you must not modify it, but can supply it to the startActivity
741     * methods that take an options Bundle.
742     */
743    public Bundle toBundle() {
744        if (mAnimationType == ANIM_DEFAULT) {
745            return null;
746        }
747        Bundle b = new Bundle();
748        if (mPackageName != null) {
749            b.putString(KEY_PACKAGE_NAME, mPackageName);
750        }
751        b.putInt(KEY_ANIM_TYPE, mAnimationType);
752        switch (mAnimationType) {
753            case ANIM_CUSTOM:
754                b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
755                b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
756                b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
757                        != null ? mAnimationStartedListener.asBinder() : null);
758                break;
759            case ANIM_SCALE_UP:
760                b.putInt(KEY_ANIM_START_X, mStartX);
761                b.putInt(KEY_ANIM_START_Y, mStartY);
762                b.putInt(KEY_ANIM_WIDTH, mWidth);
763                b.putInt(KEY_ANIM_HEIGHT, mHeight);
764                break;
765            case ANIM_THUMBNAIL_SCALE_UP:
766            case ANIM_THUMBNAIL_SCALE_DOWN:
767            case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
768            case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
769                b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
770                b.putInt(KEY_ANIM_START_X, mStartX);
771                b.putInt(KEY_ANIM_START_Y, mStartY);
772                b.putInt(KEY_ANIM_WIDTH, mWidth);
773                b.putInt(KEY_ANIM_HEIGHT, mHeight);
774                b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
775                        != null ? mAnimationStartedListener.asBinder() : null);
776                break;
777            case ANIM_SCENE_TRANSITION:
778                if (mTransitionReceiver != null) {
779                    b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionReceiver);
780                }
781                b.putBoolean(KEY_TRANSITION_IS_RETURNING, mIsReturning);
782                b.putStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS, mSharedElementNames);
783                b.putParcelable(KEY_RESULT_DATA, mResultData);
784                b.putInt(KEY_RESULT_CODE, mResultCode);
785                b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
786                break;
787        }
788
789        return b;
790    }
791
792    /**
793     * Return the filtered options only meant to be seen by the target activity itself
794     * @hide
795     */
796    public ActivityOptions forTargetActivity() {
797        if (mAnimationType == ANIM_SCENE_TRANSITION) {
798            final ActivityOptions result = new ActivityOptions();
799            result.update(this);
800            return result;
801        }
802
803        return null;
804    }
805
806}
807