blob: b42cf683100a4fad8e636c4f21dfdd51758bf1d6 [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
Dianne Hackborn6de01a92012-03-19 19:07:40 -070022import android.content.Context;
George Mount62ab9b72014-05-02 13:51:17 -070023import android.content.Intent;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070024import android.graphics.Bitmap;
Chong Zhang0fa656b2015-08-31 15:17:21 -070025import android.graphics.Rect;
Dianne Hackborn6de01a92012-03-19 19:07:40 -070026import android.os.Bundle;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070027import android.os.Handler;
28import android.os.IRemoteCallback;
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -070029import android.os.Parcelable;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070030import android.os.RemoteException;
George Mountcb4b7d92014-02-25 10:47:55 -080031import android.os.ResultReceiver;
George Mounte1803372014-02-26 19:00:52 +000032import android.util.Pair;
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070033import android.util.Slog;
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -070034import android.view.AppTransitionAnimationSpec;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070035import android.view.View;
George Mount31a21722014-03-24 17:44:36 -070036import android.view.Window;
Dianne Hackborn6de01a92012-03-19 19:07:40 -070037
George Mount62ab9b72014-05-02 13:51:17 -070038import java.util.ArrayList;
George Mount0a778ed2013-12-13 13:35:36 -080039
Dianne Hackborn6de01a92012-03-19 19:07:40 -070040/**
41 * Helper class for building an options Bundle that can be used with
42 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
43 * Context.startActivity(Intent, Bundle)} and related methods.
44 */
45public class ActivityOptions {
Adam Powellcfbe9be2013-11-06 14:58:58 -080046 private static final String TAG = "ActivityOptions";
47
Dianne Hackborn6de01a92012-03-19 19:07:40 -070048 /**
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070049 * A long in the extras delivered by {@link #requestUsageTimeReport} that contains
Dianne Hackborn67ba2c72015-06-05 14:23:38 -070050 * the total time (in ms) the user spent in the app flow.
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070051 */
Dianne Hackborna750a632015-06-16 17:18:23 -070052 public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070053
54 /**
55 * A Bundle in the extras delivered by {@link #requestUsageTimeReport} that contains
56 * detailed information about the time spent in each package associated with the app;
57 * each key is a package name, whose value is a long containing the time (in ms).
58 */
Dianne Hackborn67ba2c72015-06-05 14:23:38 -070059 public static final String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070060
61 /**
Dianne Hackborn6de01a92012-03-19 19:07:40 -070062 * The package name that created the options.
63 * @hide
64 */
Dianne Hackborna750a632015-06-16 17:18:23 -070065 public static final String KEY_PACKAGE_NAME = "android:activity.packageName";
Dianne Hackborn6de01a92012-03-19 19:07:40 -070066
67 /**
Wale Ogunwale7a8fa602015-11-18 15:56:57 -080068 * The bounds (window size) that the activity should be launched in. Set to null explicitly for
69 * full screen. If the key is not found, previous bounds will be preserved.
70 * NOTE: This value is ignored on devices that don't have
Wale Ogunwale854809c2015-12-27 16:18:19 -080071 * {@link android.content.pm.PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT} or
72 * {@link android.content.pm.PackageManager#FEATURE_PICTURE_IN_PICTURE} enabled.
Chong Zhang0fa656b2015-08-31 15:17:21 -070073 * @hide
74 */
Wale Ogunwale7a8fa602015-11-18 15:56:57 -080075 public static final String KEY_LAUNCH_BOUNDS = "android:activity.launchBounds";
Chong Zhang0fa656b2015-08-31 15:17:21 -070076
77 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070078 * Type of animation that arguments specify.
79 * @hide
80 */
Dianne Hackborna750a632015-06-16 17:18:23 -070081 public static final String KEY_ANIM_TYPE = "android:activity.animType";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070082
83 /**
Dianne Hackborn6de01a92012-03-19 19:07:40 -070084 * Custom enter animation resource ID.
85 * @hide
86 */
Dianne Hackborna750a632015-06-16 17:18:23 -070087 public static final String KEY_ANIM_ENTER_RES_ID = "android:activity.animEnterRes";
Dianne Hackborn6de01a92012-03-19 19:07:40 -070088
89 /**
90 * Custom exit animation resource ID.
91 * @hide
92 */
Dianne Hackborna750a632015-06-16 17:18:23 -070093 public static final String KEY_ANIM_EXIT_RES_ID = "android:activity.animExitRes";
Dianne Hackborn6de01a92012-03-19 19:07:40 -070094
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070095 /**
Winson Chung044d5292014-11-06 11:05:19 -080096 * Custom in-place animation resource ID.
97 * @hide
98 */
Dianne Hackborna750a632015-06-16 17:18:23 -070099 public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:activity.animInPlaceRes";
Winson Chung044d5292014-11-06 11:05:19 -0800100
101 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700102 * Bitmap for thumbnail animation.
103 * @hide
104 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700105 public static final String KEY_ANIM_THUMBNAIL = "android:activity.animThumbnail";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700106
107 /**
108 * Start X position of thumbnail animation.
109 * @hide
110 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700111 public static final String KEY_ANIM_START_X = "android:activity.animStartX";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700112
113 /**
114 * Start Y position of thumbnail animation.
115 * @hide
116 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700117 public static final String KEY_ANIM_START_Y = "android:activity.animStartY";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700118
119 /**
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700120 * Initial width of the animation.
121 * @hide
122 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700123 public static final String KEY_ANIM_WIDTH = "android:activity.animWidth";
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700124
125 /**
126 * Initial height of the animation.
127 * @hide
128 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700129 public static final String KEY_ANIM_HEIGHT = "android:activity.animHeight";
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700130
131 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700132 * Callback for when animation is started.
133 * @hide
134 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700135 public static final String KEY_ANIM_START_LISTENER = "android:activity.animStartListener";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700136
Adam Powell18e905f2013-10-24 14:27:48 -0700137 /**
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700138 * Callback for when the last frame of the animation is played.
139 * @hide
140 */
141 private static final String KEY_ANIMATION_FINISHED_LISTENER =
142 "android:activity.animationFinishedListener";
143
144 /**
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700145 * Descriptions of app transition animations to be played during the activity launch.
146 */
147 private static final String KEY_ANIM_SPECS = "android:activity.animSpecs";
148
149 /**
Wale Ogunwale854809c2015-12-27 16:18:19 -0800150 * The stack id the activity should be launched into.
151 * @hide
152 */
153 private static final String KEY_LAUNCH_STACK_ID = "android.activity.launchStackId";
154
155 /**
Filip Gruszczynski90186c62015-10-26 14:07:00 -0700156 * Where the docked stack should be positioned.
157 * @hide
158 */
159 private static final String KEY_DOCK_CREATE_MODE = "android:activity.dockCreateMode";
160
161 /**
George Mount0a778ed2013-12-13 13:35:36 -0800162 * For Activity transitions, the calling Activity's TransitionListener used to
163 * notify the called Activity when the shared element and the exit transitions
164 * complete.
165 */
166 private static final String KEY_TRANSITION_COMPLETE_LISTENER
Dianne Hackborna750a632015-06-16 17:18:23 -0700167 = "android:activity.transitionCompleteListener";
George Mount0a778ed2013-12-13 13:35:36 -0800168
Dianne Hackborna750a632015-06-16 17:18:23 -0700169 private static final String KEY_TRANSITION_IS_RETURNING
170 = "android:activity.transitionIsReturning";
171 private static final String KEY_TRANSITION_SHARED_ELEMENTS
172 = "android:activity.sharedElementNames";
173 private static final String KEY_RESULT_DATA = "android:activity.resultData";
174 private static final String KEY_RESULT_CODE = "android:activity.resultCode";
175 private static final String KEY_EXIT_COORDINATOR_INDEX
176 = "android:activity.exitCoordinatorIndex";
George Mount62ab9b72014-05-02 13:51:17 -0700177
Dianne Hackborna750a632015-06-16 17:18:23 -0700178 private static final String KEY_USAGE_TIME_REPORT = "android:activity.usageTimeReport";
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700179
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700180 /** @hide */
181 public static final int ANIM_NONE = 0;
182 /** @hide */
183 public static final int ANIM_CUSTOM = 1;
184 /** @hide */
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700185 public static final int ANIM_SCALE_UP = 2;
186 /** @hide */
Michael Jurka832cb222012-04-13 09:32:47 -0700187 public static final int ANIM_THUMBNAIL_SCALE_UP = 3;
Michael Jurka21385cd2012-05-03 10:57:31 -0700188 /** @hide */
Michael Jurka832cb222012-04-13 09:32:47 -0700189 public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4;
Adam Powell18e905f2013-10-24 14:27:48 -0700190 /** @hide */
191 public static final int ANIM_SCENE_TRANSITION = 5;
George Mount0b6f3e12014-06-20 07:35:23 -0700192 /** @hide */
193 public static final int ANIM_DEFAULT = 6;
Craig Mautnerbb742462014-07-07 15:28:55 -0700194 /** @hide */
195 public static final int ANIM_LAUNCH_TASK_BEHIND = 7;
Winson Chunga4ccb862014-08-22 15:26:27 -0700196 /** @hide */
197 public static final int ANIM_THUMBNAIL_ASPECT_SCALE_UP = 8;
198 /** @hide */
199 public static final int ANIM_THUMBNAIL_ASPECT_SCALE_DOWN = 9;
Winson Chung044d5292014-11-06 11:05:19 -0800200 /** @hide */
201 public static final int ANIM_CUSTOM_IN_PLACE = 10;
Chet Haase10e23ab2015-02-11 15:08:38 -0800202 /** @hide */
203 public static final int ANIM_CLIP_REVEAL = 11;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700204
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700205 private String mPackageName;
Wale Ogunwale7a8fa602015-11-18 15:56:57 -0800206 private boolean mHasLaunchBounds;
207 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 Ogunwale7a8fa602015-11-18 15:56:57 -0800719 mHasLaunchBounds = opts.containsKey(KEY_LAUNCH_BOUNDS);
720 if (mHasLaunchBounds) {
721 mLaunchBounds = opts.getParcelable(KEY_LAUNCH_BOUNDS);
Chong Zhang0fa656b2015-08-31 15:17:21 -0700722 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700723 mAnimationType = opts.getInt(KEY_ANIM_TYPE);
Adam Powell18e905f2013-10-24 14:27:48 -0700724 switch (mAnimationType) {
725 case ANIM_CUSTOM:
726 mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
727 mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
728 mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
729 opts.getBinder(KEY_ANIM_START_LISTENER));
730 break;
731
Winson Chung044d5292014-11-06 11:05:19 -0800732 case ANIM_CUSTOM_IN_PLACE:
733 mCustomInPlaceResId = opts.getInt(KEY_ANIM_IN_PLACE_RES_ID, 0);
734 break;
735
Adam Powell18e905f2013-10-24 14:27:48 -0700736 case ANIM_SCALE_UP:
Chet Haase10e23ab2015-02-11 15:08:38 -0800737 case ANIM_CLIP_REVEAL:
Adam Powell18e905f2013-10-24 14:27:48 -0700738 mStartX = opts.getInt(KEY_ANIM_START_X, 0);
739 mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200740 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
741 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
Adam Powell18e905f2013-10-24 14:27:48 -0700742 break;
743
744 case ANIM_THUMBNAIL_SCALE_UP:
745 case ANIM_THUMBNAIL_SCALE_DOWN:
Winson Chunga4ccb862014-08-22 15:26:27 -0700746 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
747 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
748 mThumbnail = (Bitmap) opts.getParcelable(KEY_ANIM_THUMBNAIL);
Adam Powell18e905f2013-10-24 14:27:48 -0700749 mStartX = opts.getInt(KEY_ANIM_START_X, 0);
750 mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200751 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
752 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
Adam Powell18e905f2013-10-24 14:27:48 -0700753 mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
754 opts.getBinder(KEY_ANIM_START_LISTENER));
755 break;
756
757 case ANIM_SCENE_TRANSITION:
George Mount62ab9b72014-05-02 13:51:17 -0700758 mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER);
759 mIsReturning = opts.getBoolean(KEY_TRANSITION_IS_RETURNING, false);
760 mSharedElementNames = opts.getStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS);
George Mount62ab9b72014-05-02 13:51:17 -0700761 mResultData = opts.getParcelable(KEY_RESULT_DATA);
762 mResultCode = opts.getInt(KEY_RESULT_CODE);
George Mount1fecfb22014-06-18 14:55:55 -0700763 mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX);
Adam Powell18e905f2013-10-24 14:27:48 -0700764 break;
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700765 }
Wale Ogunwale854809c2015-12-27 16:18:19 -0800766 mLaunchStackId = opts.getInt(KEY_LAUNCH_STACK_ID, INVALID_STACK_ID);
Filip Gruszczynski90186c62015-10-26 14:07:00 -0700767 mDockCreateMode = opts.getInt(KEY_DOCK_CREATE_MODE, DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT);
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700768 if (opts.containsKey(KEY_ANIM_SPECS)) {
769 Parcelable[] specs = opts.getParcelableArray(KEY_ANIM_SPECS);
770 mAnimSpecs = new AppTransitionAnimationSpec[specs.length];
771 for (int i = specs.length - 1; i >= 0; i--) {
772 mAnimSpecs[i] = (AppTransitionAnimationSpec) specs[i];
773 }
774 }
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700775 if (opts.containsKey(KEY_ANIMATION_FINISHED_LISTENER)) {
776 mAnimationFinishedListener = IRemoteCallback.Stub.asInterface(
777 opts.getBinder(KEY_ANIMATION_FINISHED_LISTENER));
778 }
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700779 }
780
Wale Ogunwale7a8fa602015-11-18 15:56:57 -0800781 /**
782 * Sets the bounds (window size) that the activity should be launched in. Set to null explicitly
783 * for full screen.
784 * NOTE: This value is ignored on devices that don't have
785 * {@link android.content.pm.PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT} enabled.
786 */
787 public ActivityOptions setLaunchBounds(Rect launchBounds) {
788 mHasLaunchBounds = true;
789 mLaunchBounds = launchBounds;
Chong Zhang0fa656b2015-08-31 15:17:21 -0700790 return this;
791 }
792
793 /** @hide */
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700794 public String getPackageName() {
795 return mPackageName;
796 }
797
Wale Ogunwale7a8fa602015-11-18 15:56:57 -0800798 public boolean hasLaunchBounds() {
799 return mHasLaunchBounds;
Chong Zhang0fa656b2015-08-31 15:17:21 -0700800 }
801
Wale Ogunwale7a8fa602015-11-18 15:56:57 -0800802 public Rect getLaunchBounds(){
803 return mLaunchBounds;
Chong Zhang0fa656b2015-08-31 15:17:21 -0700804 }
805
806 /** @hide */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700807 public int getAnimationType() {
808 return mAnimationType;
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700809 }
810
811 /** @hide */
812 public int getCustomEnterResId() {
813 return mCustomEnterResId;
814 }
815
816 /** @hide */
817 public int getCustomExitResId() {
818 return mCustomExitResId;
819 }
820
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700821 /** @hide */
Winson Chung044d5292014-11-06 11:05:19 -0800822 public int getCustomInPlaceResId() {
823 return mCustomInPlaceResId;
824 }
825
826 /** @hide */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700827 public Bitmap getThumbnail() {
828 return mThumbnail;
829 }
830
831 /** @hide */
832 public int getStartX() {
833 return mStartX;
834 }
835
836 /** @hide */
837 public int getStartY() {
838 return mStartY;
839 }
840
841 /** @hide */
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200842 public int getWidth() {
843 return mWidth;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700844 }
845
846 /** @hide */
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200847 public int getHeight() {
848 return mHeight;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700849 }
850
851 /** @hide */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700852 public IRemoteCallback getOnAnimationStartListener() {
853 return mAnimationStartedListener;
854 }
855
856 /** @hide */
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700857 public IRemoteCallback getAnimationFinishedListener() {
858 return mAnimationFinishedListener;
859 }
860
861 /** @hide */
George Mount1fecfb22014-06-18 14:55:55 -0700862 public int getExitCoordinatorKey() { return mExitCoordinatorIndex; }
George Mounte1803372014-02-26 19:00:52 +0000863
864 /** @hide */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700865 public void abort() {
866 if (mAnimationStartedListener != null) {
867 try {
868 mAnimationStartedListener.sendResult(null);
869 } catch (RemoteException e) {
870 }
871 }
872 }
873
874 /** @hide */
George Mount62ab9b72014-05-02 13:51:17 -0700875 public boolean isReturning() {
876 return mIsReturning;
877 }
878
879 /** @hide */
880 public ArrayList<String> getSharedElementNames() {
881 return mSharedElementNames;
882 }
883
884 /** @hide */
George Mount62ab9b72014-05-02 13:51:17 -0700885 public ResultReceiver getResultReceiver() { return mTransitionReceiver; }
886
887 /** @hide */
888 public int getResultCode() { return mResultCode; }
889
890 /** @hide */
891 public Intent getResultData() { return mResultData; }
892
893 /** @hide */
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700894 public PendingIntent getUsageTimeReport() {
895 return mUsageTimeReport;
896 }
897
898 /** @hide */
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700899 public AppTransitionAnimationSpec[] getAnimSpecs() { return mAnimSpecs; }
900
901 /** @hide */
Chong Zhang280d3322015-11-03 17:27:26 -0800902 public static ActivityOptions fromBundle(Bundle bOptions) {
903 return bOptions != null ? new ActivityOptions(bOptions) : null;
904 }
905
906 /** @hide */
907 public static void abort(ActivityOptions options) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700908 if (options != null) {
Chong Zhang280d3322015-11-03 17:27:26 -0800909 options.abort();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700910 }
911 }
912
Filip Gruszczynski90186c62015-10-26 14:07:00 -0700913 /** @hide */
Wale Ogunwale854809c2015-12-27 16:18:19 -0800914 public int getLaunchStackId() {
915 return mLaunchStackId;
916 }
917
918 /** @hide */
919 public void setLaunchStackId(int launchStackId) {
920 mLaunchStackId = launchStackId;
921 }
922
923 /** @hide */
924 public int getDockCreateMode() {
925 return mDockCreateMode;
926 }
Filip Gruszczynski90186c62015-10-26 14:07:00 -0700927
928 /** @hide */
929 public void setDockCreateMode(int dockCreateMode) {
930 mDockCreateMode = dockCreateMode;
931 }
932
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700933 /**
Dianne Hackbornddc52a82012-05-03 19:40:12 -0700934 * Update the current values in this ActivityOptions from those supplied
935 * in <var>otherOptions</var>. Any values
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700936 * defined in <var>otherOptions</var> replace those in the base options.
937 */
Dianne Hackbornddc52a82012-05-03 19:40:12 -0700938 public void update(ActivityOptions otherOptions) {
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700939 if (otherOptions.mPackageName != null) {
940 mPackageName = otherOptions.mPackageName;
941 }
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700942 mUsageTimeReport = otherOptions.mUsageTimeReport;
George Mount62ab9b72014-05-02 13:51:17 -0700943 mTransitionReceiver = null;
944 mSharedElementNames = null;
George Mount62ab9b72014-05-02 13:51:17 -0700945 mIsReturning = false;
946 mResultData = null;
947 mResultCode = 0;
George Mount1fecfb22014-06-18 14:55:55 -0700948 mExitCoordinatorIndex = 0;
George Mount00dde0b2014-07-01 15:27:07 -0700949 mAnimationType = otherOptions.mAnimationType;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700950 switch (otherOptions.mAnimationType) {
951 case ANIM_CUSTOM:
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700952 mCustomEnterResId = otherOptions.mCustomEnterResId;
953 mCustomExitResId = otherOptions.mCustomExitResId;
954 mThumbnail = null;
Adam Powell18e905f2013-10-24 14:27:48 -0700955 if (mAnimationStartedListener != null) {
Dianne Hackborn84375872012-06-01 19:03:50 -0700956 try {
Adam Powell18e905f2013-10-24 14:27:48 -0700957 mAnimationStartedListener.sendResult(null);
Dianne Hackborn84375872012-06-01 19:03:50 -0700958 } catch (RemoteException e) {
959 }
960 }
961 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700962 break;
Winson Chung044d5292014-11-06 11:05:19 -0800963 case ANIM_CUSTOM_IN_PLACE:
964 mCustomInPlaceResId = otherOptions.mCustomInPlaceResId;
965 break;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700966 case ANIM_SCALE_UP:
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700967 mStartX = otherOptions.mStartX;
968 mStartY = otherOptions.mStartY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200969 mWidth = otherOptions.mWidth;
970 mHeight = otherOptions.mHeight;
Adam Powell18e905f2013-10-24 14:27:48 -0700971 if (mAnimationStartedListener != null) {
Dianne Hackborn84375872012-06-01 19:03:50 -0700972 try {
Adam Powell18e905f2013-10-24 14:27:48 -0700973 mAnimationStartedListener.sendResult(null);
Dianne Hackborn84375872012-06-01 19:03:50 -0700974 } catch (RemoteException e) {
975 }
976 }
977 mAnimationStartedListener = null;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700978 break;
Michael Jurka832cb222012-04-13 09:32:47 -0700979 case ANIM_THUMBNAIL_SCALE_UP:
980 case ANIM_THUMBNAIL_SCALE_DOWN:
Winson Chunga4ccb862014-08-22 15:26:27 -0700981 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
982 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700983 mThumbnail = otherOptions.mThumbnail;
984 mStartX = otherOptions.mStartX;
985 mStartY = otherOptions.mStartY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200986 mWidth = otherOptions.mWidth;
987 mHeight = otherOptions.mHeight;
Adam Powell18e905f2013-10-24 14:27:48 -0700988 if (mAnimationStartedListener != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700989 try {
Adam Powell18e905f2013-10-24 14:27:48 -0700990 mAnimationStartedListener.sendResult(null);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700991 } catch (RemoteException e) {
992 }
993 }
994 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
Adam Powell18e905f2013-10-24 14:27:48 -0700995 break;
996 case ANIM_SCENE_TRANSITION:
George Mount62ab9b72014-05-02 13:51:17 -0700997 mTransitionReceiver = otherOptions.mTransitionReceiver;
998 mSharedElementNames = otherOptions.mSharedElementNames;
George Mount62ab9b72014-05-02 13:51:17 -0700999 mIsReturning = otherOptions.mIsReturning;
Adam Powellcfbe9be2013-11-06 14:58:58 -08001000 mThumbnail = null;
Adam Powell18e905f2013-10-24 14:27:48 -07001001 mAnimationStartedListener = null;
George Mount62ab9b72014-05-02 13:51:17 -07001002 mResultData = otherOptions.mResultData;
1003 mResultCode = otherOptions.mResultCode;
George Mount1fecfb22014-06-18 14:55:55 -07001004 mExitCoordinatorIndex = otherOptions.mExitCoordinatorIndex;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001005 break;
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001006 }
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -07001007 mAnimSpecs = otherOptions.mAnimSpecs;
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -07001008 mAnimationFinishedListener = otherOptions.mAnimationFinishedListener;
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001009 }
1010
1011 /**
1012 * Returns the created options as a Bundle, which can be passed to
1013 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
1014 * Context.startActivity(Intent, Bundle)} and related methods.
1015 * Note that the returned Bundle is still owned by the ActivityOptions
1016 * object; you must not modify it, but can supply it to the startActivity
1017 * methods that take an options Bundle.
1018 */
1019 public Bundle toBundle() {
George Mount0b6f3e12014-06-20 07:35:23 -07001020 if (mAnimationType == ANIM_DEFAULT) {
1021 return null;
1022 }
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001023 Bundle b = new Bundle();
1024 if (mPackageName != null) {
1025 b.putString(KEY_PACKAGE_NAME, mPackageName);
1026 }
Wale Ogunwale7a8fa602015-11-18 15:56:57 -08001027 if (mHasLaunchBounds) {
1028 b.putParcelable(KEY_LAUNCH_BOUNDS, mLaunchBounds);
Chong Zhang0fa656b2015-08-31 15:17:21 -07001029 }
Craig Mautnerbb742462014-07-07 15:28:55 -07001030 b.putInt(KEY_ANIM_TYPE, mAnimationType);
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07001031 if (mUsageTimeReport != null) {
1032 b.putParcelable(KEY_USAGE_TIME_REPORT, mUsageTimeReport);
1033 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001034 switch (mAnimationType) {
1035 case ANIM_CUSTOM:
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001036 b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
1037 b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
Adam Powellcfbe9be2013-11-06 14:58:58 -08001038 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
Dianne Hackborn84375872012-06-01 19:03:50 -07001039 != null ? mAnimationStartedListener.asBinder() : null);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001040 break;
Winson Chung044d5292014-11-06 11:05:19 -08001041 case ANIM_CUSTOM_IN_PLACE:
1042 b.putInt(KEY_ANIM_IN_PLACE_RES_ID, mCustomInPlaceResId);
1043 break;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001044 case ANIM_SCALE_UP:
Chet Haase10e23ab2015-02-11 15:08:38 -08001045 case ANIM_CLIP_REVEAL:
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001046 b.putInt(KEY_ANIM_START_X, mStartX);
1047 b.putInt(KEY_ANIM_START_Y, mStartY);
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001048 b.putInt(KEY_ANIM_WIDTH, mWidth);
1049 b.putInt(KEY_ANIM_HEIGHT, mHeight);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001050 break;
Michael Jurka832cb222012-04-13 09:32:47 -07001051 case ANIM_THUMBNAIL_SCALE_UP:
1052 case ANIM_THUMBNAIL_SCALE_DOWN:
Winson Chunga4ccb862014-08-22 15:26:27 -07001053 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
1054 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001055 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
1056 b.putInt(KEY_ANIM_START_X, mStartX);
1057 b.putInt(KEY_ANIM_START_Y, mStartY);
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001058 b.putInt(KEY_ANIM_WIDTH, mWidth);
1059 b.putInt(KEY_ANIM_HEIGHT, mHeight);
Adam Powellcfbe9be2013-11-06 14:58:58 -08001060 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001061 != null ? mAnimationStartedListener.asBinder() : null);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001062 break;
Adam Powellcfbe9be2013-11-06 14:58:58 -08001063 case ANIM_SCENE_TRANSITION:
George Mount62ab9b72014-05-02 13:51:17 -07001064 if (mTransitionReceiver != null) {
1065 b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionReceiver);
George Mount0a778ed2013-12-13 13:35:36 -08001066 }
George Mount62ab9b72014-05-02 13:51:17 -07001067 b.putBoolean(KEY_TRANSITION_IS_RETURNING, mIsReturning);
1068 b.putStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS, mSharedElementNames);
George Mount62ab9b72014-05-02 13:51:17 -07001069 b.putParcelable(KEY_RESULT_DATA, mResultData);
1070 b.putInt(KEY_RESULT_CODE, mResultCode);
George Mount1fecfb22014-06-18 14:55:55 -07001071 b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
Adam Powellcfbe9be2013-11-06 14:58:58 -08001072 break;
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001073 }
Wale Ogunwale854809c2015-12-27 16:18:19 -08001074 b.putInt(KEY_LAUNCH_STACK_ID, mLaunchStackId);
Filip Gruszczynski90186c62015-10-26 14:07:00 -07001075 b.putInt(KEY_DOCK_CREATE_MODE, mDockCreateMode);
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -07001076 if (mAnimSpecs != null) {
1077 b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs);
1078 }
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -07001079 if (mAnimationFinishedListener != null) {
1080 b.putBinder(KEY_ANIMATION_FINISHED_LISTENER, mAnimationFinishedListener.asBinder());
1081 }
Craig Mautnerbb742462014-07-07 15:28:55 -07001082
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001083 return b;
1084 }
Adam Powellcfbe9be2013-11-06 14:58:58 -08001085
1086 /**
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07001087 * Ask the the system track that time the user spends in the app being launched, and
1088 * report it back once done. The report will be sent to the given receiver, with
Dianne Hackborn67ba2c72015-06-05 14:23:38 -07001089 * the extras {@link #EXTRA_USAGE_TIME_REPORT} and {@link #EXTRA_USAGE_TIME_REPORT_PACKAGES}
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07001090 * filled in.
1091 *
1092 * <p>The time interval tracked is from launching this activity until the user leaves
1093 * that activity's flow. They are considered to stay in the flow as long as
1094 * new activities are being launched or returned to from the original flow,
1095 * even if this crosses package or task boundaries. For example, if the originator
1096 * starts an activity to view an image, and while there the user selects to share,
1097 * which launches their email app in a new task, and they complete the share, the
1098 * time during that entire operation will be included until they finally hit back from
1099 * the original image viewer activity.</p>
1100 *
1101 * <p>The user is considered to complete a flow once they switch to another
1102 * activity that is not part of the tracked flow. This may happen, for example, by
1103 * using the notification shade, launcher, or recents to launch or switch to another
1104 * app. Simply going in to these navigation elements does not break the flow (although
1105 * the launcher and recents stops time tracking of the session); it is the act of
1106 * going somewhere else that completes the tracking.</p>
1107 *
1108 * @param receiver A broadcast receiver that willl receive the report.
1109 */
1110 public void requestUsageTimeReport(PendingIntent receiver) {
1111 mUsageTimeReport = receiver;
1112 }
1113
1114 /**
Adam Powellcfbe9be2013-11-06 14:58:58 -08001115 * Return the filtered options only meant to be seen by the target activity itself
1116 * @hide
1117 */
1118 public ActivityOptions forTargetActivity() {
1119 if (mAnimationType == ANIM_SCENE_TRANSITION) {
1120 final ActivityOptions result = new ActivityOptions();
1121 result.update(this);
1122 return result;
1123 }
1124
1125 return null;
1126 }
George Mount0a778ed2013-12-13 13:35:36 -08001127
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -08001128 /** @hide */
1129 @Override
1130 public String toString() {
1131 return "ActivityOptions(" + hashCode() + "), mPackageName=" + mPackageName
1132 + ", mAnimationType=" + mAnimationType + ", mStartX=" + mStartX + ", mStartY="
1133 + mStartY + ", mWidth=" + mWidth + ", mHeight=" + mHeight;
1134 }
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001135}