blob: d9a46903ee38e514e18a8a08cd6e65689ef03958 [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;
Vladislav Kaznacheevacf147e2016-05-05 09:32:27 -070023import android.annotation.TestApi;
Dianne Hackborn6de01a92012-03-19 19:07:40 -070024import android.content.Context;
George Mount62ab9b72014-05-02 13:51:17 -070025import android.content.Intent;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070026import android.graphics.Bitmap;
Chong Zhang0fa656b2015-08-31 15:17:21 -070027import android.graphics.Rect;
Dianne Hackborn6de01a92012-03-19 19:07:40 -070028import android.os.Bundle;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070029import android.os.Handler;
30import android.os.IRemoteCallback;
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -070031import android.os.Parcelable;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070032import android.os.RemoteException;
George Mountcb4b7d92014-02-25 10:47:55 -080033import android.os.ResultReceiver;
George Mount413739e2016-06-08 07:13:37 -070034import android.transition.Transition;
35import android.transition.TransitionManager;
George Mounte1803372014-02-26 19:00:52 +000036import android.util.Pair;
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070037import android.util.Slog;
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -070038import android.view.AppTransitionAnimationSpec;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070039import android.view.View;
George Mount413739e2016-06-08 07:13:37 -070040import android.view.ViewGroup;
George Mount31a21722014-03-24 17:44:36 -070041import android.view.Window;
Dianne Hackborn6de01a92012-03-19 19:07:40 -070042
George Mount62ab9b72014-05-02 13:51:17 -070043import java.util.ArrayList;
George Mount0a778ed2013-12-13 13:35:36 -080044
Dianne Hackborn6de01a92012-03-19 19:07:40 -070045/**
46 * Helper class for building an options Bundle that can be used with
47 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
48 * Context.startActivity(Intent, Bundle)} and related methods.
49 */
50public class ActivityOptions {
Adam Powellcfbe9be2013-11-06 14:58:58 -080051 private static final String TAG = "ActivityOptions";
52
Dianne Hackborn6de01a92012-03-19 19:07:40 -070053 /**
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070054 * A long in the extras delivered by {@link #requestUsageTimeReport} that contains
Dianne Hackborn67ba2c72015-06-05 14:23:38 -070055 * the total time (in ms) the user spent in the app flow.
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070056 */
Dianne Hackborna750a632015-06-16 17:18:23 -070057 public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070058
59 /**
60 * A Bundle in the extras delivered by {@link #requestUsageTimeReport} that contains
61 * detailed information about the time spent in each package associated with the app;
62 * each key is a package name, whose value is a long containing the time (in ms).
63 */
Dianne Hackborn67ba2c72015-06-05 14:23:38 -070064 public static final String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
Dianne Hackbornb5a380d2015-05-20 18:18:46 -070065
66 /**
Dianne Hackborn6de01a92012-03-19 19:07:40 -070067 * The package name that created the options.
68 * @hide
69 */
Dianne Hackborna750a632015-06-16 17:18:23 -070070 public static final String KEY_PACKAGE_NAME = "android:activity.packageName";
Dianne Hackborn6de01a92012-03-19 19:07:40 -070071
72 /**
Wale Ogunwale7a8fa602015-11-18 15:56:57 -080073 * The bounds (window size) that the activity should be launched in. Set to null explicitly for
74 * full screen. If the key is not found, previous bounds will be preserved.
75 * NOTE: This value is ignored on devices that don't have
Wale Ogunwale854809c2015-12-27 16:18:19 -080076 * {@link android.content.pm.PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT} or
77 * {@link android.content.pm.PackageManager#FEATURE_PICTURE_IN_PICTURE} enabled.
Chong Zhang0fa656b2015-08-31 15:17:21 -070078 * @hide
79 */
Wale Ogunwale7a8fa602015-11-18 15:56:57 -080080 public static final String KEY_LAUNCH_BOUNDS = "android:activity.launchBounds";
Chong Zhang0fa656b2015-08-31 15:17:21 -070081
82 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070083 * Type of animation that arguments specify.
84 * @hide
85 */
Dianne Hackborna750a632015-06-16 17:18:23 -070086 public static final String KEY_ANIM_TYPE = "android:activity.animType";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070087
88 /**
Dianne Hackborn6de01a92012-03-19 19:07:40 -070089 * Custom enter animation resource ID.
90 * @hide
91 */
Dianne Hackborna750a632015-06-16 17:18:23 -070092 public static final String KEY_ANIM_ENTER_RES_ID = "android:activity.animEnterRes";
Dianne Hackborn6de01a92012-03-19 19:07:40 -070093
94 /**
95 * Custom exit animation resource ID.
96 * @hide
97 */
Dianne Hackborna750a632015-06-16 17:18:23 -070098 public static final String KEY_ANIM_EXIT_RES_ID = "android:activity.animExitRes";
Dianne Hackborn6de01a92012-03-19 19:07:40 -070099
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700100 /**
Winson Chung044d5292014-11-06 11:05:19 -0800101 * Custom in-place animation resource ID.
102 * @hide
103 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700104 public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:activity.animInPlaceRes";
Winson Chung044d5292014-11-06 11:05:19 -0800105
106 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700107 * Bitmap for thumbnail animation.
108 * @hide
109 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700110 public static final String KEY_ANIM_THUMBNAIL = "android:activity.animThumbnail";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700111
112 /**
113 * Start X position of thumbnail animation.
114 * @hide
115 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700116 public static final String KEY_ANIM_START_X = "android:activity.animStartX";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700117
118 /**
119 * Start Y position of thumbnail animation.
120 * @hide
121 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700122 public static final String KEY_ANIM_START_Y = "android:activity.animStartY";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700123
124 /**
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700125 * Initial width of the animation.
126 * @hide
127 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700128 public static final String KEY_ANIM_WIDTH = "android:activity.animWidth";
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700129
130 /**
131 * Initial height of the animation.
132 * @hide
133 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700134 public static final String KEY_ANIM_HEIGHT = "android:activity.animHeight";
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700135
136 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700137 * Callback for when animation is started.
138 * @hide
139 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700140 public static final String KEY_ANIM_START_LISTENER = "android:activity.animStartListener";
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700141
Adam Powell18e905f2013-10-24 14:27:48 -0700142 /**
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700143 * Callback for when the last frame of the animation is played.
144 * @hide
145 */
146 private static final String KEY_ANIMATION_FINISHED_LISTENER =
147 "android:activity.animationFinishedListener";
148
149 /**
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700150 * Descriptions of app transition animations to be played during the activity launch.
151 */
152 private static final String KEY_ANIM_SPECS = "android:activity.animSpecs";
153
154 /**
Wale Ogunwale854809c2015-12-27 16:18:19 -0800155 * The stack id the activity should be launched into.
156 * @hide
157 */
158 private static final String KEY_LAUNCH_STACK_ID = "android.activity.launchStackId";
159
160 /**
Jorim Jaggi2adba072016-03-03 13:43:39 +0100161 * The task id the activity should be launched into.
162 * @hide
163 */
164 private static final String KEY_LAUNCH_TASK_ID = "android.activity.launchTaskId";
165
166 /**
Wale Ogunwale3b232392016-05-13 15:37:13 -0700167 * See {@link #setTaskOverlay}.
Jorim Jaggic875ae72016-04-26 22:41:06 -0700168 * @hide
169 */
Wale Ogunwale3b232392016-05-13 15:37:13 -0700170 private static final String KEY_TASK_OVERLAY = "android.activity.taskOverlay";
Jorim Jaggic875ae72016-04-26 22:41:06 -0700171
172 /**
Filip Gruszczynski90186c62015-10-26 14:07:00 -0700173 * Where the docked stack should be positioned.
174 * @hide
175 */
176 private static final String KEY_DOCK_CREATE_MODE = "android:activity.dockCreateMode";
177
178 /**
George Mount0a778ed2013-12-13 13:35:36 -0800179 * For Activity transitions, the calling Activity's TransitionListener used to
180 * notify the called Activity when the shared element and the exit transitions
181 * complete.
182 */
183 private static final String KEY_TRANSITION_COMPLETE_LISTENER
Dianne Hackborna750a632015-06-16 17:18:23 -0700184 = "android:activity.transitionCompleteListener";
George Mount0a778ed2013-12-13 13:35:36 -0800185
Dianne Hackborna750a632015-06-16 17:18:23 -0700186 private static final String KEY_TRANSITION_IS_RETURNING
187 = "android:activity.transitionIsReturning";
188 private static final String KEY_TRANSITION_SHARED_ELEMENTS
189 = "android:activity.sharedElementNames";
190 private static final String KEY_RESULT_DATA = "android:activity.resultData";
191 private static final String KEY_RESULT_CODE = "android:activity.resultCode";
192 private static final String KEY_EXIT_COORDINATOR_INDEX
193 = "android:activity.exitCoordinatorIndex";
George Mount62ab9b72014-05-02 13:51:17 -0700194
Dianne Hackborna750a632015-06-16 17:18:23 -0700195 private static final String KEY_USAGE_TIME_REPORT = "android:activity.usageTimeReport";
Robert Carrfd10cd12016-06-29 16:41:50 -0700196 private static final String KEY_ROTATION_ANIMATION_HINT = "android:activity.rotationAnimationHint";
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700197
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700198 /** @hide */
199 public static final int ANIM_NONE = 0;
200 /** @hide */
201 public static final int ANIM_CUSTOM = 1;
202 /** @hide */
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700203 public static final int ANIM_SCALE_UP = 2;
204 /** @hide */
Michael Jurka832cb222012-04-13 09:32:47 -0700205 public static final int ANIM_THUMBNAIL_SCALE_UP = 3;
Michael Jurka21385cd2012-05-03 10:57:31 -0700206 /** @hide */
Michael Jurka832cb222012-04-13 09:32:47 -0700207 public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4;
Adam Powell18e905f2013-10-24 14:27:48 -0700208 /** @hide */
209 public static final int ANIM_SCENE_TRANSITION = 5;
George Mount0b6f3e12014-06-20 07:35:23 -0700210 /** @hide */
211 public static final int ANIM_DEFAULT = 6;
Craig Mautnerbb742462014-07-07 15:28:55 -0700212 /** @hide */
213 public static final int ANIM_LAUNCH_TASK_BEHIND = 7;
Winson Chunga4ccb862014-08-22 15:26:27 -0700214 /** @hide */
215 public static final int ANIM_THUMBNAIL_ASPECT_SCALE_UP = 8;
216 /** @hide */
217 public static final int ANIM_THUMBNAIL_ASPECT_SCALE_DOWN = 9;
Winson Chung044d5292014-11-06 11:05:19 -0800218 /** @hide */
219 public static final int ANIM_CUSTOM_IN_PLACE = 10;
Chet Haase10e23ab2015-02-11 15:08:38 -0800220 /** @hide */
221 public static final int ANIM_CLIP_REVEAL = 11;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700222
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700223 private String mPackageName;
Wale Ogunwale7a8fa602015-11-18 15:56:57 -0800224 private Rect mLaunchBounds;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700225 private int mAnimationType = ANIM_NONE;
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700226 private int mCustomEnterResId;
227 private int mCustomExitResId;
Winson Chung044d5292014-11-06 11:05:19 -0800228 private int mCustomInPlaceResId;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700229 private Bitmap mThumbnail;
230 private int mStartX;
231 private int mStartY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200232 private int mWidth;
233 private int mHeight;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700234 private IRemoteCallback mAnimationStartedListener;
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700235 private IRemoteCallback mAnimationFinishedListener;
George Mount62ab9b72014-05-02 13:51:17 -0700236 private ResultReceiver mTransitionReceiver;
237 private boolean mIsReturning;
238 private ArrayList<String> mSharedElementNames;
George Mount62ab9b72014-05-02 13:51:17 -0700239 private Intent mResultData;
240 private int mResultCode;
George Mount1fecfb22014-06-18 14:55:55 -0700241 private int mExitCoordinatorIndex;
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700242 private PendingIntent mUsageTimeReport;
Wale Ogunwale854809c2015-12-27 16:18:19 -0800243 private int mLaunchStackId = INVALID_STACK_ID;
Jorim Jaggi2adba072016-03-03 13:43:39 +0100244 private int mLaunchTaskId = -1;
Filip Gruszczynski90186c62015-10-26 14:07:00 -0700245 private int mDockCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
Wale Ogunwale3b232392016-05-13 15:37:13 -0700246 private boolean mTaskOverlay;
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700247 private AppTransitionAnimationSpec mAnimSpecs[];
Robert Carrfd10cd12016-06-29 16:41:50 -0700248 private int mRotationAnimationHint = -1;
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700249
250 /**
251 * Create an ActivityOptions specifying a custom animation to run when
252 * the activity is displayed.
253 *
254 * @param context Who is defining this. This is the application that the
255 * animation resources will be loaded from.
256 * @param enterResId A resource ID of the animation resource to use for
257 * the incoming activity. Use 0 for no animation.
258 * @param exitResId A resource ID of the animation resource to use for
259 * the outgoing activity. Use 0 for no animation.
260 * @return Returns a new ActivityOptions object that you can use to
261 * supply these options as the options Bundle when starting an activity.
262 */
263 public static ActivityOptions makeCustomAnimation(Context context,
264 int enterResId, int exitResId) {
Dianne Hackborn84375872012-06-01 19:03:50 -0700265 return makeCustomAnimation(context, enterResId, exitResId, null, null);
266 }
267
268 /**
269 * Create an ActivityOptions specifying a custom animation to run when
270 * the activity is displayed.
271 *
272 * @param context Who is defining this. This is the application that the
273 * animation resources will be loaded from.
274 * @param enterResId A resource ID of the animation resource to use for
275 * the incoming activity. Use 0 for no animation.
276 * @param exitResId A resource ID of the animation resource to use for
277 * the outgoing activity. Use 0 for no animation.
278 * @param handler If <var>listener</var> is non-null this must be a valid
279 * Handler on which to dispatch the callback; otherwise it should be null.
280 * @param listener Optional OnAnimationStartedListener to find out when the
281 * requested animation has started running. If for some reason the animation
282 * is not executed, the callback will happen immediately.
283 * @return Returns a new ActivityOptions object that you can use to
284 * supply these options as the options Bundle when starting an activity.
285 * @hide
286 */
287 public static ActivityOptions makeCustomAnimation(Context context,
288 int enterResId, int exitResId, Handler handler, OnAnimationStartedListener listener) {
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700289 ActivityOptions opts = new ActivityOptions();
290 opts.mPackageName = context.getPackageName();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700291 opts.mAnimationType = ANIM_CUSTOM;
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700292 opts.mCustomEnterResId = enterResId;
293 opts.mCustomExitResId = exitResId;
Adam Powell18e905f2013-10-24 14:27:48 -0700294 opts.setOnAnimationStartedListener(handler, listener);
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700295 return opts;
296 }
297
Winson Chung044d5292014-11-06 11:05:19 -0800298 /**
299 * Creates an ActivityOptions specifying a custom animation to run in place on an existing
300 * activity.
301 *
302 * @param context Who is defining this. This is the application that the
303 * animation resources will be loaded from.
304 * @param animId A resource ID of the animation resource to use for
305 * the incoming activity.
306 * @return Returns a new ActivityOptions object that you can use to
307 * supply these options as the options Bundle when running an in-place animation.
308 * @hide
309 */
310 public static ActivityOptions makeCustomInPlaceAnimation(Context context, int animId) {
311 if (animId == 0) {
312 throw new RuntimeException("You must specify a valid animation.");
313 }
314
315 ActivityOptions opts = new ActivityOptions();
316 opts.mPackageName = context.getPackageName();
317 opts.mAnimationType = ANIM_CUSTOM_IN_PLACE;
318 opts.mCustomInPlaceResId = animId;
319 return opts;
320 }
321
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700322 private void setOnAnimationStartedListener(final Handler handler,
323 final OnAnimationStartedListener listener) {
Dianne Hackborn84375872012-06-01 19:03:50 -0700324 if (listener != null) {
Dianne Hackborn84375872012-06-01 19:03:50 -0700325 mAnimationStartedListener = new IRemoteCallback.Stub() {
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700326 @Override
327 public void sendResult(Bundle data) throws RemoteException {
328 handler.post(new Runnable() {
Dianne Hackborn84375872012-06-01 19:03:50 -0700329 @Override public void run() {
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700330 listener.onAnimationStarted();
Dianne Hackborn84375872012-06-01 19:03:50 -0700331 }
332 });
333 }
334 };
335 }
336 }
337
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700338 /**
339 * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation}
340 * to find out when the given animation has started running.
Dianne Hackborn9944ecd2012-04-10 15:54:19 -0700341 * @hide
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700342 */
343 public interface OnAnimationStartedListener {
344 void onAnimationStarted();
345 }
346
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700347 private void setOnAnimationFinishedListener(final Handler handler,
348 final OnAnimationFinishedListener listener) {
349 if (listener != null) {
350 mAnimationFinishedListener = new IRemoteCallback.Stub() {
351 @Override
352 public void sendResult(Bundle data) throws RemoteException {
353 handler.post(new Runnable() {
354 @Override
355 public void run() {
356 listener.onAnimationFinished();
357 }
358 });
359 }
360 };
361 }
362 }
363
364 /**
365 * Callback for use with {@link ActivityOptions#makeThumbnailAspectScaleDownAnimation}
366 * to find out when the given animation has drawn its last frame.
367 * @hide
368 */
369 public interface OnAnimationFinishedListener {
370 void onAnimationFinished();
371 }
372
Adam Powell18e905f2013-10-24 14:27:48 -0700373 /**
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700374 * Create an ActivityOptions specifying an animation where the new
375 * activity is scaled from a small originating area of the screen to
376 * its final full representation.
377 *
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700378 * <p>If the Intent this is being used with has not set its
379 * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds},
380 * those bounds will be filled in for you based on the initial
381 * bounds passed in here.
382 *
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700383 * @param source The View that the new activity is animating from. This
384 * defines the coordinate space for <var>startX</var> and <var>startY</var>.
385 * @param startX The x starting location of the new activity, relative to <var>source</var>.
386 * @param startY The y starting location of the activity, relative to <var>source</var>.
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200387 * @param width The initial width of the new activity.
388 * @param height The initial height of the new activity.
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700389 * @return Returns a new ActivityOptions object that you can use to
390 * supply these options as the options Bundle when starting an activity.
391 */
392 public static ActivityOptions makeScaleUpAnimation(View source,
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200393 int startX, int startY, int width, int height) {
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700394 ActivityOptions opts = new ActivityOptions();
395 opts.mPackageName = source.getContext().getPackageName();
396 opts.mAnimationType = ANIM_SCALE_UP;
397 int[] pts = new int[2];
398 source.getLocationOnScreen(pts);
399 opts.mStartX = pts[0] + startX;
400 opts.mStartY = pts[1] + startY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200401 opts.mWidth = width;
402 opts.mHeight = height;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700403 return opts;
404 }
405
406 /**
Chet Haase10e23ab2015-02-11 15:08:38 -0800407 * Create an ActivityOptions specifying an animation where the new
408 * activity is revealed from a small originating area of the screen to
409 * its final full representation.
410 *
411 * @param source The View that the new activity is animating from. This
412 * defines the coordinate space for <var>startX</var> and <var>startY</var>.
413 * @param startX The x starting location of the new activity, relative to <var>source</var>.
414 * @param startY The y starting location of the activity, relative to <var>source</var>.
415 * @param width The initial width of the new activity.
416 * @param height The initial height of the new activity.
417 * @return Returns a new ActivityOptions object that you can use to
418 * supply these options as the options Bundle when starting an activity.
419 */
420 public static ActivityOptions makeClipRevealAnimation(View source,
421 int startX, int startY, int width, int height) {
422 ActivityOptions opts = new ActivityOptions();
423 opts.mAnimationType = ANIM_CLIP_REVEAL;
424 int[] pts = new int[2];
425 source.getLocationOnScreen(pts);
426 opts.mStartX = pts[0] + startX;
427 opts.mStartY = pts[1] + startY;
428 opts.mWidth = width;
429 opts.mHeight = height;
430 return opts;
431 }
432
433 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700434 * Create an ActivityOptions specifying an animation where a thumbnail
435 * is scaled from a given position to the new activity window that is
436 * being started.
437 *
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700438 * <p>If the Intent this is being used with has not set its
439 * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds},
440 * those bounds will be filled in for you based on the initial
441 * thumbnail location and size provided here.
442 *
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700443 * @param source The View that this thumbnail is animating from. This
444 * defines the coordinate space for <var>startX</var> and <var>startY</var>.
445 * @param thumbnail The bitmap that will be shown as the initial thumbnail
446 * of the animation.
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700447 * @param startX The x starting location of the bitmap, relative to <var>source</var>.
448 * @param startY The y starting location of the bitmap, relative to <var>source</var>.
Dianne Hackborn9944ecd2012-04-10 15:54:19 -0700449 * @return Returns a new ActivityOptions object that you can use to
450 * supply these options as the options Bundle when starting an activity.
451 */
452 public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
453 Bitmap thumbnail, int startX, int startY) {
454 return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, null);
455 }
456
457 /**
458 * Create an ActivityOptions specifying an animation where a thumbnail
459 * is scaled from a given position to the new activity window that is
460 * being started.
461 *
462 * @param source The View that this thumbnail is animating from. This
463 * defines the coordinate space for <var>startX</var> and <var>startY</var>.
464 * @param thumbnail The bitmap that will be shown as the initial thumbnail
465 * of the animation.
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700466 * @param startX The x starting location of the bitmap, relative to <var>source</var>.
467 * @param startY The y starting location of the bitmap, relative to <var>source</var>.
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700468 * @param listener Optional OnAnimationStartedListener to find out when the
469 * requested animation has started running. If for some reason the animation
470 * is not executed, the callback will happen immediately.
471 * @return Returns a new ActivityOptions object that you can use to
472 * supply these options as the options Bundle when starting an activity.
Dianne Hackborn9944ecd2012-04-10 15:54:19 -0700473 * @hide
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700474 */
475 public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
476 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
Michael Jurka832cb222012-04-13 09:32:47 -0700477 return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, true);
Michael Jurka21385cd2012-05-03 10:57:31 -0700478 }
479
480 /**
Michael Jurka832cb222012-04-13 09:32:47 -0700481 * Create an ActivityOptions specifying an animation where an activity window
482 * is scaled from a given position to a thumbnail at a specified location.
Michael Jurka21385cd2012-05-03 10:57:31 -0700483 *
Michael Jurka832cb222012-04-13 09:32:47 -0700484 * @param source The View that this thumbnail is animating to. This
Michael Jurka21385cd2012-05-03 10:57:31 -0700485 * defines the coordinate space for <var>startX</var> and <var>startY</var>.
Michael Jurka832cb222012-04-13 09:32:47 -0700486 * @param thumbnail The bitmap that will be shown as the final thumbnail
Michael Jurka21385cd2012-05-03 10:57:31 -0700487 * of the animation.
Michael Jurka832cb222012-04-13 09:32:47 -0700488 * @param startX The x end location of the bitmap, relative to <var>source</var>.
489 * @param startY The y end location of the bitmap, relative to <var>source</var>.
Michael Jurka21385cd2012-05-03 10:57:31 -0700490 * @param listener Optional OnAnimationStartedListener to find out when the
491 * requested animation has started running. If for some reason the animation
492 * is not executed, the callback will happen immediately.
493 * @return Returns a new ActivityOptions object that you can use to
494 * supply these options as the options Bundle when starting an activity.
495 * @hide
496 */
Michael Jurka832cb222012-04-13 09:32:47 -0700497 public static ActivityOptions makeThumbnailScaleDownAnimation(View source,
Michael Jurka21385cd2012-05-03 10:57:31 -0700498 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
Michael Jurka832cb222012-04-13 09:32:47 -0700499 return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, false);
Michael Jurka21385cd2012-05-03 10:57:31 -0700500 }
501
Michael Jurka832cb222012-04-13 09:32:47 -0700502 private static ActivityOptions makeThumbnailAnimation(View source,
Michael Jurka21385cd2012-05-03 10:57:31 -0700503 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener,
Michael Jurka832cb222012-04-13 09:32:47 -0700504 boolean scaleUp) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700505 ActivityOptions opts = new ActivityOptions();
506 opts.mPackageName = source.getContext().getPackageName();
Michael Jurka832cb222012-04-13 09:32:47 -0700507 opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700508 opts.mThumbnail = thumbnail;
509 int[] pts = new int[2];
510 source.getLocationOnScreen(pts);
511 opts.mStartX = pts[0] + startX;
512 opts.mStartY = pts[1] + startY;
Adam Powell18e905f2013-10-24 14:27:48 -0700513 opts.setOnAnimationStartedListener(source.getHandler(), listener);
514 return opts;
515 }
516
517 /**
Winson Chunga4ccb862014-08-22 15:26:27 -0700518 * Create an ActivityOptions specifying an animation where the new activity
519 * window and a thumbnail is aspect-scaled to a new location.
520 *
521 * @param source The View that this thumbnail is animating from. This
522 * defines the coordinate space for <var>startX</var> and <var>startY</var>.
523 * @param thumbnail The bitmap that will be shown as the initial thumbnail
524 * of the animation.
525 * @param startX The x starting location of the bitmap, relative to <var>source</var>.
526 * @param startY The y starting location of the bitmap, relative to <var>source</var>.
Winson Chunge494c382014-12-17 10:12:54 -0800527 * @param handler If <var>listener</var> is non-null this must be a valid
528 * Handler on which to dispatch the callback; otherwise it should be null.
Winson Chunga4ccb862014-08-22 15:26:27 -0700529 * @param listener Optional OnAnimationStartedListener to find out when the
530 * requested animation has started running. If for some reason the animation
531 * is not executed, the callback will happen immediately.
532 * @return Returns a new ActivityOptions object that you can use to
533 * supply these options as the options Bundle when starting an activity.
534 * @hide
535 */
536 public static ActivityOptions makeThumbnailAspectScaleUpAnimation(View source,
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200537 Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight,
Winson Chunge494c382014-12-17 10:12:54 -0800538 Handler handler, OnAnimationStartedListener listener) {
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200539 return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY,
Winson Chunge494c382014-12-17 10:12:54 -0800540 targetWidth, targetHeight, handler, listener, true);
Winson Chunga4ccb862014-08-22 15:26:27 -0700541 }
542
543 /**
544 * Create an ActivityOptions specifying an animation where the new activity
545 * window and a thumbnail is aspect-scaled to a new location.
546 *
547 * @param source The View that this thumbnail is animating to. This
548 * defines the coordinate space for <var>startX</var> and <var>startY</var>.
549 * @param thumbnail The bitmap that will be shown as the final thumbnail
550 * of the animation.
551 * @param startX The x end location of the bitmap, relative to <var>source</var>.
552 * @param startY The y end location of the bitmap, relative to <var>source</var>.
Winson Chunge494c382014-12-17 10:12:54 -0800553 * @param handler If <var>listener</var> is non-null this must be a valid
554 * Handler on which to dispatch the callback; otherwise it should be null.
Winson Chunga4ccb862014-08-22 15:26:27 -0700555 * @param listener Optional OnAnimationStartedListener to find out when the
556 * requested animation has started running. If for some reason the animation
557 * is not executed, the callback will happen immediately.
558 * @return Returns a new ActivityOptions object that you can use to
559 * supply these options as the options Bundle when starting an activity.
560 * @hide
561 */
562 public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source,
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200563 Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight,
Winson Chunge494c382014-12-17 10:12:54 -0800564 Handler handler, OnAnimationStartedListener listener) {
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200565 return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY,
Winson Chunge494c382014-12-17 10:12:54 -0800566 targetWidth, targetHeight, handler, listener, false);
Winson Chunga4ccb862014-08-22 15:26:27 -0700567 }
568
569 private static ActivityOptions makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail,
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200570 int startX, int startY, int targetWidth, int targetHeight,
Winson Chunge494c382014-12-17 10:12:54 -0800571 Handler handler, OnAnimationStartedListener listener, boolean scaleUp) {
Winson Chunga4ccb862014-08-22 15:26:27 -0700572 ActivityOptions opts = new ActivityOptions();
573 opts.mPackageName = source.getContext().getPackageName();
574 opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_ASPECT_SCALE_UP :
575 ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
576 opts.mThumbnail = thumbnail;
577 int[] pts = new int[2];
578 source.getLocationOnScreen(pts);
579 opts.mStartX = pts[0] + startX;
580 opts.mStartY = pts[1] + startY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200581 opts.mWidth = targetWidth;
582 opts.mHeight = targetHeight;
Winson Chunge494c382014-12-17 10:12:54 -0800583 opts.setOnAnimationStartedListener(handler, listener);
Winson Chunga4ccb862014-08-22 15:26:27 -0700584 return opts;
585 }
586
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700587 /** @hide */
588 public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source,
589 AppTransitionAnimationSpec[] specs, Handler handler,
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700590 OnAnimationStartedListener onAnimationStartedListener,
591 OnAnimationFinishedListener onAnimationFinishedListener) {
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700592 ActivityOptions opts = new ActivityOptions();
593 opts.mPackageName = source.getContext().getPackageName();
594 opts.mAnimationType = ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
595 opts.mAnimSpecs = specs;
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700596 opts.setOnAnimationStartedListener(handler, onAnimationStartedListener);
597 opts.setOnAnimationFinishedListener(handler, onAnimationFinishedListener);
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700598 return opts;
599 }
600
Winson Chunga4ccb862014-08-22 15:26:27 -0700601 /**
George Mounte1803372014-02-26 19:00:52 +0000602 * Create an ActivityOptions to transition between Activities using cross-Activity scene
603 * animations. This method carries the position of one shared element to the started Activity.
George Mount31a21722014-03-24 17:44:36 -0700604 * The position of <code>sharedElement</code> will be used as the epicenter for the
605 * exit Transition. The position of the shared element in the launched Activity will be the
606 * epicenter of its entering Transition.
George Mount0a778ed2013-12-13 13:35:36 -0800607 *
George Mount9826f632014-09-11 08:50:09 -0700608 * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be
George Mount0a778ed2013-12-13 13:35:36 -0800609 * enabled on the calling Activity to cause an exit transition. The same must be in
610 * the called Activity to get an entering transition.</p>
George Mount62ab9b72014-05-02 13:51:17 -0700611 * @param activity The Activity whose window contains the shared elements.
George Mount0b6f3e12014-06-20 07:35:23 -0700612 * @param sharedElement The View to transition to the started Activity.
613 * @param sharedElementName The shared element name as used in the target Activity. This
614 * must not be null.
George Mounte1803372014-02-26 19:00:52 +0000615 * @return Returns a new ActivityOptions object that you can use to
616 * supply these options as the options Bundle when starting an activity.
George Mount31a21722014-03-24 17:44:36 -0700617 * @see android.transition.Transition#setEpicenterCallback(
618 * android.transition.Transition.EpicenterCallback)
Adam Powell18e905f2013-10-24 14:27:48 -0700619 */
George Mount62ab9b72014-05-02 13:51:17 -0700620 public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
George Mount31a21722014-03-24 17:44:36 -0700621 View sharedElement, String sharedElementName) {
George Mount62ab9b72014-05-02 13:51:17 -0700622 return makeSceneTransitionAnimation(activity, Pair.create(sharedElement, sharedElementName));
George Mounte1803372014-02-26 19:00:52 +0000623 }
624
625 /**
626 * Create an ActivityOptions to transition between Activities using cross-Activity scene
627 * animations. This method carries the position of multiple shared elements to the started
George Mount62ab9b72014-05-02 13:51:17 -0700628 * Activity. The position of the first element in sharedElements
George Mount31a21722014-03-24 17:44:36 -0700629 * will be used as the epicenter for the exit Transition. The position of the associated
630 * shared element in the launched Activity will be the epicenter of its entering Transition.
George Mounte1803372014-02-26 19:00:52 +0000631 *
George Mount9826f632014-09-11 08:50:09 -0700632 * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be
George Mounte1803372014-02-26 19:00:52 +0000633 * enabled on the calling Activity to cause an exit transition. The same must be in
634 * the called Activity to get an entering transition.</p>
George Mount62ab9b72014-05-02 13:51:17 -0700635 * @param activity The Activity whose window contains the shared elements.
636 * @param sharedElements The names of the shared elements to transfer to the called
637 * Activity and their associated Views. The Views must each have
638 * a unique shared element name.
George Mounte1803372014-02-26 19:00:52 +0000639 * @return Returns a new ActivityOptions object that you can use to
640 * supply these options as the options Bundle when starting an activity.
George Mount31a21722014-03-24 17:44:36 -0700641 * @see android.transition.Transition#setEpicenterCallback(
642 * android.transition.Transition.EpicenterCallback)
George Mounte1803372014-02-26 19:00:52 +0000643 */
George Mountd98f4ba2016-03-14 14:29:24 -0700644 @SafeVarargs
George Mount62ab9b72014-05-02 13:51:17 -0700645 public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
646 Pair<View, String>... sharedElements) {
Adam Powell18e905f2013-10-24 14:27:48 -0700647 ActivityOptions opts = new ActivityOptions();
George Mount413739e2016-06-08 07:13:37 -0700648 makeSceneTransitionAnimation(activity, activity.getWindow(), opts,
649 activity.mExitTransitionListener, sharedElements);
650 return opts;
651 }
652
653 /**
654 * Call this immediately prior to startActivity to begin a shared element transition
655 * from a non-Activity. The window must support Window.FEATURE_ACTIVITY_TRANSITIONS.
656 * The exit transition will start immediately and the shared element transition will
657 * start once the launched Activity's shared element is ready.
658 * <p>
659 * When all transitions have completed and the shared element has been transfered,
660 * the window's decor View will have its visibility set to View.GONE.
661 *
662 * @hide
663 */
664 @SafeVarargs
665 public static ActivityOptions startSharedElementAnimation(Window window,
666 Pair<View, String>... sharedElements) {
667 ActivityOptions opts = new ActivityOptions();
668 final View decorView = window.getDecorView();
669 if (decorView == null) {
Eino-Ville Talvala563df3b2016-06-06 22:04:54 +0000670 return opts;
George Mount04073dc2016-05-27 11:02:13 -0700671 }
George Mount413739e2016-06-08 07:13:37 -0700672 final ExitTransitionCoordinator exit =
673 makeSceneTransitionAnimation(null, window, opts, null, sharedElements);
674 if (exit != null) {
675 HideWindowListener listener = new HideWindowListener(window, exit);
676 exit.setHideSharedElementsCallback(listener);
677 exit.startExit();
678 }
679 return opts;
680 }
681
682 /**
683 * This method should be called when the {@link #startSharedElementAnimation(Window, Pair[])}
684 * animation must be stopped and the Views reset. This can happen if there was an error
685 * from startActivity or a springboard activity and the animation should stop and reset.
686 *
687 * @hide
688 */
689 public static void stopSharedElementAnimation(Window window) {
690 final View decorView = window.getDecorView();
691 if (decorView == null) {
692 return;
693 }
694 final ExitTransitionCoordinator exit = (ExitTransitionCoordinator)
695 decorView.getTag(com.android.internal.R.id.cross_task_transition);
696 if (exit != null) {
697 exit.cancelPendingTransitions();
698 decorView.setTagInternal(com.android.internal.R.id.cross_task_transition, null);
699 TransitionManager.endTransitions((ViewGroup) decorView);
700 exit.resetViews();
701 exit.clearState();
702 decorView.setVisibility(View.VISIBLE);
703 }
704 }
705
706 static ExitTransitionCoordinator makeSceneTransitionAnimation(Activity activity, Window window,
707 ActivityOptions opts, SharedElementCallback callback,
708 Pair<View, String>[] sharedElements) {
709 if (!window.hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) {
710 opts.mAnimationType = ANIM_DEFAULT;
711 return null;
712 }
Adam Powell18e905f2013-10-24 14:27:48 -0700713 opts.mAnimationType = ANIM_SCENE_TRANSITION;
George Mount62ab9b72014-05-02 13:51:17 -0700714
715 ArrayList<String> names = new ArrayList<String>();
George Mount1fecfb22014-06-18 14:55:55 -0700716 ArrayList<View> views = new ArrayList<View>();
George Mount62ab9b72014-05-02 13:51:17 -0700717
718 if (sharedElements != null) {
719 for (int i = 0; i < sharedElements.length; i++) {
720 Pair<View, String> sharedElement = sharedElements[i];
George Mountd5f9d732014-06-05 15:43:06 -0700721 String sharedElementName = sharedElement.second;
722 if (sharedElementName == null) {
723 throw new IllegalArgumentException("Shared element name must not be null");
724 }
George Mountd5f9d732014-06-05 15:43:06 -0700725 names.add(sharedElementName);
George Mount1fecfb22014-06-18 14:55:55 -0700726 View view = sharedElement.first;
727 if (view == null) {
728 throw new IllegalArgumentException("Shared element must not be null");
729 }
730 views.add(sharedElement.first);
George Mount62ab9b72014-05-02 13:51:17 -0700731 }
732 }
733
George Mount413739e2016-06-08 07:13:37 -0700734 ExitTransitionCoordinator exit = new ExitTransitionCoordinator(activity, window,
735 callback, names, names, views, false);
George Mount62ab9b72014-05-02 13:51:17 -0700736 opts.mTransitionReceiver = exit;
737 opts.mSharedElementNames = names;
George Mount413739e2016-06-08 07:13:37 -0700738 opts.mIsReturning = (activity == null);
739 if (activity == null) {
740 opts.mExitCoordinatorIndex = -1;
741 } else {
742 opts.mExitCoordinatorIndex =
743 activity.mActivityTransitionState.addExitTransitionCoordinator(exit);
744 }
745 return exit;
George Mount62ab9b72014-05-02 13:51:17 -0700746 }
747
748 /** @hide */
George Mount413739e2016-06-08 07:13:37 -0700749 static ActivityOptions makeSceneTransitionAnimation(Activity activity,
George Mount62ab9b72014-05-02 13:51:17 -0700750 ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames,
751 int resultCode, Intent resultData) {
752 ActivityOptions opts = new ActivityOptions();
753 opts.mAnimationType = ANIM_SCENE_TRANSITION;
754 opts.mSharedElementNames = sharedElementNames;
755 opts.mTransitionReceiver = exitCoordinator;
756 opts.mIsReturning = true;
757 opts.mResultCode = resultCode;
758 opts.mResultData = resultData;
George Mount1fecfb22014-06-18 14:55:55 -0700759 opts.mExitCoordinatorIndex =
760 activity.mActivityTransitionState.addExitTransitionCoordinator(exitCoordinator);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700761 return opts;
762 }
763
Craig Mautnerbb742462014-07-07 15:28:55 -0700764 /**
765 * If set along with Intent.FLAG_ACTIVITY_NEW_DOCUMENT then the task being launched will not be
766 * presented to the user but will instead be only available through the recents task list.
767 * In addition, the new task wil be affiliated with the launching activity's task.
768 * Affiliated tasks are grouped together in the recents task list.
769 *
770 * <p>This behavior is not supported for activities with {@link
771 * android.R.styleable#AndroidManifestActivity_launchMode launchMode} values of
772 * <code>singleInstance</code> or <code>singleTask</code>.
773 */
Craig Mautner3b2cd1d2014-08-25 14:25:54 -0700774 public static ActivityOptions makeTaskLaunchBehind() {
Craig Mautnerbb742462014-07-07 15:28:55 -0700775 final ActivityOptions opts = new ActivityOptions();
776 opts.mAnimationType = ANIM_LAUNCH_TASK_BEHIND;
777 return opts;
778 }
779
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700780 /**
781 * Create a basic ActivityOptions that has no special animation associated with it.
782 * Other options can still be set.
783 */
784 public static ActivityOptions makeBasic() {
785 final ActivityOptions opts = new ActivityOptions();
786 return opts;
787 }
788
Craig Mautnerbb742462014-07-07 15:28:55 -0700789 /** @hide */
790 public boolean getLaunchTaskBehind() {
791 return mAnimationType == ANIM_LAUNCH_TASK_BEHIND;
792 }
793
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700794 private ActivityOptions() {
795 }
796
797 /** @hide */
798 public ActivityOptions(Bundle opts) {
Jeff Sharkeyd136e512016-03-09 22:30:56 -0700799 // If the remote side sent us bad parcelables, they won't get the
800 // results they want, which is their loss.
801 opts.setDefusable(true);
802
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700803 mPackageName = opts.getString(KEY_PACKAGE_NAME);
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700804 try {
805 mUsageTimeReport = opts.getParcelable(KEY_USAGE_TIME_REPORT);
806 } catch (RuntimeException e) {
807 Slog.w(TAG, e);
808 }
Wale Ogunwale5122df02016-01-29 22:33:38 -0800809 mLaunchBounds = opts.getParcelable(KEY_LAUNCH_BOUNDS);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700810 mAnimationType = opts.getInt(KEY_ANIM_TYPE);
Adam Powell18e905f2013-10-24 14:27:48 -0700811 switch (mAnimationType) {
812 case ANIM_CUSTOM:
813 mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
814 mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
815 mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
816 opts.getBinder(KEY_ANIM_START_LISTENER));
817 break;
818
Winson Chung044d5292014-11-06 11:05:19 -0800819 case ANIM_CUSTOM_IN_PLACE:
820 mCustomInPlaceResId = opts.getInt(KEY_ANIM_IN_PLACE_RES_ID, 0);
821 break;
822
Adam Powell18e905f2013-10-24 14:27:48 -0700823 case ANIM_SCALE_UP:
Chet Haase10e23ab2015-02-11 15:08:38 -0800824 case ANIM_CLIP_REVEAL:
Adam Powell18e905f2013-10-24 14:27:48 -0700825 mStartX = opts.getInt(KEY_ANIM_START_X, 0);
826 mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200827 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
828 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
Adam Powell18e905f2013-10-24 14:27:48 -0700829 break;
830
831 case ANIM_THUMBNAIL_SCALE_UP:
832 case ANIM_THUMBNAIL_SCALE_DOWN:
Winson Chunga4ccb862014-08-22 15:26:27 -0700833 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
834 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
835 mThumbnail = (Bitmap) opts.getParcelable(KEY_ANIM_THUMBNAIL);
Adam Powell18e905f2013-10-24 14:27:48 -0700836 mStartX = opts.getInt(KEY_ANIM_START_X, 0);
837 mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200838 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
839 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
Adam Powell18e905f2013-10-24 14:27:48 -0700840 mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
841 opts.getBinder(KEY_ANIM_START_LISTENER));
842 break;
843
844 case ANIM_SCENE_TRANSITION:
George Mount62ab9b72014-05-02 13:51:17 -0700845 mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER);
846 mIsReturning = opts.getBoolean(KEY_TRANSITION_IS_RETURNING, false);
847 mSharedElementNames = opts.getStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS);
George Mount62ab9b72014-05-02 13:51:17 -0700848 mResultData = opts.getParcelable(KEY_RESULT_DATA);
849 mResultCode = opts.getInt(KEY_RESULT_CODE);
George Mount1fecfb22014-06-18 14:55:55 -0700850 mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX);
Adam Powell18e905f2013-10-24 14:27:48 -0700851 break;
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700852 }
Wale Ogunwale854809c2015-12-27 16:18:19 -0800853 mLaunchStackId = opts.getInt(KEY_LAUNCH_STACK_ID, INVALID_STACK_ID);
Jorim Jaggi2adba072016-03-03 13:43:39 +0100854 mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1);
Wale Ogunwale3b232392016-05-13 15:37:13 -0700855 mTaskOverlay = opts.getBoolean(KEY_TASK_OVERLAY, false);
Filip Gruszczynski90186c62015-10-26 14:07:00 -0700856 mDockCreateMode = opts.getInt(KEY_DOCK_CREATE_MODE, DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT);
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -0700857 if (opts.containsKey(KEY_ANIM_SPECS)) {
858 Parcelable[] specs = opts.getParcelableArray(KEY_ANIM_SPECS);
859 mAnimSpecs = new AppTransitionAnimationSpec[specs.length];
860 for (int i = specs.length - 1; i >= 0; i--) {
861 mAnimSpecs[i] = (AppTransitionAnimationSpec) specs[i];
862 }
863 }
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700864 if (opts.containsKey(KEY_ANIMATION_FINISHED_LISTENER)) {
865 mAnimationFinishedListener = IRemoteCallback.Stub.asInterface(
866 opts.getBinder(KEY_ANIMATION_FINISHED_LISTENER));
867 }
Robert Carrfd10cd12016-06-29 16:41:50 -0700868 mRotationAnimationHint = opts.getInt(KEY_ROTATION_ANIMATION_HINT);
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700869 }
870
Wale Ogunwale7a8fa602015-11-18 15:56:57 -0800871 /**
Wale Ogunwale5122df02016-01-29 22:33:38 -0800872 * Sets the bounds (window size) that the activity should be launched in.
Andrii Kulian8f1701d2016-03-10 21:56:35 -0800873 * Rect position should be provided in pixels and in screen coordinates.
Wale Ogunwale5122df02016-01-29 22:33:38 -0800874 * Set to null explicitly for fullscreen.
875 * <p>
876 * <strong>NOTE:<strong/> This value is ignored on devices that don't have
877 * {@link android.content.pm.PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT} or
878 * {@link android.content.pm.PackageManager#FEATURE_PICTURE_IN_PICTURE} enabled.
Andrii Kulian8f1701d2016-03-10 21:56:35 -0800879 * @param screenSpacePixelRect Launch bounds to use for the activity or null for fullscreen.
Wale Ogunwale7a8fa602015-11-18 15:56:57 -0800880 */
Andrii Kulian8f1701d2016-03-10 21:56:35 -0800881 public ActivityOptions setLaunchBounds(@Nullable Rect screenSpacePixelRect) {
882 mLaunchBounds = screenSpacePixelRect != null ? new Rect(screenSpacePixelRect) : null;
Chong Zhang0fa656b2015-08-31 15:17:21 -0700883 return this;
884 }
885
886 /** @hide */
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700887 public String getPackageName() {
888 return mPackageName;
889 }
890
Wale Ogunwale5122df02016-01-29 22:33:38 -0800891 /**
892 * Returns the bounds that should be used to launch the activity.
893 * @see #setLaunchBounds(Rect)
894 * @return Bounds used to launch the activity.
895 */
896 @Nullable
897 public Rect getLaunchBounds() {
Wale Ogunwale7a8fa602015-11-18 15:56:57 -0800898 return mLaunchBounds;
Chong Zhang0fa656b2015-08-31 15:17:21 -0700899 }
900
901 /** @hide */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700902 public int getAnimationType() {
903 return mAnimationType;
Dianne Hackborn6de01a92012-03-19 19:07:40 -0700904 }
905
906 /** @hide */
907 public int getCustomEnterResId() {
908 return mCustomEnterResId;
909 }
910
911 /** @hide */
912 public int getCustomExitResId() {
913 return mCustomExitResId;
914 }
915
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700916 /** @hide */
Winson Chung044d5292014-11-06 11:05:19 -0800917 public int getCustomInPlaceResId() {
918 return mCustomInPlaceResId;
919 }
920
921 /** @hide */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700922 public Bitmap getThumbnail() {
923 return mThumbnail;
924 }
925
926 /** @hide */
927 public int getStartX() {
928 return mStartX;
929 }
930
931 /** @hide */
932 public int getStartY() {
933 return mStartY;
934 }
935
936 /** @hide */
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200937 public int getWidth() {
938 return mWidth;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700939 }
940
941 /** @hide */
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200942 public int getHeight() {
943 return mHeight;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700944 }
945
946 /** @hide */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700947 public IRemoteCallback getOnAnimationStartListener() {
948 return mAnimationStartedListener;
949 }
950
951 /** @hide */
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700952 public IRemoteCallback getAnimationFinishedListener() {
953 return mAnimationFinishedListener;
954 }
955
956 /** @hide */
George Mount1fecfb22014-06-18 14:55:55 -0700957 public int getExitCoordinatorKey() { return mExitCoordinatorIndex; }
George Mounte1803372014-02-26 19:00:52 +0000958
959 /** @hide */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700960 public void abort() {
961 if (mAnimationStartedListener != null) {
962 try {
963 mAnimationStartedListener.sendResult(null);
964 } catch (RemoteException e) {
965 }
966 }
967 }
968
969 /** @hide */
George Mount62ab9b72014-05-02 13:51:17 -0700970 public boolean isReturning() {
971 return mIsReturning;
972 }
973
George Mount413739e2016-06-08 07:13:37 -0700974 /**
975 * Returns whether or not the ActivityOptions was created with
976 * {@link #startSharedElementAnimation(Window, Pair[])}.
977 *
978 * @hide
979 */
980 boolean isCrossTask() {
981 return mExitCoordinatorIndex < 0;
982 }
983
George Mount62ab9b72014-05-02 13:51:17 -0700984 /** @hide */
985 public ArrayList<String> getSharedElementNames() {
986 return mSharedElementNames;
987 }
988
989 /** @hide */
George Mount62ab9b72014-05-02 13:51:17 -0700990 public ResultReceiver getResultReceiver() { return mTransitionReceiver; }
991
992 /** @hide */
993 public int getResultCode() { return mResultCode; }
994
995 /** @hide */
996 public Intent getResultData() { return mResultData; }
997
998 /** @hide */
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700999 public PendingIntent getUsageTimeReport() {
1000 return mUsageTimeReport;
1001 }
1002
1003 /** @hide */
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -07001004 public AppTransitionAnimationSpec[] getAnimSpecs() { return mAnimSpecs; }
1005
1006 /** @hide */
Chong Zhang280d3322015-11-03 17:27:26 -08001007 public static ActivityOptions fromBundle(Bundle bOptions) {
1008 return bOptions != null ? new ActivityOptions(bOptions) : null;
1009 }
1010
1011 /** @hide */
1012 public static void abort(ActivityOptions options) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001013 if (options != null) {
Chong Zhang280d3322015-11-03 17:27:26 -08001014 options.abort();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001015 }
1016 }
1017
Filip Gruszczynski90186c62015-10-26 14:07:00 -07001018 /** @hide */
Wale Ogunwale854809c2015-12-27 16:18:19 -08001019 public int getLaunchStackId() {
1020 return mLaunchStackId;
1021 }
1022
1023 /** @hide */
Vladislav Kaznacheevacf147e2016-05-05 09:32:27 -07001024 @TestApi
Wale Ogunwale854809c2015-12-27 16:18:19 -08001025 public void setLaunchStackId(int launchStackId) {
1026 mLaunchStackId = launchStackId;
1027 }
1028
Jorim Jaggi2adba072016-03-03 13:43:39 +01001029 /**
1030 * Sets the task the activity will be launched in.
1031 * @hide
1032 */
1033 public void setLaunchTaskId(int taskId) {
1034 mLaunchTaskId = taskId;
1035 }
1036
1037 /**
1038 * @hide
1039 */
1040 public int getLaunchTaskId() {
1041 return mLaunchTaskId;
1042 }
1043
Jorim Jaggic875ae72016-04-26 22:41:06 -07001044 /**
Wale Ogunwale3b232392016-05-13 15:37:13 -07001045 * Set's whether the activity launched with this option should be a task overlay. That is the
1046 * activity will always be the top activity of the task and doesn't cause the task to be moved
1047 * to the front when it is added.
Jorim Jaggic875ae72016-04-26 22:41:06 -07001048 * @hide
1049 */
Wale Ogunwale3b232392016-05-13 15:37:13 -07001050 public void setTaskOverlay(boolean taskOverlay) {
1051 mTaskOverlay = taskOverlay;
Jorim Jaggic875ae72016-04-26 22:41:06 -07001052 }
1053
1054 /**
1055 * @hide
1056 */
Wale Ogunwale3b232392016-05-13 15:37:13 -07001057 public boolean getTaskOverlay() {
1058 return mTaskOverlay;
Jorim Jaggic875ae72016-04-26 22:41:06 -07001059 }
1060
Wale Ogunwale854809c2015-12-27 16:18:19 -08001061 /** @hide */
1062 public int getDockCreateMode() {
1063 return mDockCreateMode;
1064 }
Filip Gruszczynski90186c62015-10-26 14:07:00 -07001065
1066 /** @hide */
1067 public void setDockCreateMode(int dockCreateMode) {
1068 mDockCreateMode = dockCreateMode;
1069 }
1070
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001071 /**
Dianne Hackbornddc52a82012-05-03 19:40:12 -07001072 * Update the current values in this ActivityOptions from those supplied
1073 * in <var>otherOptions</var>. Any values
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001074 * defined in <var>otherOptions</var> replace those in the base options.
1075 */
Dianne Hackbornddc52a82012-05-03 19:40:12 -07001076 public void update(ActivityOptions otherOptions) {
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001077 if (otherOptions.mPackageName != null) {
1078 mPackageName = otherOptions.mPackageName;
1079 }
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07001080 mUsageTimeReport = otherOptions.mUsageTimeReport;
George Mount62ab9b72014-05-02 13:51:17 -07001081 mTransitionReceiver = null;
1082 mSharedElementNames = null;
George Mount62ab9b72014-05-02 13:51:17 -07001083 mIsReturning = false;
1084 mResultData = null;
1085 mResultCode = 0;
George Mount1fecfb22014-06-18 14:55:55 -07001086 mExitCoordinatorIndex = 0;
George Mount00dde0b2014-07-01 15:27:07 -07001087 mAnimationType = otherOptions.mAnimationType;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001088 switch (otherOptions.mAnimationType) {
1089 case ANIM_CUSTOM:
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001090 mCustomEnterResId = otherOptions.mCustomEnterResId;
1091 mCustomExitResId = otherOptions.mCustomExitResId;
1092 mThumbnail = null;
Adam Powell18e905f2013-10-24 14:27:48 -07001093 if (mAnimationStartedListener != null) {
Dianne Hackborn84375872012-06-01 19:03:50 -07001094 try {
Adam Powell18e905f2013-10-24 14:27:48 -07001095 mAnimationStartedListener.sendResult(null);
Dianne Hackborn84375872012-06-01 19:03:50 -07001096 } catch (RemoteException e) {
1097 }
1098 }
1099 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001100 break;
Winson Chung044d5292014-11-06 11:05:19 -08001101 case ANIM_CUSTOM_IN_PLACE:
1102 mCustomInPlaceResId = otherOptions.mCustomInPlaceResId;
1103 break;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001104 case ANIM_SCALE_UP:
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001105 mStartX = otherOptions.mStartX;
1106 mStartY = otherOptions.mStartY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001107 mWidth = otherOptions.mWidth;
1108 mHeight = otherOptions.mHeight;
Adam Powell18e905f2013-10-24 14:27:48 -07001109 if (mAnimationStartedListener != null) {
Dianne Hackborn84375872012-06-01 19:03:50 -07001110 try {
Adam Powell18e905f2013-10-24 14:27:48 -07001111 mAnimationStartedListener.sendResult(null);
Dianne Hackborn84375872012-06-01 19:03:50 -07001112 } catch (RemoteException e) {
1113 }
1114 }
1115 mAnimationStartedListener = null;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001116 break;
Michael Jurka832cb222012-04-13 09:32:47 -07001117 case ANIM_THUMBNAIL_SCALE_UP:
1118 case ANIM_THUMBNAIL_SCALE_DOWN:
Winson Chunga4ccb862014-08-22 15:26:27 -07001119 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
1120 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001121 mThumbnail = otherOptions.mThumbnail;
1122 mStartX = otherOptions.mStartX;
1123 mStartY = otherOptions.mStartY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001124 mWidth = otherOptions.mWidth;
1125 mHeight = otherOptions.mHeight;
Adam Powell18e905f2013-10-24 14:27:48 -07001126 if (mAnimationStartedListener != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001127 try {
Adam Powell18e905f2013-10-24 14:27:48 -07001128 mAnimationStartedListener.sendResult(null);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001129 } catch (RemoteException e) {
1130 }
1131 }
1132 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
Adam Powell18e905f2013-10-24 14:27:48 -07001133 break;
1134 case ANIM_SCENE_TRANSITION:
George Mount62ab9b72014-05-02 13:51:17 -07001135 mTransitionReceiver = otherOptions.mTransitionReceiver;
1136 mSharedElementNames = otherOptions.mSharedElementNames;
George Mount62ab9b72014-05-02 13:51:17 -07001137 mIsReturning = otherOptions.mIsReturning;
Adam Powellcfbe9be2013-11-06 14:58:58 -08001138 mThumbnail = null;
Adam Powell18e905f2013-10-24 14:27:48 -07001139 mAnimationStartedListener = null;
George Mount62ab9b72014-05-02 13:51:17 -07001140 mResultData = otherOptions.mResultData;
1141 mResultCode = otherOptions.mResultCode;
George Mount1fecfb22014-06-18 14:55:55 -07001142 mExitCoordinatorIndex = otherOptions.mExitCoordinatorIndex;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001143 break;
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001144 }
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -07001145 mAnimSpecs = otherOptions.mAnimSpecs;
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -07001146 mAnimationFinishedListener = otherOptions.mAnimationFinishedListener;
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001147 }
1148
1149 /**
1150 * Returns the created options as a Bundle, which can be passed to
1151 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
1152 * Context.startActivity(Intent, Bundle)} and related methods.
1153 * Note that the returned Bundle is still owned by the ActivityOptions
1154 * object; you must not modify it, but can supply it to the startActivity
1155 * methods that take an options Bundle.
1156 */
1157 public Bundle toBundle() {
George Mount0b6f3e12014-06-20 07:35:23 -07001158 if (mAnimationType == ANIM_DEFAULT) {
1159 return null;
1160 }
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001161 Bundle b = new Bundle();
1162 if (mPackageName != null) {
1163 b.putString(KEY_PACKAGE_NAME, mPackageName);
1164 }
Wale Ogunwale5122df02016-01-29 22:33:38 -08001165 if (mLaunchBounds != null) {
Wale Ogunwale7a8fa602015-11-18 15:56:57 -08001166 b.putParcelable(KEY_LAUNCH_BOUNDS, mLaunchBounds);
Chong Zhang0fa656b2015-08-31 15:17:21 -07001167 }
Craig Mautnerbb742462014-07-07 15:28:55 -07001168 b.putInt(KEY_ANIM_TYPE, mAnimationType);
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07001169 if (mUsageTimeReport != null) {
1170 b.putParcelable(KEY_USAGE_TIME_REPORT, mUsageTimeReport);
1171 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001172 switch (mAnimationType) {
1173 case ANIM_CUSTOM:
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001174 b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
1175 b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
Adam Powellcfbe9be2013-11-06 14:58:58 -08001176 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
Dianne Hackborn84375872012-06-01 19:03:50 -07001177 != null ? mAnimationStartedListener.asBinder() : null);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001178 break;
Winson Chung044d5292014-11-06 11:05:19 -08001179 case ANIM_CUSTOM_IN_PLACE:
1180 b.putInt(KEY_ANIM_IN_PLACE_RES_ID, mCustomInPlaceResId);
1181 break;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001182 case ANIM_SCALE_UP:
Chet Haase10e23ab2015-02-11 15:08:38 -08001183 case ANIM_CLIP_REVEAL:
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001184 b.putInt(KEY_ANIM_START_X, mStartX);
1185 b.putInt(KEY_ANIM_START_Y, mStartY);
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001186 b.putInt(KEY_ANIM_WIDTH, mWidth);
1187 b.putInt(KEY_ANIM_HEIGHT, mHeight);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001188 break;
Michael Jurka832cb222012-04-13 09:32:47 -07001189 case ANIM_THUMBNAIL_SCALE_UP:
1190 case ANIM_THUMBNAIL_SCALE_DOWN:
Winson Chunga4ccb862014-08-22 15:26:27 -07001191 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
1192 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001193 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
1194 b.putInt(KEY_ANIM_START_X, mStartX);
1195 b.putInt(KEY_ANIM_START_Y, mStartY);
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001196 b.putInt(KEY_ANIM_WIDTH, mWidth);
1197 b.putInt(KEY_ANIM_HEIGHT, mHeight);
Adam Powellcfbe9be2013-11-06 14:58:58 -08001198 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001199 != null ? mAnimationStartedListener.asBinder() : null);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07001200 break;
Adam Powellcfbe9be2013-11-06 14:58:58 -08001201 case ANIM_SCENE_TRANSITION:
George Mount62ab9b72014-05-02 13:51:17 -07001202 if (mTransitionReceiver != null) {
1203 b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionReceiver);
George Mount0a778ed2013-12-13 13:35:36 -08001204 }
George Mount62ab9b72014-05-02 13:51:17 -07001205 b.putBoolean(KEY_TRANSITION_IS_RETURNING, mIsReturning);
1206 b.putStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS, mSharedElementNames);
George Mount62ab9b72014-05-02 13:51:17 -07001207 b.putParcelable(KEY_RESULT_DATA, mResultData);
1208 b.putInt(KEY_RESULT_CODE, mResultCode);
George Mount1fecfb22014-06-18 14:55:55 -07001209 b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
Adam Powellcfbe9be2013-11-06 14:58:58 -08001210 break;
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001211 }
Wale Ogunwale854809c2015-12-27 16:18:19 -08001212 b.putInt(KEY_LAUNCH_STACK_ID, mLaunchStackId);
Jorim Jaggi2adba072016-03-03 13:43:39 +01001213 b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId);
Wale Ogunwale3b232392016-05-13 15:37:13 -07001214 b.putBoolean(KEY_TASK_OVERLAY, mTaskOverlay);
Filip Gruszczynski90186c62015-10-26 14:07:00 -07001215 b.putInt(KEY_DOCK_CREATE_MODE, mDockCreateMode);
Filip Gruszczynskid64ef3e2015-10-27 17:58:02 -07001216 if (mAnimSpecs != null) {
1217 b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs);
1218 }
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -07001219 if (mAnimationFinishedListener != null) {
1220 b.putBinder(KEY_ANIMATION_FINISHED_LISTENER, mAnimationFinishedListener.asBinder());
1221 }
Robert Carrfd10cd12016-06-29 16:41:50 -07001222 b.putInt(KEY_ROTATION_ANIMATION_HINT, mRotationAnimationHint);
Craig Mautnerbb742462014-07-07 15:28:55 -07001223
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001224 return b;
1225 }
Adam Powellcfbe9be2013-11-06 14:58:58 -08001226
1227 /**
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07001228 * Ask the the system track that time the user spends in the app being launched, and
1229 * report it back once done. The report will be sent to the given receiver, with
Dianne Hackborn67ba2c72015-06-05 14:23:38 -07001230 * the extras {@link #EXTRA_USAGE_TIME_REPORT} and {@link #EXTRA_USAGE_TIME_REPORT_PACKAGES}
Dianne Hackbornb5a380d2015-05-20 18:18:46 -07001231 * filled in.
1232 *
1233 * <p>The time interval tracked is from launching this activity until the user leaves
1234 * that activity's flow. They are considered to stay in the flow as long as
1235 * new activities are being launched or returned to from the original flow,
1236 * even if this crosses package or task boundaries. For example, if the originator
1237 * starts an activity to view an image, and while there the user selects to share,
1238 * which launches their email app in a new task, and they complete the share, the
1239 * time during that entire operation will be included until they finally hit back from
1240 * the original image viewer activity.</p>
1241 *
1242 * <p>The user is considered to complete a flow once they switch to another
1243 * activity that is not part of the tracked flow. This may happen, for example, by
1244 * using the notification shade, launcher, or recents to launch or switch to another
1245 * app. Simply going in to these navigation elements does not break the flow (although
1246 * the launcher and recents stops time tracking of the session); it is the act of
1247 * going somewhere else that completes the tracking.</p>
1248 *
1249 * @param receiver A broadcast receiver that willl receive the report.
1250 */
1251 public void requestUsageTimeReport(PendingIntent receiver) {
1252 mUsageTimeReport = receiver;
1253 }
1254
1255 /**
Adam Powellcfbe9be2013-11-06 14:58:58 -08001256 * Return the filtered options only meant to be seen by the target activity itself
1257 * @hide
1258 */
1259 public ActivityOptions forTargetActivity() {
1260 if (mAnimationType == ANIM_SCENE_TRANSITION) {
1261 final ActivityOptions result = new ActivityOptions();
1262 result.update(this);
1263 return result;
1264 }
1265
1266 return null;
1267 }
George Mount0a778ed2013-12-13 13:35:36 -08001268
Robert Carrfd10cd12016-06-29 16:41:50 -07001269 /**
1270 * Returns the rotation animation set by {@link setRotationAnimationHint} or -1
1271 * if unspecified.
1272 * @hide
1273 */
1274 public int getRotationAnimationHint() {
1275 return mRotationAnimationHint;
1276 }
1277
1278
1279 /**
1280 * Set a rotation animation to be used if launching the activity
1281 * triggers an orientation change, or -1 to clear. See
1282 * {@link android.view.WindowManager.LayoutParams} for rotation
1283 * animation values.
1284 * @hide
1285 */
1286 public void setRotationAnimationHint(int hint) {
1287 mRotationAnimationHint = hint;
1288 }
1289
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -08001290 /** @hide */
1291 @Override
1292 public String toString() {
1293 return "ActivityOptions(" + hashCode() + "), mPackageName=" + mPackageName
1294 + ", mAnimationType=" + mAnimationType + ", mStartX=" + mStartX + ", mStartY="
1295 + mStartY + ", mWidth=" + mWidth + ", mHeight=" + mHeight;
1296 }
George Mount413739e2016-06-08 07:13:37 -07001297
1298 private static class HideWindowListener extends Transition.TransitionListenerAdapter
1299 implements ExitTransitionCoordinator.HideSharedElementsCallback {
1300 private final Window mWindow;
1301 private final ExitTransitionCoordinator mExit;
1302 private final boolean mWaitingForTransition;
1303 private boolean mTransitionEnded;
1304 private boolean mSharedElementHidden;
1305 private ArrayList<View> mSharedElements;
1306
1307 public HideWindowListener(Window window, ExitTransitionCoordinator exit) {
1308 mWindow = window;
1309 mExit = exit;
1310 mSharedElements = new ArrayList<>(exit.mSharedElements);
1311 Transition transition = mWindow.getExitTransition();
1312 if (transition != null) {
1313 transition.addListener(this);
1314 mWaitingForTransition = true;
1315 } else {
1316 mWaitingForTransition = false;
1317 }
1318 View decorView = mWindow.getDecorView();
1319 if (decorView != null) {
1320 if (decorView.getTag(com.android.internal.R.id.cross_task_transition) != null) {
1321 throw new IllegalStateException(
1322 "Cannot start a transition while one is running");
1323 }
1324 decorView.setTagInternal(com.android.internal.R.id.cross_task_transition, exit);
1325 }
1326 }
1327
1328 @Override
1329 public void onTransitionEnd(Transition transition) {
1330 mTransitionEnded = true;
1331 hideWhenDone();
1332 transition.removeListener(this);
1333 }
1334
1335 @Override
1336 public void hideSharedElements() {
1337 mSharedElementHidden = true;
1338 hideWhenDone();
1339 }
1340
1341 private void hideWhenDone() {
1342 if (mSharedElementHidden && (!mWaitingForTransition || mTransitionEnded)) {
1343 mExit.resetViews();
1344 int numSharedElements = mSharedElements.size();
1345 for (int i = 0; i < numSharedElements; i++) {
1346 View view = mSharedElements.get(i);
1347 view.requestLayout();
1348 }
1349 View decorView = mWindow.getDecorView();
1350 if (decorView != null) {
1351 decorView.setTagInternal(
1352 com.android.internal.R.id.cross_task_transition, null);
1353 decorView.setVisibility(View.GONE);
1354 }
1355 }
1356 }
1357 }
Dianne Hackborn6de01a92012-03-19 19:07:40 -07001358}