• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /**
29  * Represents a set of parameters used to initialize and update an Activity in picture-in-picture
30  * mode.
31  */
32 public final class PictureInPictureParams implements Parcelable {
33 
34     /**
35      * Builder class for {@link PictureInPictureParams} objects.
36      */
37     public static class Builder {
38 
39         @Nullable
40         private Rational mAspectRatio;
41 
42         @Nullable
43         private List<RemoteAction> mUserActions;
44 
45         @Nullable
46         private Rect mSourceRectHint;
47 
48         /**
49          * Sets the aspect ratio.  This aspect ratio is defined as the desired width / height, and
50          * does not change upon device rotation.
51          *
52          * @param aspectRatio the new aspect ratio for the activity in picture-in-picture, must be
53          * between 2.39:1 and 1:2.39 (inclusive).
54          *
55          * @return this builder instance.
56          */
setAspectRatio(Rational aspectRatio)57         public Builder setAspectRatio(Rational aspectRatio) {
58             mAspectRatio = aspectRatio;
59             return this;
60         }
61 
62         /**
63          * Sets the user actions.  If there are more than
64          * {@link Activity#getMaxNumPictureInPictureActions()} actions, then the input list
65          * will be truncated to that number.
66          *
67          * @param actions the new actions to show in the picture-in-picture menu.
68          *
69          * @return this builder instance.
70          *
71          * @see RemoteAction
72          */
setActions(List<RemoteAction> actions)73         public Builder setActions(List<RemoteAction> actions) {
74             if (mUserActions != null) {
75                 mUserActions = null;
76             }
77             if (actions != null) {
78                 mUserActions = new ArrayList<>(actions);
79             }
80             return this;
81         }
82 
83         /**
84          * Sets the source bounds hint. These bounds are only used when an activity first enters
85          * picture-in-picture, and describe the bounds in window coordinates of activity entering
86          * picture-in-picture that will be visible following the transition. For the best effect,
87          * these bounds should also match the aspect ratio in the arguments.
88          *
89          * @param launchBounds window-coordinate bounds indicating the area of the activity that
90          * will still be visible following the transition into picture-in-picture (eg. the video
91          * view bounds in a video player)
92          *
93          * @return this builder instance.
94          */
setSourceRectHint(Rect launchBounds)95         public Builder setSourceRectHint(Rect launchBounds) {
96             if (launchBounds == null) {
97                 mSourceRectHint = null;
98             } else {
99                 mSourceRectHint = new Rect(launchBounds);
100             }
101             return this;
102         }
103 
104         /**
105          * @return an immutable {@link PictureInPictureParams} to be used when entering or updating
106          * the activity in picture-in-picture.
107          *
108          * @see Activity#enterPictureInPictureMode(PictureInPictureParams)
109          * @see Activity#setPictureInPictureParams(PictureInPictureParams)
110          */
build()111         public PictureInPictureParams build() {
112             PictureInPictureParams params = new PictureInPictureParams(mAspectRatio, mUserActions,
113                     mSourceRectHint);
114             return params;
115         }
116     }
117 
118     /**
119      * The expected aspect ratio of the picture-in-picture.
120      */
121     @Nullable
122     private Rational mAspectRatio;
123 
124     /**
125      * The set of actions that are associated with this activity when in picture-in-picture.
126      */
127     @Nullable
128     private List<RemoteAction> mUserActions;
129 
130     /**
131      * The source bounds hint used when entering picture-in-picture, relative to the window bounds.
132      * We can use this internally for the transition into picture-in-picture to ensure that a
133      * particular source rect is visible throughout the whole transition.
134      */
135     @Nullable
136     private Rect mSourceRectHint;
137 
138     /** {@hide} */
PictureInPictureParams()139     PictureInPictureParams() {
140     }
141 
142     /** {@hide} */
PictureInPictureParams(Parcel in)143     PictureInPictureParams(Parcel in) {
144         if (in.readInt() != 0) {
145             mAspectRatio = new Rational(in.readInt(), in.readInt());
146         }
147         if (in.readInt() != 0) {
148             mUserActions = new ArrayList<>();
149             in.readParcelableList(mUserActions, RemoteAction.class.getClassLoader());
150         }
151         if (in.readInt() != 0) {
152             mSourceRectHint = Rect.CREATOR.createFromParcel(in);
153         }
154     }
155 
156     /** {@hide} */
PictureInPictureParams(Rational aspectRatio, List<RemoteAction> actions, Rect sourceRectHint)157     PictureInPictureParams(Rational aspectRatio, List<RemoteAction> actions,
158             Rect sourceRectHint) {
159         mAspectRatio = aspectRatio;
160         mUserActions = actions;
161         mSourceRectHint = sourceRectHint;
162     }
163 
164     /**
165      * Copies the set parameters from the other picture-in-picture args.
166      * @hide
167      */
copyOnlySet(PictureInPictureParams otherArgs)168     public void copyOnlySet(PictureInPictureParams otherArgs) {
169         if (otherArgs.hasSetAspectRatio()) {
170             mAspectRatio = otherArgs.mAspectRatio;
171         }
172         if (otherArgs.hasSetActions()) {
173             mUserActions = otherArgs.mUserActions;
174         }
175         if (otherArgs.hasSourceBoundsHint()) {
176             mSourceRectHint = new Rect(otherArgs.getSourceRectHint());
177         }
178     }
179 
180     /**
181      * @return the aspect ratio. If none is set, return 0.
182      * @hide
183      */
getAspectRatio()184     public float getAspectRatio() {
185         if (mAspectRatio != null) {
186             return mAspectRatio.floatValue();
187         }
188         return 0f;
189     }
190 
191     /** @hide */
getAspectRatioRational()192     public Rational getAspectRatioRational() {
193         return mAspectRatio;
194     }
195 
196     /**
197      * @return whether the aspect ratio is set.
198      * @hide
199      */
hasSetAspectRatio()200     public boolean hasSetAspectRatio() {
201         return mAspectRatio != null;
202     }
203 
204     /**
205      * @return the set of user actions.
206      * @hide
207      */
getActions()208     public List<RemoteAction> getActions() {
209         return mUserActions;
210     }
211 
212     /**
213      * @return whether the user actions are set.
214      * @hide
215      */
hasSetActions()216     public boolean hasSetActions() {
217         return mUserActions != null;
218     }
219 
220     /**
221      * Truncates the set of actions to the given {@param size}.
222      * @hide
223      */
truncateActions(int size)224     public void truncateActions(int size) {
225         if (hasSetActions()) {
226             mUserActions = mUserActions.subList(0, Math.min(mUserActions.size(), size));
227         }
228     }
229 
230     /**
231      * @return the source rect hint
232      * @hide
233      */
getSourceRectHint()234     public Rect getSourceRectHint() {
235         return mSourceRectHint;
236     }
237 
238     /**
239      * @return whether there are launch bounds set
240      * @hide
241      */
hasSourceBoundsHint()242     public boolean hasSourceBoundsHint() {
243         return mSourceRectHint != null && !mSourceRectHint.isEmpty();
244     }
245 
246     @Override
describeContents()247     public int describeContents() {
248         return 0;
249     }
250 
251     @Override
writeToParcel(Parcel out, int flags)252     public void writeToParcel(Parcel out, int flags) {
253         if (mAspectRatio != null) {
254             out.writeInt(1);
255             out.writeInt(mAspectRatio.getNumerator());
256             out.writeInt(mAspectRatio.getDenominator());
257         } else {
258             out.writeInt(0);
259         }
260         if (mUserActions != null) {
261             out.writeInt(1);
262             out.writeParcelableList(mUserActions, 0);
263         } else {
264             out.writeInt(0);
265         }
266         if (mSourceRectHint != null) {
267             out.writeInt(1);
268             mSourceRectHint.writeToParcel(out, 0);
269         } else {
270             out.writeInt(0);
271         }
272     }
273 
274     public static final Creator<PictureInPictureParams> CREATOR =
275             new Creator<PictureInPictureParams>() {
276                 public PictureInPictureParams createFromParcel(Parcel in) {
277                     return new PictureInPictureParams(in);
278                 }
279                 public PictureInPictureParams[] newArray(int size) {
280                     return new PictureInPictureParams[size];
281                 }
282             };
283 }
284