blob: bfd966c575a9e1ef019b62c35fa86c93a332eb0a [file] [log] [blame]
Winson Chung709904f2017-04-25 11:00:48 -07001/*
2 * Copyright (C) 2017 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
19import android.annotation.Nullable;
Winson Chung37b99ba2018-06-28 15:42:06 -070020import android.annotation.TestApi;
Winson Chung709904f2017-04-25 11:00:48 -070021import android.graphics.Rect;
22import android.os.Parcel;
23import android.os.Parcelable;
24import android.util.Rational;
25
26import java.util.ArrayList;
27import java.util.List;
28
29/**
30 * Represents a set of parameters used to initialize and update an Activity in picture-in-picture
31 * mode.
Winson Chung709904f2017-04-25 11:00:48 -070032 */
Jeff Sharkey000ce802017-04-29 13:13:27 -060033public final class PictureInPictureParams implements Parcelable {
Winson Chung709904f2017-04-25 11:00:48 -070034
35 /**
36 * Builder class for {@link PictureInPictureParams} objects.
37 */
38 public static class Builder {
39
40 @Nullable
41 private Rational mAspectRatio;
42
43 @Nullable
44 private List<RemoteAction> mUserActions;
45
46 @Nullable
47 private Rect mSourceRectHint;
48
49 /**
50 * Sets the aspect ratio. This aspect ratio is defined as the desired width / height, and
51 * does not change upon device rotation.
52 *
53 * @param aspectRatio the new aspect ratio for the activity in picture-in-picture, must be
54 * between 2.39:1 and 1:2.39 (inclusive).
55 *
56 * @return this builder instance.
57 */
58 public Builder setAspectRatio(Rational aspectRatio) {
59 mAspectRatio = aspectRatio;
60 return this;
61 }
62
63 /**
64 * Sets the user actions. If there are more than
Jeff Sharkey000ce802017-04-29 13:13:27 -060065 * {@link Activity#getMaxNumPictureInPictureActions()} actions, then the input list
Winson Chung709904f2017-04-25 11:00:48 -070066 * will be truncated to that number.
67 *
68 * @param actions the new actions to show in the picture-in-picture menu.
69 *
70 * @return this builder instance.
71 *
72 * @see RemoteAction
73 */
74 public Builder setActions(List<RemoteAction> actions) {
75 if (mUserActions != null) {
76 mUserActions = null;
77 }
78 if (actions != null) {
79 mUserActions = new ArrayList<>(actions);
80 }
81 return this;
82 }
83
84 /**
85 * Sets the source bounds hint. These bounds are only used when an activity first enters
86 * picture-in-picture, and describe the bounds in window coordinates of activity entering
87 * picture-in-picture that will be visible following the transition. For the best effect,
88 * these bounds should also match the aspect ratio in the arguments.
89 *
90 * @param launchBounds window-coordinate bounds indicating the area of the activity that
91 * will still be visible following the transition into picture-in-picture (eg. the video
92 * view bounds in a video player)
93 *
94 * @return this builder instance.
95 */
96 public Builder setSourceRectHint(Rect launchBounds) {
97 if (launchBounds == null) {
98 mSourceRectHint = null;
99 } else {
100 mSourceRectHint = new Rect(launchBounds);
101 }
102 return this;
103 }
104
105 /**
106 * @return an immutable {@link PictureInPictureParams} to be used when entering or updating
107 * the activity in picture-in-picture.
108 *
109 * @see Activity#enterPictureInPictureMode(PictureInPictureParams)
110 * @see Activity#setPictureInPictureParams(PictureInPictureParams)
111 */
112 public PictureInPictureParams build() {
113 PictureInPictureParams params = new PictureInPictureParams(mAspectRatio, mUserActions,
114 mSourceRectHint);
115 return params;
116 }
117 }
118
119 /**
120 * The expected aspect ratio of the picture-in-picture.
121 */
Winson Chung709904f2017-04-25 11:00:48 -0700122 @Nullable
Jeff Sharkey000ce802017-04-29 13:13:27 -0600123 private Rational mAspectRatio;
Winson Chung709904f2017-04-25 11:00:48 -0700124
125 /**
126 * The set of actions that are associated with this activity when in picture-in-picture.
127 */
Winson Chung709904f2017-04-25 11:00:48 -0700128 @Nullable
Jeff Sharkey000ce802017-04-29 13:13:27 -0600129 private List<RemoteAction> mUserActions;
Winson Chung709904f2017-04-25 11:00:48 -0700130
131 /**
132 * The source bounds hint used when entering picture-in-picture, relative to the window bounds.
133 * We can use this internally for the transition into picture-in-picture to ensure that a
134 * particular source rect is visible throughout the whole transition.
135 */
Winson Chung709904f2017-04-25 11:00:48 -0700136 @Nullable
Jeff Sharkey000ce802017-04-29 13:13:27 -0600137 private Rect mSourceRectHint;
Winson Chung709904f2017-04-25 11:00:48 -0700138
Jeff Sharkey000ce802017-04-29 13:13:27 -0600139 /** {@hide} */
Winson Chung709904f2017-04-25 11:00:48 -0700140 PictureInPictureParams() {
Winson Chung709904f2017-04-25 11:00:48 -0700141 }
142
Jeff Sharkey000ce802017-04-29 13:13:27 -0600143 /** {@hide} */
144 PictureInPictureParams(Parcel in) {
Winson Chung709904f2017-04-25 11:00:48 -0700145 if (in.readInt() != 0) {
146 mAspectRatio = new Rational(in.readInt(), in.readInt());
147 }
148 if (in.readInt() != 0) {
149 mUserActions = new ArrayList<>();
150 in.readParcelableList(mUserActions, RemoteAction.class.getClassLoader());
151 }
152 if (in.readInt() != 0) {
153 mSourceRectHint = Rect.CREATOR.createFromParcel(in);
154 }
Winson Chung709904f2017-04-25 11:00:48 -0700155 }
156
Jeff Sharkey000ce802017-04-29 13:13:27 -0600157 /** {@hide} */
158 PictureInPictureParams(Rational aspectRatio, List<RemoteAction> actions,
Winson Chung709904f2017-04-25 11:00:48 -0700159 Rect sourceRectHint) {
160 mAspectRatio = aspectRatio;
161 mUserActions = actions;
162 mSourceRectHint = sourceRectHint;
163 }
164
165 /**
166 * Copies the set parameters from the other picture-in-picture args.
167 * @hide
168 */
169 public void copyOnlySet(PictureInPictureParams otherArgs) {
170 if (otherArgs.hasSetAspectRatio()) {
171 mAspectRatio = otherArgs.mAspectRatio;
172 }
173 if (otherArgs.hasSetActions()) {
174 mUserActions = otherArgs.mUserActions;
175 }
176 if (otherArgs.hasSourceBoundsHint()) {
177 mSourceRectHint = new Rect(otherArgs.getSourceRectHint());
178 }
Winson Chung709904f2017-04-25 11:00:48 -0700179 }
180
181 /**
182 * @return the aspect ratio. If none is set, return 0.
183 * @hide
184 */
Winson Chung37b99ba2018-06-28 15:42:06 -0700185 @TestApi
Winson Chung709904f2017-04-25 11:00:48 -0700186 public float getAspectRatio() {
187 if (mAspectRatio != null) {
188 return mAspectRatio.floatValue();
189 }
190 return 0f;
191 }
192
Jeff Sharkey000ce802017-04-29 13:13:27 -0600193 /** @hide */
194 public Rational getAspectRatioRational() {
195 return mAspectRatio;
196 }
197
Winson Chung709904f2017-04-25 11:00:48 -0700198 /**
199 * @return whether the aspect ratio is set.
200 * @hide
201 */
202 public boolean hasSetAspectRatio() {
203 return mAspectRatio != null;
204 }
205
206 /**
207 * @return the set of user actions.
208 * @hide
209 */
Winson Chung37b99ba2018-06-28 15:42:06 -0700210 @TestApi
Winson Chung709904f2017-04-25 11:00:48 -0700211 public List<RemoteAction> getActions() {
212 return mUserActions;
213 }
214
215 /**
216 * @return whether the user actions are set.
217 * @hide
218 */
219 public boolean hasSetActions() {
220 return mUserActions != null;
221 }
222
223 /**
224 * Truncates the set of actions to the given {@param size}.
225 * @hide
226 */
227 public void truncateActions(int size) {
228 if (hasSetActions()) {
Winson Chung90853252017-04-27 17:38:13 -0700229 mUserActions = mUserActions.subList(0, Math.min(mUserActions.size(), size));
Winson Chung709904f2017-04-25 11:00:48 -0700230 }
231 }
232
233 /**
Winson Chung709904f2017-04-25 11:00:48 -0700234 * @return the source rect hint
235 * @hide
236 */
Winson Chung37b99ba2018-06-28 15:42:06 -0700237 @TestApi
Winson Chung709904f2017-04-25 11:00:48 -0700238 public Rect getSourceRectHint() {
239 return mSourceRectHint;
240 }
241
242 /**
Winson Chung709904f2017-04-25 11:00:48 -0700243 * @return whether there are launch bounds set
244 * @hide
245 */
246 public boolean hasSourceBoundsHint() {
247 return mSourceRectHint != null && !mSourceRectHint.isEmpty();
248 }
249
Winson Chung709904f2017-04-25 11:00:48 -0700250 @Override
251 public int describeContents() {
252 return 0;
253 }
254
255 @Override
256 public void writeToParcel(Parcel out, int flags) {
257 if (mAspectRatio != null) {
258 out.writeInt(1);
259 out.writeInt(mAspectRatio.getNumerator());
260 out.writeInt(mAspectRatio.getDenominator());
261 } else {
262 out.writeInt(0);
263 }
264 if (mUserActions != null) {
265 out.writeInt(1);
266 out.writeParcelableList(mUserActions, 0);
267 } else {
268 out.writeInt(0);
269 }
270 if (mSourceRectHint != null) {
271 out.writeInt(1);
272 mSourceRectHint.writeToParcel(out, 0);
273 } else {
274 out.writeInt(0);
275 }
Winson Chung709904f2017-04-25 11:00:48 -0700276 }
277
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700278 public static final @android.annotation.NonNull Creator<PictureInPictureParams> CREATOR =
Winson Chung709904f2017-04-25 11:00:48 -0700279 new Creator<PictureInPictureParams>() {
280 public PictureInPictureParams createFromParcel(Parcel in) {
281 return new PictureInPictureParams(in);
282 }
283 public PictureInPictureParams[] newArray(int size) {
284 return new PictureInPictureParams[size];
285 }
286 };
Robert Carr18f622f2017-05-08 11:20:43 -0700287}