1 /*
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 
17 package android.app;
18 
19 import android.annotation.Nullable;
20 import android.graphics.Rect;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.util.Rational;
24 
25 import java.util.ArrayList;
26 import java.util.List;
27 
28 /** @removed */
29 @Deprecated
30 public final class PictureInPictureArgs implements Parcelable {
31 
32     /**
33      * Builder class for {@link PictureInPictureArgs} objects.
34      */
35     public static class Builder {
36 
37         @Nullable
38         private Rational mAspectRatio;
39 
40         @Nullable
41         private List<RemoteAction> mUserActions;
42 
43         @Nullable
44         private Rect mSourceRectHint;
45 
46         /**
47          * Sets the aspect ratio.  This aspect ratio is defined as the desired width / height, and
48          * does not change upon device rotation.
49          *
50          * @param aspectRatio the new aspect ratio for the activity in picture-in-picture, must be
51          * between 2.39:1 and 1:2.39 (inclusive).
52          *
53          * @return this builder instance.
54          */
setAspectRatio(Rational aspectRatio)55         public Builder setAspectRatio(Rational aspectRatio) {
56             mAspectRatio = aspectRatio;
57             return this;
58         }
59 
60         /**
61          * Sets the user actions.  If there are more than
62          * {@link Activity#getMaxNumPictureInPictureActions()} actions, then the input list
63          * will be truncated to that number.
64          *
65          * @param actions the new actions to show in the picture-in-picture menu.
66          *
67          * @return this builder instance.
68          *
69          * @see RemoteAction
70          */
setActions(List<RemoteAction> actions)71         public Builder setActions(List<RemoteAction> actions) {
72             if (mUserActions != null) {
73                 mUserActions = null;
74             }
75             if (actions != null) {
76                 mUserActions = new ArrayList<>(actions);
77             }
78             return this;
79         }
80 
81         /**
82          * Sets the source bounds hint. These bounds are only used when an activity first enters
83          * picture-in-picture, and describe the bounds in window coordinates of activity entering
84          * picture-in-picture that will be visible following the transition. For the best effect,
85          * these bounds should also match the aspect ratio in the arguments.
86          *
87          * @param launchBounds window-coordinate bounds indicating the area of the activity that
88          * will still be visible following the transition into picture-in-picture (eg. the video
89          * view bounds in a video player)
90          *
91          * @return this builder instance.
92          */
setSourceRectHint(Rect launchBounds)93         public Builder setSourceRectHint(Rect launchBounds) {
94             if (launchBounds == null) {
95                 mSourceRectHint = null;
96             } else {
97                 mSourceRectHint = new Rect(launchBounds);
98             }
99             return this;
100         }
101 
build()102         public PictureInPictureArgs build() {
103             PictureInPictureArgs args = new PictureInPictureArgs(mAspectRatio, mUserActions,
104                     mSourceRectHint);
105             return args;
106         }
107     }
108 
109     /**
110      * The expected aspect ratio of the picture-in-picture.
111      */
112     @Nullable
113     private Rational mAspectRatio;
114 
115     /**
116      * The set of actions that are associated with this activity when in picture-in-picture.
117      */
118     @Nullable
119     private List<RemoteAction> mUserActions;
120 
121     /**
122      * The source bounds hint used when entering picture-in-picture, relative to the window bounds.
123      * We can use this internally for the transition into picture-in-picture to ensure that a
124      * particular source rect is visible throughout the whole transition.
125      */
126     @Nullable
127     private Rect mSourceRectHint;
128 
129     /**
130      * The content insets that are used with the source hint rect for the transition into PiP where
131      * the insets are removed at the beginning of the transition.
132      */
133     @Nullable
134     private Rect mSourceRectHintInsets;
135 
136     /**
137      * @hide
138      */
139     @Deprecated
PictureInPictureArgs()140     public PictureInPictureArgs() {
141     }
142 
143     /**
144      * @hide
145      */
146     @Deprecated
PictureInPictureArgs(float aspectRatio, List<RemoteAction> actions)147     public PictureInPictureArgs(float aspectRatio, List<RemoteAction> actions) {
148         setAspectRatio(aspectRatio);
149         setActions(actions);
150     }
151 
PictureInPictureArgs(Parcel in)152     private PictureInPictureArgs(Parcel in) {
153         if (in.readInt() != 0) {
154             mAspectRatio = new Rational(in.readInt(), in.readInt());
155         }
156         if (in.readInt() != 0) {
157             mUserActions = new ArrayList<>();
158             in.readParcelableList(mUserActions, RemoteAction.class.getClassLoader());
159         }
160         if (in.readInt() != 0) {
161             mSourceRectHint = Rect.CREATOR.createFromParcel(in);
162         }
163     }
164 
PictureInPictureArgs(Rational aspectRatio, List<RemoteAction> actions, Rect sourceRectHint)165     private PictureInPictureArgs(Rational aspectRatio, List<RemoteAction> actions,
166             Rect sourceRectHint) {
167         mAspectRatio = aspectRatio;
168         mUserActions = actions;
169         mSourceRectHint = sourceRectHint;
170     }
171 
172     /**
173      * @hide
174      */
175     @Deprecated
setAspectRatio(float aspectRatio)176     public void setAspectRatio(float aspectRatio) {
177         // Temporary workaround
178         mAspectRatio = new Rational((int) (aspectRatio * 1000000000), 1000000000);
179     }
180 
181     /**
182      * @hide
183      */
184     @Deprecated
setActions(List<RemoteAction> actions)185     public void setActions(List<RemoteAction> actions) {
186         if (mUserActions != null) {
187             mUserActions = null;
188         }
189         if (actions != null) {
190             mUserActions = new ArrayList<>(actions);
191         }
192     }
193 
194     /**
195      * @hide
196      */
197     @Deprecated
setSourceRectHint(Rect launchBounds)198     public void setSourceRectHint(Rect launchBounds) {
199         if (launchBounds == null) {
200             mSourceRectHint = null;
201         } else {
202             mSourceRectHint = new Rect(launchBounds);
203         }
204     }
205 
206     /**
207      * Copies the set parameters from the other picture-in-picture args.
208      * @hide
209      */
copyOnlySet(PictureInPictureArgs otherArgs)210     public void copyOnlySet(PictureInPictureArgs otherArgs) {
211         if (otherArgs.hasSetAspectRatio()) {
212             mAspectRatio = otherArgs.mAspectRatio;
213         }
214         if (otherArgs.hasSetActions()) {
215             mUserActions = otherArgs.mUserActions;
216         }
217         if (otherArgs.hasSourceBoundsHint()) {
218             mSourceRectHint = new Rect(otherArgs.getSourceRectHint());
219         }
220     }
221 
222     /**
223      * @return the aspect ratio. If none is set, return 0.
224      * @hide
225      */
getAspectRatio()226     public float getAspectRatio() {
227         if (mAspectRatio != null) {
228             return mAspectRatio.floatValue();
229         }
230         return 0f;
231     }
232 
233     /** {@hide} */
getAspectRatioRational()234     public Rational getAspectRatioRational() {
235         return mAspectRatio;
236     }
237 
238     /**
239      * @return whether the aspect ratio is set.
240      * @hide
241      */
hasSetAspectRatio()242     public boolean hasSetAspectRatio() {
243         return mAspectRatio != null;
244     }
245 
246     /**
247      * @return the set of user actions.
248      * @hide
249      */
getActions()250     public List<RemoteAction> getActions() {
251         return mUserActions;
252     }
253 
254     /**
255      * @return whether the user actions are set.
256      * @hide
257      */
hasSetActions()258     public boolean hasSetActions() {
259         return mUserActions != null;
260     }
261 
262     /**
263      * Truncates the set of actions to the given {@param size}.
264      * @hide
265      */
truncateActions(int size)266     public void truncateActions(int size) {
267         if (hasSetActions()) {
268             mUserActions = mUserActions.subList(0, Math.min(mUserActions.size(), size));
269         }
270     }
271 
272     /**
273      * Sets the insets to be used with the source rect hint bounds.
274      * @hide
275      */
276     @Deprecated
setSourceRectHintInsets(Rect insets)277     public void setSourceRectHintInsets(Rect insets) {
278         if (insets == null) {
279             mSourceRectHintInsets = null;
280         } else {
281             mSourceRectHintInsets = new Rect(insets);
282         }
283     }
284 
285     /**
286      * @return the source rect hint
287      * @hide
288      */
getSourceRectHint()289     public Rect getSourceRectHint() {
290         return mSourceRectHint;
291     }
292 
293     /**
294      * @return the source rect hint insets.
295      * @hide
296      */
getSourceRectHintInsets()297     public Rect getSourceRectHintInsets() {
298         return mSourceRectHintInsets;
299     }
300 
301     /**
302      * @return whether there are launch bounds set
303      * @hide
304      */
hasSourceBoundsHint()305     public boolean hasSourceBoundsHint() {
306         return mSourceRectHint != null && !mSourceRectHint.isEmpty();
307     }
308 
309     /**
310      * @return whether there are source rect hint insets set
311      * @hide
312      */
hasSourceBoundsHintInsets()313     public boolean hasSourceBoundsHintInsets() {
314         return mSourceRectHintInsets != null;
315     }
316 
317     @Override
describeContents()318     public int describeContents() {
319         return 0;
320     }
321 
322     @Override
writeToParcel(Parcel out, int flags)323     public void writeToParcel(Parcel out, int flags) {
324         if (mAspectRatio != null) {
325             out.writeInt(1);
326             out.writeInt(mAspectRatio.getNumerator());
327             out.writeInt(mAspectRatio.getDenominator());
328         } else {
329             out.writeInt(0);
330         }
331         if (mUserActions != null) {
332             out.writeInt(1);
333             out.writeParcelableList(mUserActions, 0);
334         } else {
335             out.writeInt(0);
336         }
337         if (mSourceRectHint != null) {
338             out.writeInt(1);
339             mSourceRectHint.writeToParcel(out, 0);
340         } else {
341             out.writeInt(0);
342         }
343     }
344 
345     public static final Creator<PictureInPictureArgs> CREATOR =
346             new Creator<PictureInPictureArgs>() {
347                 public PictureInPictureArgs createFromParcel(Parcel in) {
348                     return new PictureInPictureArgs(in);
349                 }
350                 public PictureInPictureArgs[] newArray(int size) {
351                     return new PictureInPictureArgs[size];
352                 }
353             };
354 
convert(PictureInPictureParams params)355     public static PictureInPictureArgs convert(PictureInPictureParams params) {
356         return new PictureInPictureArgs(params.getAspectRatioRational(), params.getActions(),
357                 params.getSourceRectHint());
358     }
359 
convert(PictureInPictureArgs args)360     public static PictureInPictureParams convert(PictureInPictureArgs args) {
361         return new PictureInPictureParams(args.getAspectRatioRational(), args.getActions(),
362                 args.getSourceRectHint());
363     }
364 }
365