blob: 094950bfb3fd3b96782571e195774938bb168db0 [file] [log] [blame]
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001/*
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
Filip Gruszczynski90186c62015-10-26 14:07:00 -070019import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
Wale Ogunwale854809c2015-12-27 16:18:19 -080020import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
Filip Gruszczynski90186c62015-10-26 14:07:00 -070021
Wale Ogunwale5122df02016-01-29 22:33:38 -080022import android.annotation.Nullable;
Dianne Hackborn6de01a92012-03-19 19:07:40 -070023import android.content.Context;
George Mount62ab9b72014-05-02 13:51:17 -070024import android.content.Intent;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070025import android.graphics.Bitmap;
Chong Zhang0fa656b2015-08-31 15:17:21 -070026import android.graphics.Rect;
Dianne Hackborn6de01a92012-03-19 19:07:40 -070027import android.os.Bundle;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070028import android.os.Handler;
29import android.os.IRemoteCallback;
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -070030import android.os.Parcelable;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070031import android.os.RemoteException;
George Mountcb4b7d92014-02-25 10:47:55 -080032import android.os.ResultReceiver;
George Mounte1803372014-02-26 19:00:52 +000033import android.util.Pair;
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070034import android.util.Slog;
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -070035import android.view.AppTransitionAnimationSpec;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070036import android.view.View;
George Mount31a21722014-03-24 17:44:36 -070037import android.view.Window;
Dianne Hackborn6de01a92012-03-19 19:07:40 -070038
George Mount62ab9b72014-05-02 13:51:17 -070039import java.util.ArrayList;
George Mount0a778ed2013-12-13 13:35:36 -080040
Dianne Hackborn6de01a92012-03-19 19:07:40 -070041/**
42 * Helper class for building an options Bundle that can be used with
43 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
44 * Context.startActivity(Intent, Bundle)} and related methods.
45 */
46public class ActivityOptions {
Adam Powellcfbe9be2013-11-06 14:58:58 -080047 private static final String TAG = "ActivityOptions";
48
Dianne Hackborn6de01a92012-03-19 19:07:40 -070049 /**
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070050 * A long in the extras delivered by {@link #requestUsageTimeReport} that contains
Dianne Hackborn67ba2c72015-06-05 14:23:38 -070051 * the total time (in ms) the user spent in the app flow.
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070052 */
Dianne Hackborna750a632015-06-16 17:18:23 -070053 public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070054
55 /**
56 * A Bundle in the extras delivered by {@link #requestUsageTimeReport} that contains
57 * detailed information about the time spent in each package associated with the app;
58 * each key is a package name, whose value is a long containing the time (in ms).
59 */
Dianne Hackborn67ba2c72015-06-05 14:23:38 -070060 public static final String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070061
62 /**
Dianne Hackborn6de01a92012-03-19 19:07:40 -070063 * The package name that created the options.
64 * @hide
65 */
Dianne Hackborna750a632015-06-16 17:18:23 -070066 public static final String KEY_PACKAGE_NAME = "android:activity.packageName";
Dianne Hackborn6de01a92012-03-19 19:07:40 -070067
68 /**
Wale Ogunwale7a8fa602015-11-18 15:56:57 -080069 * The bounds (window size) that the activity should be launched in. Set to null explicitly for
70 * full screen. If the key is not found, previous bounds will be preserved.
71 * NOTE: This value is ignored on devices that don't have
Wale Ogunwale854809c2015-12-27 16:18:19 -080072 * {@link android.content.pm.PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT} or
73 * {@link android.content.pm.PackageManager#FEATURE_PICTURE_IN_PICTURE} enabled.
Chong Zhang0fa656b2015-08-31 15:17:21 -070074 * @hide
75 */
Wale Ogunwale7a8fa602015-11-18 15:56:57 -080076 public static final String KEY_LAUNCH_BOUNDS = "android:activity.launchBounds";
Chong Zhang0fa656b2015-08-31 15:17:21 -070077
78 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070079 * Type of animation that arguments specify.
80 * @hide
81 */
Dianne Hackborna750a632015-06-16 17:18:23 -070082 public static final String KEY_ANIM_TYPE = "android:activity.animType";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070083
84 /**
Dianne Hackborn6de01a92012-03-19 19:07:40 -070085 * Custom enter animation resource ID.
86 * @hide
87 */
Dianne Hackborna750a632015-06-16 17:18:23 -070088 public static final String KEY_ANIM_ENTER_RES_ID = "android:activity.animEnterRes";
Dianne Hackborn6de01a92012-03-19 19:07:40 -070089
90 /**
91 * Custom exit animation resource ID.
92 * @hide
93 */
Dianne Hackborna750a632015-06-16 17:18:23 -070094 public static final String KEY_ANIM_EXIT_RES_ID = "android:activity.animExitRes";
Dianne Hackborn6de01a92012-03-19 19:07:40 -070095
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070096 /**
Winson Chung044d5292014-11-06 11:05:19 -080097 * Custom in-place animation resource ID.
98 * @hide
99 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700100 public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:activity.animInPlaceRes";
Winson Chung044d5292014-11-06 11:05:19 -0800101
102 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700103 * Bitmap for thumbnail animation.
104 * @hide
105 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700106 public static final String KEY_ANIM_THUMBNAIL = "android:activity.animThumbnail";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700107
108 /**
109 * Start X position of thumbnail animation.
110 * @hide
111 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700112 public static final String KEY_ANIM_START_X = "android:activity.animStartX";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700113
114 /**
115 * Start Y position of thumbnail animation.
116 * @hide
117 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700118 public static final String KEY_ANIM_START_Y = "android:activity.animStartY";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700119
120 /**
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700121 * Initial width of the animation.
122 * @hide
123 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700124 public static final String KEY_ANIM_WIDTH = "android:activity.animWidth";
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700125
126 /**
127 * Initial height of the animation.
128 * @hide
129 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700130 public static final String KEY_ANIM_HEIGHT = "android:activity.animHeight";
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700131
132 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700133 * Callback for when animation is started.
134 * @hide
135 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700136 public static final String KEY_ANIM_START_LISTENER = "android:activity.animStartListener";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700137
Adam Powell18e905f2013-10-24 14:27:48 -0700138 /**
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700139 * Callback for when the last frame of the animation is played.
140 * @hide
141 */
142 private static final String KEY_ANIMATION_FINISHED_LISTENER =
143 "android:activity.animationFinishedListener";
144
145 /**
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700146 * Descriptions of app transition animations to be played during the activity launch.
147 */
148 private static final String KEY_ANIM_SPECS = "android:activity.animSpecs";
149
150 /**
Wale Ogunwale854809c2015-12-27 16:18:19 -0800151 * The stack id the activity should be launched into.
152 * @hide
153 */
154 private static final String KEY_LAUNCH_STACK_ID = "android.activity.launchStackId";
155
156 /**
Filip Gruszczynski90186c62015-10-26 14:07:00 -0700157 * Where the docked stack should be positioned.
158 * @hide
159 */
160 private static final String KEY_DOCK_CREATE_MODE = "android:activity.dockCreateMode";
161
162 /**
George Mount0a778ed2013-12-13 13:35:36 -0800163 * For Activity transitions, the calling Activity's TransitionListener used to
164 * notify the called Activity when the shared element and the exit transitions
165 * complete.
166 */
167 private static final String KEY_TRANSITION_COMPLETE_LISTENER
Dianne Hackborna750a632015-06-16 17:18:23 -0700168 = "android:activity.transitionCompleteListener";
George Mount0a778ed2013-12-13 13:35:36 -0800169
Dianne Hackborna750a632015-06-16 17:18:23 -0700170 private static final String KEY_TRANSITION_IS_RETURNING
171 = "android:activity.transitionIsReturning";
172 private static final String KEY_TRANSITION_SHARED_ELEMENTS
173 = "android:activity.sharedElementNames";
174 private static final String KEY_RESULT_DATA = "android:activity.resultData";
175 private static final String KEY_RESULT_CODE = "android:activity.resultCode";
176 private static final String KEY_EXIT_COORDINATOR_INDEX
177 = "android:activity.exitCoordinatorIndex";
George Mount62ab9b72014-05-02 13:51:17 -0700178
Dianne Hackborna750a632015-06-16 17:18:23 -0700179 private static final String KEY_USAGE_TIME_REPORT = "android:activity.usageTimeReport";
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700180
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700181 /** @hide */
182 public static final int ANIM_NONE = 0;
183 /** @hide */
184 public static final int ANIM_CUSTOM = 1;
185 /** @hide */
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700186 public static final int ANIM_SCALE_UP = 2;
187 /** @hide */
Michael Jurka832cb222012-04-13 09:32:47 -0700188 public static final int ANIM_THUMBNAIL_SCALE_UP = 3;
Michael Jurka21385cd2012-05-03 10:57:31 -0700189 /** @hide */
Michael Jurka832cb222012-04-13 09:32:47 -0700190 public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4;
Adam Powell18e905f2013-10-24 14:27:48 -0700191 /** @hide */
192 public static final int ANIM_SCENE_TRANSITION = 5;
George Mount0b6f3e12014-06-20 07:35:23 -0700193 /** @hide */
194 public static final int ANIM_DEFAULT = 6;
Craig Mautnerbb742462014-07-07 15:28:55 -0700195 /** @hide */
196 public static final int ANIM_LAUNCH_TASK_BEHIND = 7;
Winson Chunga4ccb862014-08-22 15:26:27 -0700197 /** @hide */
198 public static final int ANIM_THUMBNAIL_ASPECT_SCALE_UP = 8;
199 /** @hide */
200 public static final int ANIM_THUMBNAIL_ASPECT_SCALE_DOWN = 9;
Winson Chung044d5292014-11-06 11:05:19 -0800201 /** @hide */
202 public static final int ANIM_CUSTOM_IN_PLACE = 10;
Chet Haase10e23ab2015-02-11 15:08:38 -0800203 /** @hide */
204 public static final int ANIM_CLIP_REVEAL = 11;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700205
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700206 private String mPackageName;
Wale Ogunwale7a8fa602015-11-18 15:56:57 -0800207 private Rect mLaunchBounds;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700208 private int mAnimationType = ANIM_NONE;
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700209 private int mCustomEnterResId;
210 private int mCustomExitResId;
Winson Chung044d5292014-11-06 11:05:19 -0800211 private int mCustomInPlaceResId;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700212 private Bitmap mThumbnail;
213 private int mStartX;
214 private int mStartY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200215 private int mWidth;
216 private int mHeight;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700217 private IRemoteCallback mAnimationStartedListener;
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700218 private IRemoteCallback mAnimationFinishedListener;
George Mount62ab9b72014-05-02 13:51:17 -0700219 private ResultReceiver mTransitionReceiver;
220 private boolean mIsReturning;
221 private ArrayList<String> mSharedElementNames;
George Mount62ab9b72014-05-02 13:51:17 -0700222 private Intent mResultData;
223 private int mResultCode;
George Mount1fecfb22014-06-18 14:55:55 -0700224 private int mExitCoordinatorIndex;
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700225 private PendingIntent mUsageTimeReport;
Wale Ogunwale854809c2015-12-27 16:18:19 -0800226 private int mLaunchStackId = INVALID_STACK_ID;
Filip Gruszczynski90186c62015-10-26 14:07:00 -0700227 private int mDockCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700228 private AppTransitionAnimationSpec mAnimSpecs[];
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700229
230 /**
231 * Create an ActivityOptions specifying a custom animation to run when
232 * the activity is displayed.
233 *
234 * @param context Who is defining this. This is the application that the
235 * animation resources will be loaded from.
236 * @param enterResId A resource ID of the animation resource to use for
237 * the incoming activity. Use 0 for no animation.
238 * @param exitResId A resource ID of the animation resource to use for
239 * the outgoing activity. Use 0 for no animation.
240 * @return Returns a new ActivityOptions object that you can use to
241 * supply these options as the options Bundle when starting an activity.
242 */
243 public static ActivityOptions makeCustomAnimation(Context context,
244 int enterResId, int exitResId) {
Dianne Hackborn84375872012-06-01 19:03:50 -0700245 return makeCustomAnimation(context, enterResId, exitResId, null, null);
246 }
247
248 /**
249 * Create an ActivityOptions specifying a custom animation to run when
250 * the activity is displayed.
251 *
252 * @param context Who is defining this. This is the application that the
253 * animation resources will be loaded from.
254 * @param enterResId A resource ID of the animation resource to use for
255 * the incoming activity. Use 0 for no animation.
256 * @param exitResId A resource ID of the animation resource to use for
257 * the outgoing activity. Use 0 for no animation.
258 * @param handler If <var>listener</var> is non-null this must be a valid
259 * Handler on which to dispatch the callback; otherwise it should be null.
260 * @param listener Optional OnAnimationStartedListener to find out when the
261 * requested animation has started running. If for some reason the animation
262 * is not executed, the callback will happen immediately.
263 * @return Returns a new ActivityOptions object that you can use to
264 * supply these options as the options Bundle when starting an activity.
265 * @hide
266 */
267 public static ActivityOptions makeCustomAnimation(Context context,
268 int enterResId, int exitResId, Handler handler, OnAnimationStartedListener listener) {
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700269 ActivityOptions opts = new ActivityOptions();
270 opts.mPackageName = context.getPackageName();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700271 opts.mAnimationType = ANIM_CUSTOM;
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700272 opts.mCustomEnterResId = enterResId;
273 opts.mCustomExitResId = exitResId;
Adam Powell18e905f2013-10-24 14:27:48 -0700274 opts.setOnAnimationStartedListener(handler, listener);
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700275 return opts;
276 }
277
Winson Chung044d5292014-11-06 11:05:19 -0800278 /**
279 * Creates an ActivityOptions specifying a custom animation to run in place on an existing
280 * activity.
281 *
282 * @param context Who is defining this. This is the application that the
283 * animation resources will be loaded from.
284 * @param animId A resource ID of the animation resource to use for
285 * the incoming activity.
286 * @return Returns a new ActivityOptions object that you can use to
287 * supply these options as the options Bundle when running an in-place animation.
288 * @hide
289 */
290 public static ActivityOptions makeCustomInPlaceAnimation(Context context, int animId) {
291 if (animId == 0) {
292 throw new RuntimeException("You must specify a valid animation.");
293 }
294
295 ActivityOptions opts = new ActivityOptions();
296 opts.mPackageName = context.getPackageName();
297 opts.mAnimationType = ANIM_CUSTOM_IN_PLACE;
298 opts.mCustomInPlaceResId = animId;
299 return opts;
300 }
301
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700302 private void setOnAnimationStartedListener(final Handler handler,
303 final OnAnimationStartedListener listener) {
Dianne Hackborn84375872012-06-01 19:03:50 -0700304 if (listener != null) {
Dianne Hackborn84375872012-06-01 19:03:50 -0700305 mAnimationStartedListener = new IRemoteCallback.Stub() {
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700306 @Override
307 public void sendResult(Bundle data) throws RemoteException {
308 handler.post(new Runnable() {
Dianne Hackborn84375872012-06-01 19:03:50 -0700309 @Override public void run() {
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700310 listener.onAnimationStarted();
Dianne Hackborn84375872012-06-01 19:03:50 -0700311 }
312 });
313 }
314 };
315 }
316 }
317
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700318 /**
319 * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation}
320 * to find out when the given animation has started running.
Dianne Hackborn9944ecd2012-04-10 15:54:19 -0700321 * @hide
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700322 */
323 public interface OnAnimationStartedListener {
324 void onAnimationStarted();
325 }
326
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700327 private void setOnAnimationFinishedListener(final Handler handler,
328 final OnAnimationFinishedListener listener) {
329 if (listener != null) {
330 mAnimationFinishedListener = new IRemoteCallback.Stub() {
331 @Override
332 public void sendResult(Bundle data) throws RemoteException {
333 handler.post(new Runnable() {
334 @Override
335 public void run() {
336 listener.onAnimationFinished();
337 }
338 });
339 }
340 };
341 }
342 }
343
344 /**
345 * Callback for use with {@link ActivityOptions#makeThumbnailAspectScaleDownAnimation}
346 * to find out when the given animation has drawn its last frame.
347 * @hide
348 */
349 public interface OnAnimationFinishedListener {
350 void onAnimationFinished();
351 }
352
Adam Powell18e905f2013-10-24 14:27:48 -0700353 /**
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700354 * Create an ActivityOptions specifying an animation where the new
355 * activity is scaled from a small originating area of the screen to
356 * its final full representation.
357 *
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700358 * <p>If the Intent this is being used with has not set its
359 * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds},
360 * those bounds will be filled in for you based on the initial
361 * bounds passed in here.
362 *
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700363 * @param source The View that the new activity is animating from. This
364 * defines the coordinate space for <var>startX</var> and <var>startY</var>.
365 * @param startX The x starting location of the new activity, relative to <var>source</var>.
366 * @param startY The y starting location of the activity, relative to <var>source</var>.
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200367 * @param width The initial width of the new activity.
368 * @param height The initial height of the new activity.
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700369 * @return Returns a new ActivityOptions object that you can use to
370 * supply these options as the options Bundle when starting an activity.
371 */
372 public static ActivityOptions makeScaleUpAnimation(View source,
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200373 int startX, int startY, int width, int height) {
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700374 ActivityOptions opts = new ActivityOptions();
375 opts.mPackageName = source.getContext().getPackageName();
376 opts.mAnimationType = ANIM_SCALE_UP;
377 int[] pts = new int[2];
378 source.getLocationOnScreen(pts);
379 opts.mStartX = pts[0] + startX;
380 opts.mStartY = pts[1] + startY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200381 opts.mWidth = width;
382 opts.mHeight = height;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700383 return opts;
384 }
385
386 /**
Chet Haase10e23ab2015-02-11 15:08:38 -0800387 * Create an ActivityOptions specifying an animation where the new
388 * activity is revealed from a small originating area of the screen to
389 * its final full representation.
390 *
391 * @param source The View that the new activity is animating from. This
392 * defines the coordinate space for <var>startX</var> and <var>startY</var>.
393 * @param startX The x starting location of the new activity, relative to <var>source</var>.
394 * @param startY The y starting location of the activity, relative to <var>source</var>.
395 * @param width The initial width of the new activity.
396 * @param height The initial height of the new activity.
397 * @return Returns a new ActivityOptions object that you can use to
398 * supply these options as the options Bundle when starting an activity.
399 */
400 public static ActivityOptions makeClipRevealAnimation(View source,
401 int startX, int startY, int width, int height) {
402 ActivityOptions opts = new ActivityOptions();
403 opts.mAnimationType = ANIM_CLIP_REVEAL;
404 int[] pts = new int[2];
405 source.getLocationOnScreen(pts);
406 opts.mStartX = pts[0] + startX;
407 opts.mStartY = pts[1] + startY;
408 opts.mWidth = width;
409 opts.mHeight = height;
410 return opts;
411 }
412
413 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700414 * Create an ActivityOptions specifying an animation where a thumbnail
415 * is scaled from a given position to the new activity window that is
416 * being started.
417 *
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700418 * <p>If the Intent this is being used with has not set its
419 * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds},
420 * those bounds will be filled in for you based on the initial
421 * thumbnail location and size provided here.
422 *
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700423 * @param source The View that this thumbnail is animating from. This
424 * defines the coordinate space for <var>startX</var> and <var>startY</var>.
425 * @param thumbnail The bitmap that will be shown as the initial thumbnail
426 * of the animation.
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700427 * @param startX The x starting location of the bitmap, relative to <var>source</var>.
428 * @param startY The y starting location of the bitmap, relative to <var>source</var>.
Dianne Hackborn9944ecd2012-04-10 15:54:19 -0700429 * @return Returns a new ActivityOptions object that you can use to
430 * supply these options as the options Bundle when starting an activity.
431 */
432 public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
433 Bitmap thumbnail, int startX, int startY) {
434 return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, null);
435 }
436
437 /**
438 * Create an ActivityOptions specifying an animation where a thumbnail
439 * is scaled from a given position to the new activity window that is
440 * being started.
441 *
442 * @param source The View that this thumbnail is animating from. This
443 * defines the coordinate space for <var>startX</var> and <var>startY</var>.
444 * @param thumbnail The bitmap that will be shown as the initial thumbnail
445 * of the animation.
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700446 * @param startX The x starting location of the bitmap, relative to <var>source</var>.
447 * @param startY The y starting location of the bitmap, relative to <var>source</var>.
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700448 * @param listener Optional OnAnimationStartedListener to find out when the
449 * requested animation has started running. If for some reason the animation
450 * is not executed, the callback will happen immediately.
451 * @return Returns a new ActivityOptions object that you can use to
452 * supply these options as the options Bundle when starting an activity.
Dianne Hackborn9944ecd2012-04-10 15:54:19 -0700453 * @hide
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700454 */
455 public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
456 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
Michael Jurka832cb222012-04-13 09:32:47 -0700457 return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, true);
Michael Jurka21385cd2012-05-03 10:57:31 -0700458 }
459
460 /**
Michael Jurka832cb222012-04-13 09:32:47 -0700461 * Create an ActivityOptions specifying an animation where an activity window
462 * is scaled from a given position to a thumbnail at a specified location.
Michael Jurka21385cd2012-05-03 10:57:31 -0700463 *
Michael Jurka832cb222012-04-13 09:32:47 -0700464 * @param source The View that this thumbnail is animating to. This
Michael Jurka21385cd2012-05-03 10:57:31 -0700465 * defines the coordinate space for <var>startX</var> and <var>startY</var>.
Michael Jurka832cb222012-04-13 09:32:47 -0700466 * @param thumbnail The bitmap that will be shown as the final thumbnail
Michael Jurka21385cd2012-05-03 10:57:31 -0700467 * of the animation.
Michael Jurka832cb222012-04-13 09:32:47 -0700468 * @param startX The x end location of the bitmap, relative to <var>source</var>.
469 * @param startY The y end location of the bitmap, relative to <var>source</var>.
Michael Jurka21385cd2012-05-03 10:57:31 -0700470 * @param listener Optional OnAnimationStartedListener to find out when the
471 * requested animation has started running. If for some reason the animation
472 * is not executed, the callback will happen immediately.
473 * @return Returns a new ActivityOptions object that you can use to
474 * supply these options as the options Bundle when starting an activity.
475 * @hide
476 */
Michael Jurka832cb222012-04-13 09:32:47 -0700477 public static ActivityOptions makeThumbnailScaleDownAnimation(View source,
Michael Jurka21385cd2012-05-03 10:57:31 -0700478 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
Michael Jurka832cb222012-04-13 09:32:47 -0700479 return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, false);
Michael Jurka21385cd2012-05-03 10:57:31 -0700480 }
481
Michael Jurka832cb222012-04-13 09:32:47 -0700482 private static ActivityOptions makeThumbnailAnimation(View source,
Michael Jurka21385cd2012-05-03 10:57:31 -0700483 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener,
Michael Jurka832cb222012-04-13 09:32:47 -0700484 boolean scaleUp) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700485 ActivityOptions opts = new ActivityOptions();
486 opts.mPackageName = source.getContext().getPackageName();
Michael Jurka832cb222012-04-13 09:32:47 -0700487 opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700488 opts.mThumbnail = thumbnail;
489 int[] pts = new int[2];
490 source.getLocationOnScreen(pts);
491 opts.mStartX = pts[0] + startX;
492 opts.mStartY = pts[1] + startY;
Adam Powell18e905f2013-10-24 14:27:48 -0700493 opts.setOnAnimationStartedListener(source.getHandler(), listener);
494 return opts;
495 }
496
497 /**
Winson Chunga4ccb862014-08-22 15:26:27 -0700498 * Create an ActivityOptions specifying an animation where the new activity
499 * window and a thumbnail is aspect-scaled to a new location.
500 *
501 * @param source The View that this thumbnail is animating from. This
502 * defines the coordinate space for <var>startX</var> and <var>startY</var>.
503 * @param thumbnail The bitmap that will be shown as the initial thumbnail
504 * of the animation.
505 * @param startX The x starting location of the bitmap, relative to <var>source</var>.
506 * @param startY The y starting location of the bitmap, relative to <var>source</var>.
Winson Chunge494c382014-12-17 10:12:54 -0800507 * @param handler If <var>listener</var> is non-null this must be a valid
508 * Handler on which to dispatch the callback; otherwise it should be null.
Winson Chunga4ccb862014-08-22 15:26:27 -0700509 * @param listener Optional OnAnimationStartedListener to find out when the
510 * requested animation has started running. If for some reason the animation
511 * is not executed, the callback will happen immediately.
512 * @return Returns a new ActivityOptions object that you can use to
513 * supply these options as the options Bundle when starting an activity.
514 * @hide
515 */
516 public static ActivityOptions makeThumbnailAspectScaleUpAnimation(View source,
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200517 Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight,
Winson Chunge494c382014-12-17 10:12:54 -0800518 Handler handler, OnAnimationStartedListener listener) {
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200519 return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY,
Winson Chunge494c382014-12-17 10:12:54 -0800520 targetWidth, targetHeight, handler, listener, true);
Winson Chunga4ccb862014-08-22 15:26:27 -0700521 }
522
523 /**
524 * Create an ActivityOptions specifying an animation where the new activity
525 * window and a thumbnail is aspect-scaled to a new location.
526 *
527 * @param source The View that this thumbnail is animating to. This
528 * defines the coordinate space for <var>startX</var> and <var>startY</var>.
529 * @param thumbnail The bitmap that will be shown as the final thumbnail
530 * of the animation.
531 * @param startX The x end location of the bitmap, relative to <var>source</var>.
532 * @param startY The y end location of the bitmap, relative to <var>source</var>.
Winson Chunge494c382014-12-17 10:12:54 -0800533 * @param handler If <var>listener</var> is non-null this must be a valid
534 * Handler on which to dispatch the callback; otherwise it should be null.
Winson Chunga4ccb862014-08-22 15:26:27 -0700535 * @param listener Optional OnAnimationStartedListener to find out when the
536 * requested animation has started running. If for some reason the animation
537 * is not executed, the callback will happen immediately.
538 * @return Returns a new ActivityOptions object that you can use to
539 * supply these options as the options Bundle when starting an activity.
540 * @hide
541 */
542 public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source,
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200543 Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight,
Winson Chunge494c382014-12-17 10:12:54 -0800544 Handler handler, OnAnimationStartedListener listener) {
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200545 return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY,
Winson Chunge494c382014-12-17 10:12:54 -0800546 targetWidth, targetHeight, handler, listener, false);
Winson Chunga4ccb862014-08-22 15:26:27 -0700547 }
548
549 private static ActivityOptions makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail,
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200550 int startX, int startY, int targetWidth, int targetHeight,
Winson Chunge494c382014-12-17 10:12:54 -0800551 Handler handler, OnAnimationStartedListener listener, boolean scaleUp) {
Winson Chunga4ccb862014-08-22 15:26:27 -0700552 ActivityOptions opts = new ActivityOptions();
553 opts.mPackageName = source.getContext().getPackageName();
554 opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_ASPECT_SCALE_UP :
555 ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
556 opts.mThumbnail = thumbnail;
557 int[] pts = new int[2];
558 source.getLocationOnScreen(pts);
559 opts.mStartX = pts[0] + startX;
560 opts.mStartY = pts[1] + startY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200561 opts.mWidth = targetWidth;
562 opts.mHeight = targetHeight;
Winson Chunge494c382014-12-17 10:12:54 -0800563 opts.setOnAnimationStartedListener(handler, listener);
Winson Chunga4ccb862014-08-22 15:26:27 -0700564 return opts;
565 }
566
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700567 /** @hide */
568 public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source,
569 AppTransitionAnimationSpec[] specs, Handler handler,
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700570 OnAnimationStartedListener onAnimationStartedListener,
571 OnAnimationFinishedListener onAnimationFinishedListener) {
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700572 ActivityOptions opts = new ActivityOptions();
573 opts.mPackageName = source.getContext().getPackageName();
574 opts.mAnimationType = ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
575 opts.mAnimSpecs = specs;
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700576 opts.setOnAnimationStartedListener(handler, onAnimationStartedListener);
577 opts.setOnAnimationFinishedListener(handler, onAnimationFinishedListener);
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700578 return opts;
579 }
580
Winson Chunga4ccb862014-08-22 15:26:27 -0700581 /**
George Mounte1803372014-02-26 19:00:52 +0000582 * Create an ActivityOptions to transition between Activities using cross-Activity scene
583 * animations. This method carries the position of one shared element to the started Activity.
George Mount31a21722014-03-24 17:44:36 -0700584 * The position of <code>sharedElement</code> will be used as the epicenter for the
585 * exit Transition. The position of the shared element in the launched Activity will be the
586 * epicenter of its entering Transition.
George Mount0a778ed2013-12-13 13:35:36 -0800587 *
George Mount9826f632014-09-11 08:50:09 -0700588 * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be
George Mount0a778ed2013-12-13 13:35:36 -0800589 * enabled on the calling Activity to cause an exit transition. The same must be in
590 * the called Activity to get an entering transition.</p>
George Mount62ab9b72014-05-02 13:51:17 -0700591 * @param activity The Activity whose window contains the shared elements.
George Mount0b6f3e12014-06-20 07:35:23 -0700592 * @param sharedElement The View to transition to the started Activity.
593 * @param sharedElementName The shared element name as used in the target Activity. This
594 * must not be null.
George Mounte1803372014-02-26 19:00:52 +0000595 * @return Returns a new ActivityOptions object that you can use to
596 * supply these options as the options Bundle when starting an activity.
George Mount31a21722014-03-24 17:44:36 -0700597 * @see android.transition.Transition#setEpicenterCallback(
598 * android.transition.Transition.EpicenterCallback)
Adam Powell18e905f2013-10-24 14:27:48 -0700599 */
George Mount62ab9b72014-05-02 13:51:17 -0700600 public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
George Mount31a21722014-03-24 17:44:36 -0700601 View sharedElement, String sharedElementName) {
George Mount62ab9b72014-05-02 13:51:17 -0700602 return makeSceneTransitionAnimation(activity, Pair.create(sharedElement, sharedElementName));
George Mounte1803372014-02-26 19:00:52 +0000603 }
604
605 /**
606 * Create an ActivityOptions to transition between Activities using cross-Activity scene
607 * animations. This method carries the position of multiple shared elements to the started
George Mount62ab9b72014-05-02 13:51:17 -0700608 * Activity. The position of the first element in sharedElements
George Mount31a21722014-03-24 17:44:36 -0700609 * will be used as the epicenter for the exit Transition. The position of the associated
610 * shared element in the launched Activity will be the epicenter of its entering Transition.
George Mounte1803372014-02-26 19:00:52 +0000611 *
George Mount9826f632014-09-11 08:50:09 -0700612 * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be
George Mounte1803372014-02-26 19:00:52 +0000613 * enabled on the calling Activity to cause an exit transition. The same must be in
614 * the called Activity to get an entering transition.</p>
George Mount62ab9b72014-05-02 13:51:17 -0700615 * @param activity The Activity whose window contains the shared elements.
616 * @param sharedElements The names of the shared elements to transfer to the called
617 * Activity and their associated Views. The Views must each have
618 * a unique shared element name.
George Mounte1803372014-02-26 19:00:52 +0000619 * @return Returns a new ActivityOptions object that you can use to
620 * supply these options as the options Bundle when starting an activity.
George Mount31a21722014-03-24 17:44:36 -0700621 * @see android.transition.Transition#setEpicenterCallback(
622 * android.transition.Transition.EpicenterCallback)
George Mounte1803372014-02-26 19:00:52 +0000623 */
George Mount62ab9b72014-05-02 13:51:17 -0700624 public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
625 Pair<View, String>... sharedElements) {
Adam Powell18e905f2013-10-24 14:27:48 -0700626 ActivityOptions opts = new ActivityOptions();
George Mount9826f632014-09-11 08:50:09 -0700627 if (!activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) {
George Mount0b6f3e12014-06-20 07:35:23 -0700628 opts.mAnimationType = ANIM_DEFAULT;
629 return opts;
630 }
Adam Powell18e905f2013-10-24 14:27:48 -0700631 opts.mAnimationType = ANIM_SCENE_TRANSITION;
George Mount62ab9b72014-05-02 13:51:17 -0700632
633 ArrayList<String> names = new ArrayList<String>();
George Mount1fecfb22014-06-18 14:55:55 -0700634 ArrayList<View> views = new ArrayList<View>();
George Mount62ab9b72014-05-02 13:51:17 -0700635
636 if (sharedElements != null) {
637 for (int i = 0; i < sharedElements.length; i++) {
638 Pair<View, String> sharedElement = sharedElements[i];
George Mountd5f9d732014-06-05 15:43:06 -0700639 String sharedElementName = sharedElement.second;
640 if (sharedElementName == null) {
641 throw new IllegalArgumentException("Shared element name must not be null");
642 }
George Mountd5f9d732014-06-05 15:43:06 -0700643 names.add(sharedElementName);
George Mount1fecfb22014-06-18 14:55:55 -0700644 View view = sharedElement.first;
645 if (view == null) {
646 throw new IllegalArgumentException("Shared element must not be null");
647 }
648 views.add(sharedElement.first);
George Mount62ab9b72014-05-02 13:51:17 -0700649 }
650 }
651
652 ExitTransitionCoordinator exit = new ExitTransitionCoordinator(activity, names, names,
George Mount1fecfb22014-06-18 14:55:55 -0700653 views, false);
George Mount62ab9b72014-05-02 13:51:17 -0700654 opts.mTransitionReceiver = exit;
655 opts.mSharedElementNames = names;
George Mount62ab9b72014-05-02 13:51:17 -0700656 opts.mIsReturning = false;
George Mount1fecfb22014-06-18 14:55:55 -0700657 opts.mExitCoordinatorIndex =
658 activity.mActivityTransitionState.addExitTransitionCoordinator(exit);
George Mount62ab9b72014-05-02 13:51:17 -0700659 return opts;
660 }
661
662 /** @hide */
663 public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
664 ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames,
665 int resultCode, Intent resultData) {
666 ActivityOptions opts = new ActivityOptions();
667 opts.mAnimationType = ANIM_SCENE_TRANSITION;
668 opts.mSharedElementNames = sharedElementNames;
669 opts.mTransitionReceiver = exitCoordinator;
670 opts.mIsReturning = true;
671 opts.mResultCode = resultCode;
672 opts.mResultData = resultData;
George Mount1fecfb22014-06-18 14:55:55 -0700673 opts.mExitCoordinatorIndex =
674 activity.mActivityTransitionState.addExitTransitionCoordinator(exitCoordinator);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700675 return opts;
676 }
677
Craig Mautnerbb742462014-07-07 15:28:55 -0700678 /**
679 * If set along with Intent.FLAG_ACTIVITY_NEW_DOCUMENT then the task being launched will not be
680 * presented to the user but will instead be only available through the recents task list.
681 * In addition, the new task wil be affiliated with the launching activity's task.
682 * Affiliated tasks are grouped together in the recents task list.
683 *
684 * <p>This behavior is not supported for activities with {@link
685 * android.R.styleable#AndroidManifestActivity_launchMode launchMode} values of
686 * <code>singleInstance</code> or <code>singleTask</code>.
687 */
Craig Mautner3b2cd1d2014-08-25 14:25:54 -0700688 public static ActivityOptions makeTaskLaunchBehind() {
Craig Mautnerbb742462014-07-07 15:28:55 -0700689 final ActivityOptions opts = new ActivityOptions();
690 opts.mAnimationType = ANIM_LAUNCH_TASK_BEHIND;
691 return opts;
692 }
693
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700694 /**
695 * Create a basic ActivityOptions that has no special animation associated with it.
696 * Other options can still be set.
697 */
698 public static ActivityOptions makeBasic() {
699 final ActivityOptions opts = new ActivityOptions();
700 return opts;
701 }
702
Craig Mautnerbb742462014-07-07 15:28:55 -0700703 /** @hide */
704 public boolean getLaunchTaskBehind() {
705 return mAnimationType == ANIM_LAUNCH_TASK_BEHIND;
706 }
707
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700708 private ActivityOptions() {
709 }
710
711 /** @hide */
712 public ActivityOptions(Bundle opts) {
713 mPackageName = opts.getString(KEY_PACKAGE_NAME);
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700714 try {
715 mUsageTimeReport = opts.getParcelable(KEY_USAGE_TIME_REPORT);
716 } catch (RuntimeException e) {
717 Slog.w(TAG, e);
718 }
Wale Ogunwale5122df02016-01-29 22:33:38 -0800719 mLaunchBounds = opts.getParcelable(KEY_LAUNCH_BOUNDS);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700720 mAnimationType = opts.getInt(KEY_ANIM_TYPE);
Adam Powell18e905f2013-10-24 14:27:48 -0700721 switch (mAnimationType) {
722 case ANIM_CUSTOM:
723 mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
724 mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
725 mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
726 opts.getBinder(KEY_ANIM_START_LISTENER));
727 break;
728
Winson Chung044d5292014-11-06 11:05:19 -0800729 case ANIM_CUSTOM_IN_PLACE:
730 mCustomInPlaceResId = opts.getInt(KEY_ANIM_IN_PLACE_RES_ID, 0);
731 break;
732
Adam Powell18e905f2013-10-24 14:27:48 -0700733 case ANIM_SCALE_UP:
Chet Haase10e23ab2015-02-11 15:08:38 -0800734 case ANIM_CLIP_REVEAL:
Adam Powell18e905f2013-10-24 14:27:48 -0700735 mStartX = opts.getInt(KEY_ANIM_START_X, 0);
736 mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200737 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
738 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
Adam Powell18e905f2013-10-24 14:27:48 -0700739 break;
740
741 case ANIM_THUMBNAIL_SCALE_UP:
742 case ANIM_THUMBNAIL_SCALE_DOWN:
Winson Chunga4ccb862014-08-22 15:26:27 -0700743 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
744 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
745 mThumbnail = (Bitmap) opts.getParcelable(KEY_ANIM_THUMBNAIL);
Adam Powell18e905f2013-10-24 14:27:48 -0700746 mStartX = opts.getInt(KEY_ANIM_START_X, 0);
747 mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200748 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
749 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
Adam Powell18e905f2013-10-24 14:27:48 -0700750 mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
751 opts.getBinder(KEY_ANIM_START_LISTENER));
752 break;
753
754 case ANIM_SCENE_TRANSITION:
George Mount62ab9b72014-05-02 13:51:17 -0700755 mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER);
756 mIsReturning = opts.getBoolean(KEY_TRANSITION_IS_RETURNING, false);
757 mSharedElementNames = opts.getStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS);
George Mount62ab9b72014-05-02 13:51:17 -0700758 mResultData = opts.getParcelable(KEY_RESULT_DATA);
759 mResultCode = opts.getInt(KEY_RESULT_CODE);
George Mount1fecfb22014-06-18 14:55:55 -0700760 mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX);
Adam Powell18e905f2013-10-24 14:27:48 -0700761 break;
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700762 }
Wale Ogunwale854809c2015-12-27 16:18:19 -0800763 mLaunchStackId = opts.getInt(KEY_LAUNCH_STACK_ID, INVALID_STACK_ID);
Filip Gruszczynski90186c62015-10-26 14:07:00 -0700764 mDockCreateMode = opts.getInt(KEY_DOCK_CREATE_MODE, DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT);
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700765 if (opts.containsKey(KEY_ANIM_SPECS)) {
766 Parcelable[] specs = opts.getParcelableArray(KEY_ANIM_SPECS);
767 mAnimSpecs = new AppTransitionAnimationSpec[specs.length];
768 for (int i = specs.length - 1; i >= 0; i--) {
769 mAnimSpecs[i] = (AppTransitionAnimationSpec) specs[i];
770 }
771 }
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700772 if (opts.containsKey(KEY_ANIMATION_FINISHED_LISTENER)) {
773 mAnimationFinishedListener = IRemoteCallback.Stub.asInterface(
774 opts.getBinder(KEY_ANIMATION_FINISHED_LISTENER));
775 }
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700776 }
777
Wale Ogunwale7a8fa602015-11-18 15:56:57 -0800778 /**
Wale Ogunwale5122df02016-01-29 22:33:38 -0800779 * Sets the bounds (window size) that the activity should be launched in.
780 * Set to null explicitly for fullscreen.
781 * <p>
782 * <strong>NOTE:<strong/> This value is ignored on devices that don't have
783 * {@link android.content.pm.PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT} or
784 * {@link android.content.pm.PackageManager#FEATURE_PICTURE_IN_PICTURE} enabled.
785 * @param launchBounds Launch bounds to use for the activity or null for fullscreen.
Wale Ogunwale7a8fa602015-11-18 15:56:57 -0800786 */
Wale Ogunwale5122df02016-01-29 22:33:38 -0800787 public ActivityOptions setLaunchBounds(@Nullable Rect launchBounds) {
788 mLaunchBounds = launchBounds != null ? new Rect(launchBounds) : null;
Chong Zhang0fa656b2015-08-31 15:17:21 -0700789 return this;
790 }
791
792 /** @hide */
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700793 public String getPackageName() {
794 return mPackageName;
795 }
796
Wale Ogunwale5122df02016-01-29 22:33:38 -0800797 /**
798 * Returns the bounds that should be used to launch the activity.
799 * @see #setLaunchBounds(Rect)
800 * @return Bounds used to launch the activity.
801 */
802 @Nullable
803 public Rect getLaunchBounds() {
Wale Ogunwale7a8fa602015-11-18 15:56:57 -0800804 return mLaunchBounds;
Chong Zhang0fa656b2015-08-31 15:17:21 -0700805 }
806
807 /** @hide */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700808 public int getAnimationType() {
809 return mAnimationType;
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700810 }
811
812 /** @hide */
813 public int getCustomEnterResId() {
814 return mCustomEnterResId;
815 }
816
817 /** @hide */
818 public int getCustomExitResId() {
819 return mCustomExitResId;
820 }
821
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700822 /** @hide */
Winson Chung044d5292014-11-06 11:05:19 -0800823 public int getCustomInPlaceResId() {
824 return mCustomInPlaceResId;
825 }
826
827 /** @hide */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700828 public Bitmap getThumbnail() {
829 return mThumbnail;
830 }
831
832 /** @hide */
833 public int getStartX() {
834 return mStartX;
835 }
836
837 /** @hide */
838 public int getStartY() {
839 return mStartY;
840 }
841
842 /** @hide */
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200843 public int getWidth() {
844 return mWidth;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700845 }
846
847 /** @hide */
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200848 public int getHeight() {
849 return mHeight;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700850 }
851
852 /** @hide */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700853 public IRemoteCallback getOnAnimationStartListener() {
854 return mAnimationStartedListener;
855 }
856
857 /** @hide */
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700858 public IRemoteCallback getAnimationFinishedListener() {
859 return mAnimationFinishedListener;
860 }
861
862 /** @hide */
George Mount1fecfb22014-06-18 14:55:55 -0700863 public int getExitCoordinatorKey() { return mExitCoordinatorIndex; }
George Mounte1803372014-02-26 19:00:52 +0000864
865 /** @hide */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700866 public void abort() {
867 if (mAnimationStartedListener != null) {
868 try {
869 mAnimationStartedListener.sendResult(null);
870 } catch (RemoteException e) {
871 }
872 }
873 }
874
875 /** @hide */
George Mount62ab9b72014-05-02 13:51:17 -0700876 public boolean isReturning() {
877 return mIsReturning;
878 }
879
880 /** @hide */
881 public ArrayList<String> getSharedElementNames() {
882 return mSharedElementNames;
883 }
884
885 /** @hide */
George Mount62ab9b72014-05-02 13:51:17 -0700886 public ResultReceiver getResultReceiver() { return mTransitionReceiver; }
887
888 /** @hide */
889 public int getResultCode() { return mResultCode; }
890
891 /** @hide */
892 public Intent getResultData() { return mResultData; }
893
894 /** @hide */
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700895 public PendingIntent getUsageTimeReport() {
896 return mUsageTimeReport;
897 }
898
899 /** @hide */
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700900 public AppTransitionAnimationSpec[] getAnimSpecs() { return mAnimSpecs; }
901
902 /** @hide */
Chong Zhang280d3322015-11-03 17:27:26 -0800903 public static ActivityOptions fromBundle(Bundle bOptions) {
904 return bOptions != null ? new ActivityOptions(bOptions) : null;
905 }
906
907 /** @hide */
908 public static void abort(ActivityOptions options) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700909 if (options != null) {
Chong Zhang280d3322015-11-03 17:27:26 -0800910 options.abort();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700911 }
912 }
913
Filip Gruszczynski90186c62015-10-26 14:07:00 -0700914 /** @hide */
Wale Ogunwale854809c2015-12-27 16:18:19 -0800915 public int getLaunchStackId() {
916 return mLaunchStackId;
917 }
918
919 /** @hide */
920 public void setLaunchStackId(int launchStackId) {
921 mLaunchStackId = launchStackId;
922 }
923
924 /** @hide */
925 public int getDockCreateMode() {
926 return mDockCreateMode;
927 }
Filip Gruszczynski90186c62015-10-26 14:07:00 -0700928
929 /** @hide */
930 public void setDockCreateMode(int dockCreateMode) {
931 mDockCreateMode = dockCreateMode;
932 }
933
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700934 /**
Dianne Hackbornddc52a82012-05-03 19:40:12 -0700935 * Update the current values in this ActivityOptions from those supplied
936 * in <var>otherOptions</var>. Any values
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700937 * defined in <var>otherOptions</var> replace those in the base options.
938 */
Dianne Hackbornddc52a82012-05-03 19:40:12 -0700939 public void update(ActivityOptions otherOptions) {
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700940 if (otherOptions.mPackageName != null) {
941 mPackageName = otherOptions.mPackageName;
942 }
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700943 mUsageTimeReport = otherOptions.mUsageTimeReport;
George Mount62ab9b72014-05-02 13:51:17 -0700944 mTransitionReceiver = null;
945 mSharedElementNames = null;
George Mount62ab9b72014-05-02 13:51:17 -0700946 mIsReturning = false;
947 mResultData = null;
948 mResultCode = 0;
George Mount1fecfb22014-06-18 14:55:55 -0700949 mExitCoordinatorIndex = 0;
George Mount00dde0b2014-07-01 15:27:07 -0700950 mAnimationType = otherOptions.mAnimationType;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700951 switch (otherOptions.mAnimationType) {
952 case ANIM_CUSTOM:
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700953 mCustomEnterResId = otherOptions.mCustomEnterResId;
954 mCustomExitResId = otherOptions.mCustomExitResId;
955 mThumbnail = null;
Adam Powell18e905f2013-10-24 14:27:48 -0700956 if (mAnimationStartedListener != null) {
Dianne Hackborn84375872012-06-01 19:03:50 -0700957 try {
Adam Powell18e905f2013-10-24 14:27:48 -0700958 mAnimationStartedListener.sendResult(null);
Dianne Hackborn84375872012-06-01 19:03:50 -0700959 } catch (RemoteException e) {
960 }
961 }
962 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700963 break;
Winson Chung044d5292014-11-06 11:05:19 -0800964 case ANIM_CUSTOM_IN_PLACE:
965 mCustomInPlaceResId = otherOptions.mCustomInPlaceResId;
966 break;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700967 case ANIM_SCALE_UP:
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700968 mStartX = otherOptions.mStartX;
969 mStartY = otherOptions.mStartY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200970 mWidth = otherOptions.mWidth;
971 mHeight = otherOptions.mHeight;
Adam Powell18e905f2013-10-24 14:27:48 -0700972 if (mAnimationStartedListener != null) {
Dianne Hackborn84375872012-06-01 19:03:50 -0700973 try {
Adam Powell18e905f2013-10-24 14:27:48 -0700974 mAnimationStartedListener.sendResult(null);
Dianne Hackborn84375872012-06-01 19:03:50 -0700975 } catch (RemoteException e) {
976 }
977 }
978 mAnimationStartedListener = null;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700979 break;
Michael Jurka832cb222012-04-13 09:32:47 -0700980 case ANIM_THUMBNAIL_SCALE_UP:
981 case ANIM_THUMBNAIL_SCALE_DOWN:
Winson Chunga4ccb862014-08-22 15:26:27 -0700982 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
983 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700984 mThumbnail = otherOptions.mThumbnail;
985 mStartX = otherOptions.mStartX;
986 mStartY = otherOptions.mStartY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200987 mWidth = otherOptions.mWidth;
988 mHeight = otherOptions.mHeight;
Adam Powell18e905f2013-10-24 14:27:48 -0700989 if (mAnimationStartedListener != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700990 try {
Adam Powell18e905f2013-10-24 14:27:48 -0700991 mAnimationStartedListener.sendResult(null);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700992 } catch (RemoteException e) {
993 }
994 }
995 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
Adam Powell18e905f2013-10-24 14:27:48 -0700996 break;
997 case ANIM_SCENE_TRANSITION:
George Mount62ab9b72014-05-02 13:51:17 -0700998 mTransitionReceiver = otherOptions.mTransitionReceiver;
999 mSharedElementNames = otherOptions.mSharedElementNames;
George Mount62ab9b72014-05-02 13:51:17 -07001000 mIsReturning = otherOptions.mIsReturning;
Adam Powellcfbe9be2013-11-06 14:58:58 -08001001 mThumbnail = null;
Adam Powell18e905f2013-10-24 14:27:48 -07001002 mAnimationStartedListener = null;
George Mount62ab9b72014-05-02 13:51:17 -07001003 mResultData = otherOptions.mResultData;
1004 mResultCode = otherOptions.mResultCode;
George Mount1fecfb22014-06-18 14:55:55 -07001005 mExitCoordinatorIndex = otherOptions.mExitCoordinatorIndex;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001006 break;
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001007 }
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -07001008 mAnimSpecs = otherOptions.mAnimSpecs;
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -07001009 mAnimationFinishedListener = otherOptions.mAnimationFinishedListener;
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001010 }
1011
1012 /**
1013 * Returns the created options as a Bundle, which can be passed to
1014 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
1015 * Context.startActivity(Intent, Bundle)} and related methods.
1016 * Note that the returned Bundle is still owned by the ActivityOptions
1017 * object; you must not modify it, but can supply it to the startActivity
1018 * methods that take an options Bundle.
1019 */
1020 public Bundle toBundle() {
George Mount0b6f3e12014-06-20 07:35:23 -07001021 if (mAnimationType == ANIM_DEFAULT) {
1022 return null;
1023 }
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001024 Bundle b = new Bundle();
1025 if (mPackageName != null) {
1026 b.putString(KEY_PACKAGE_NAME, mPackageName);
1027 }
Wale Ogunwale5122df02016-01-29 22:33:38 -08001028 if (mLaunchBounds != null) {
Wale Ogunwale7a8fa602015-11-18 15:56:57 -08001029 b.putParcelable(KEY_LAUNCH_BOUNDS, mLaunchBounds);
Chong Zhang0fa656b2015-08-31 15:17:21 -07001030 }
Craig Mautnerbb742462014-07-07 15:28:55 -07001031 b.putInt(KEY_ANIM_TYPE, mAnimationType);
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07001032 if (mUsageTimeReport != null) {
1033 b.putParcelable(KEY_USAGE_TIME_REPORT, mUsageTimeReport);
1034 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001035 switch (mAnimationType) {
1036 case ANIM_CUSTOM:
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001037 b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
1038 b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
Adam Powellcfbe9be2013-11-06 14:58:58 -08001039 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
Dianne Hackborn84375872012-06-01 19:03:50 -07001040 != null ? mAnimationStartedListener.asBinder() : null);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001041 break;
Winson Chung044d5292014-11-06 11:05:19 -08001042 case ANIM_CUSTOM_IN_PLACE:
1043 b.putInt(KEY_ANIM_IN_PLACE_RES_ID, mCustomInPlaceResId);
1044 break;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001045 case ANIM_SCALE_UP:
Chet Haase10e23ab2015-02-11 15:08:38 -08001046 case ANIM_CLIP_REVEAL:
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001047 b.putInt(KEY_ANIM_START_X, mStartX);
1048 b.putInt(KEY_ANIM_START_Y, mStartY);
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001049 b.putInt(KEY_ANIM_WIDTH, mWidth);
1050 b.putInt(KEY_ANIM_HEIGHT, mHeight);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001051 break;
Michael Jurka832cb222012-04-13 09:32:47 -07001052 case ANIM_THUMBNAIL_SCALE_UP:
1053 case ANIM_THUMBNAIL_SCALE_DOWN:
Winson Chunga4ccb862014-08-22 15:26:27 -07001054 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
1055 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001056 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
1057 b.putInt(KEY_ANIM_START_X, mStartX);
1058 b.putInt(KEY_ANIM_START_Y, mStartY);
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001059 b.putInt(KEY_ANIM_WIDTH, mWidth);
1060 b.putInt(KEY_ANIM_HEIGHT, mHeight);
Adam Powellcfbe9be2013-11-06 14:58:58 -08001061 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001062 != null ? mAnimationStartedListener.asBinder() : null);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001063 break;
Adam Powellcfbe9be2013-11-06 14:58:58 -08001064 case ANIM_SCENE_TRANSITION:
George Mount62ab9b72014-05-02 13:51:17 -07001065 if (mTransitionReceiver != null) {
1066 b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionReceiver);
George Mount0a778ed2013-12-13 13:35:36 -08001067 }
George Mount62ab9b72014-05-02 13:51:17 -07001068 b.putBoolean(KEY_TRANSITION_IS_RETURNING, mIsReturning);
1069 b.putStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS, mSharedElementNames);
George Mount62ab9b72014-05-02 13:51:17 -07001070 b.putParcelable(KEY_RESULT_DATA, mResultData);
1071 b.putInt(KEY_RESULT_CODE, mResultCode);
George Mount1fecfb22014-06-18 14:55:55 -07001072 b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
Adam Powellcfbe9be2013-11-06 14:58:58 -08001073 break;
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001074 }
Wale Ogunwale854809c2015-12-27 16:18:19 -08001075 b.putInt(KEY_LAUNCH_STACK_ID, mLaunchStackId);
Filip Gruszczynski90186c62015-10-26 14:07:00 -07001076 b.putInt(KEY_DOCK_CREATE_MODE, mDockCreateMode);
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -07001077 if (mAnimSpecs != null) {
1078 b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs);
1079 }
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -07001080 if (mAnimationFinishedListener != null) {
1081 b.putBinder(KEY_ANIMATION_FINISHED_LISTENER, mAnimationFinishedListener.asBinder());
1082 }
Craig Mautnerbb742462014-07-07 15:28:55 -07001083
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001084 return b;
1085 }
Adam Powellcfbe9be2013-11-06 14:58:58 -08001086
1087 /**
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07001088 * Ask the the system track that time the user spends in the app being launched, and
1089 * report it back once done. The report will be sent to the given receiver, with
Dianne Hackborn67ba2c72015-06-05 14:23:38 -07001090 * the extras {@link #EXTRA_USAGE_TIME_REPORT} and {@link #EXTRA_USAGE_TIME_REPORT_PACKAGES}
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07001091 * filled in.
1092 *
1093 * <p>The time interval tracked is from launching this activity until the user leaves
1094 * that activity's flow. They are considered to stay in the flow as long as
1095 * new activities are being launched or returned to from the original flow,
1096 * even if this crosses package or task boundaries. For example, if the originator
1097 * starts an activity to view an image, and while there the user selects to share,
1098 * which launches their email app in a new task, and they complete the share, the
1099 * time during that entire operation will be included until they finally hit back from
1100 * the original image viewer activity.</p>
1101 *
1102 * <p>The user is considered to complete a flow once they switch to another
1103 * activity that is not part of the tracked flow. This may happen, for example, by
1104 * using the notification shade, launcher, or recents to launch or switch to another
1105 * app. Simply going in to these navigation elements does not break the flow (although
1106 * the launcher and recents stops time tracking of the session); it is the act of
1107 * going somewhere else that completes the tracking.</p>
1108 *
1109 * @param receiver A broadcast receiver that willl receive the report.
1110 */
1111 public void requestUsageTimeReport(PendingIntent receiver) {
1112 mUsageTimeReport = receiver;
1113 }
1114
1115 /**
Adam Powellcfbe9be2013-11-06 14:58:58 -08001116 * Return the filtered options only meant to be seen by the target activity itself
1117 * @hide
1118 */
1119 public ActivityOptions forTargetActivity() {
1120 if (mAnimationType == ANIM_SCENE_TRANSITION) {
1121 final ActivityOptions result = new ActivityOptions();
1122 result.update(this);
1123 return result;
1124 }
1125
1126 return null;
1127 }
George Mount0a778ed2013-12-13 13:35:36 -08001128
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -08001129 /** @hide */
1130 @Override
1131 public String toString() {
1132 return "ActivityOptions(" + hashCode() + "), mPackageName=" + mPackageName
1133 + ", mAnimationType=" + mAnimationType + ", mStartX=" + mStartX + ", mStartY="
1134 + mStartY + ", mWidth=" + mWidth + ", mHeight=" + mHeight;
1135 }
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001136}