• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
makeCustomAnimation(Context context, int enterResId, int exitResId)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      */
makeCustomAnimation(Context context, int enterResId, int exitResId, Handler handler, OnAnimationStartedListener listener)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 
setOnAnimationStartedListener(Handler handler, OnAnimationStartedListener listener)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 {
onAnimationStarted()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      */
makeScaleUpAnimation(View source, int startX, int startY, int width, int height)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      */
makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY)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      */
makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener)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      */
makeThumbnailScaleDownAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener)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 
makeThumbnailAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener, boolean scaleUp)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      */
makeThumbnailAspectScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, OnAnimationStartedListener listener)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      */
makeThumbnailAspectScaleDownAnimation(View source, Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, OnAnimationStartedListener listener)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 
makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, OnAnimationStartedListener listener, boolean scaleUp)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      */
makeSceneTransitionAnimation(Activity activity, View sharedElement, String sharedElementName)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      */
makeSceneTransitionAnimation(Activity activity, Pair<View, String>... sharedElements)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 */
makeSceneTransitionAnimation(Activity activity, ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames, int resultCode, Intent resultData)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      */
makeTaskLaunchBehind()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 */
getLaunchTaskBehind()524     public boolean getLaunchTaskBehind() {
525         return mAnimationType == ANIM_LAUNCH_TASK_BEHIND;
526     }
527 
ActivityOptions()528     private ActivityOptions() {
529     }
530 
531     /** @hide */
ActivityOptions(Bundle opts)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 */
getPackageName()575     public String getPackageName() {
576         return mPackageName;
577     }
578 
579     /** @hide */
getAnimationType()580     public int getAnimationType() {
581         return mAnimationType;
582     }
583 
584     /** @hide */
getCustomEnterResId()585     public int getCustomEnterResId() {
586         return mCustomEnterResId;
587     }
588 
589     /** @hide */
getCustomExitResId()590     public int getCustomExitResId() {
591         return mCustomExitResId;
592     }
593 
594     /** @hide */
getThumbnail()595     public Bitmap getThumbnail() {
596         return mThumbnail;
597     }
598 
599     /** @hide */
getStartX()600     public int getStartX() {
601         return mStartX;
602     }
603 
604     /** @hide */
getStartY()605     public int getStartY() {
606         return mStartY;
607     }
608 
609     /** @hide */
getWidth()610     public int getWidth() {
611         return mWidth;
612     }
613 
614     /** @hide */
getHeight()615     public int getHeight() {
616         return mHeight;
617     }
618 
619     /** @hide */
getOnAnimationStartListener()620     public IRemoteCallback getOnAnimationStartListener() {
621         return mAnimationStartedListener;
622     }
623 
624     /** @hide */
getExitCoordinatorKey()625     public int getExitCoordinatorKey() { return mExitCoordinatorIndex; }
626 
627     /** @hide */
abort()628     public void abort() {
629         if (mAnimationStartedListener != null) {
630             try {
631                 mAnimationStartedListener.sendResult(null);
632             } catch (RemoteException e) {
633             }
634         }
635     }
636 
637     /** @hide */
isReturning()638     public boolean isReturning() {
639         return mIsReturning;
640     }
641 
642     /** @hide */
getSharedElementNames()643     public ArrayList<String> getSharedElementNames() {
644         return mSharedElementNames;
645     }
646 
647     /** @hide */
getResultReceiver()648     public ResultReceiver getResultReceiver() { return mTransitionReceiver; }
649 
650     /** @hide */
getResultCode()651     public int getResultCode() { return mResultCode; }
652 
653     /** @hide */
getResultData()654     public Intent getResultData() { return mResultData; }
655 
656     /** @hide */
abort(Bundle options)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      */
update(ActivityOptions otherOptions)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      */
toBundle()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      */
forTargetActivity()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