Home | History | Annotate | Download | only in app
      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 
     17 package android.app;
     18 
     19 import android.content.Context;
     20 import android.content.Intent;
     21 import android.graphics.Bitmap;
     22 import android.os.Bundle;
     23 import android.os.Handler;
     24 import android.os.IRemoteCallback;
     25 import android.os.RemoteException;
     26 import android.os.ResultReceiver;
     27 import android.util.Pair;
     28 import android.view.View;
     29 import android.view.Window;
     30 
     31 import 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  */
     38 public 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_ACTIVITY_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_ACTIVITY_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_ACTIVITY_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