• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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.telecom;
18 
19 import android.annotation.FloatRange;
20 import android.annotation.IntDef;
21 import android.annotation.IntRange;
22 import android.annotation.UnsupportedAppUsage;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 
26 import java.lang.annotation.Retention;
27 import java.lang.annotation.RetentionPolicy;
28 
29 /**
30  * Represents attributes of video calls.
31  */
32 public class VideoProfile implements Parcelable {
33 
34     /** @hide */
35     @Retention(RetentionPolicy.SOURCE)
36     @IntDef({QUALITY_UNKNOWN, QUALITY_HIGH, QUALITY_MEDIUM, QUALITY_LOW, QUALITY_DEFAULT})
37     public @interface VideoQuality {}
38 
39     /**
40      * "Unknown" video quality.
41      * @hide
42      */
43     public static final int QUALITY_UNKNOWN = 0;
44     /**
45      * "High" video quality.
46      */
47     public static final int QUALITY_HIGH = 1;
48 
49     /**
50      * "Medium" video quality.
51      */
52     public static final int QUALITY_MEDIUM = 2;
53 
54     /**
55      * "Low" video quality.
56      */
57     public static final int QUALITY_LOW = 3;
58 
59     /**
60      * Use default video quality.
61      */
62     public static final int QUALITY_DEFAULT = 4;
63 
64     /** @hide */
65     @Retention(RetentionPolicy.SOURCE)
66     @IntDef(
67             flag = true,
68             prefix = { "STATE_" },
69             value = {STATE_AUDIO_ONLY, STATE_TX_ENABLED, STATE_RX_ENABLED, STATE_BIDIRECTIONAL,
70                     STATE_PAUSED})
71     public @interface VideoState {}
72 
73     /**
74      * Used when answering or dialing a call to indicate that the call does not have a video
75      * component.
76      * <p>
77      * Should <b>not</b> be used in comparison checks to determine if a video state represents an
78      * audio-only call.
79      * <p>
80      * The following, for example, is not the correct way to check if a call is audio-only:
81      * <pre>
82      * {@code
83      * // This is the incorrect way to check for an audio-only call.
84      * if (videoState == VideoProfile.STATE_AUDIO_ONLY) {
85      *      // Handle audio-only call.
86      * }
87      * }
88      * </pre>
89      * <p>
90      * Instead, use the {@link VideoProfile#isAudioOnly(int)} helper function to check if a
91      * video state represents an audio-only call:
92      * <pre>
93      * {@code
94      * // This is the correct way to check for an audio-only call.
95      * if (VideoProfile.isAudioOnly(videoState)) {
96      *      // Handle audio-only call.
97      * }
98      * }
99      * </pre>
100      */
101     public static final int STATE_AUDIO_ONLY = 0x0;
102 
103     /**
104      * Video transmission is enabled.
105      */
106     public static final int STATE_TX_ENABLED = 0x1;
107 
108     /**
109      * Video reception is enabled.
110      */
111     public static final int STATE_RX_ENABLED = 0x2;
112 
113     /**
114      * Video signal is bi-directional.
115      */
116     public static final int STATE_BIDIRECTIONAL = STATE_TX_ENABLED | STATE_RX_ENABLED;
117 
118     /**
119      * Video is paused.
120      */
121     public static final int STATE_PAUSED = 0x4;
122 
123     private final int mVideoState;
124 
125     private final int mQuality;
126 
127     /**
128      * Creates an instance of the VideoProfile
129      *
130      * @param videoState The video state.
131      */
VideoProfile(@ideoState int videoState)132     public VideoProfile(@VideoState int videoState) {
133         this(videoState, QUALITY_DEFAULT);
134     }
135 
136     /**
137      * Creates an instance of the VideoProfile
138      *
139      * @param videoState The video state.
140      * @param quality The video quality.
141      */
VideoProfile(@ideoState int videoState, @VideoQuality int quality)142     public VideoProfile(@VideoState int videoState, @VideoQuality int quality) {
143         mVideoState = videoState;
144         mQuality = quality;
145     }
146 
147     /**
148      * The video state of the call.
149      * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
150      * {@link VideoProfile#STATE_BIDIRECTIONAL},
151      * {@link VideoProfile#STATE_TX_ENABLED},
152      * {@link VideoProfile#STATE_RX_ENABLED},
153      * {@link VideoProfile#STATE_PAUSED}.
154      */
155     @VideoState
getVideoState()156     public int getVideoState() {
157         return mVideoState;
158     }
159 
160     /**
161      * The desired video quality for the call.
162      * Valid values: {@link VideoProfile#QUALITY_HIGH}, {@link VideoProfile#QUALITY_MEDIUM},
163      * {@link VideoProfile#QUALITY_LOW}, {@link VideoProfile#QUALITY_DEFAULT}.
164      */
165     @VideoQuality
getQuality()166     public int getQuality() {
167         return mQuality;
168     }
169 
170     /**
171      * Responsible for creating VideoProfile objects from deserialized Parcels.
172      **/
173     public static final @android.annotation.NonNull Parcelable.Creator<VideoProfile> CREATOR =
174             new Parcelable.Creator<VideoProfile> () {
175                 /**
176                  * Creates a MediaProfile instances from a parcel.
177                  *
178                  * @param source The parcel.
179                  * @return The MediaProfile.
180                  */
181                 @Override
182                 public VideoProfile createFromParcel(Parcel source) {
183                     int state = source.readInt();
184                     int quality = source.readInt();
185 
186                     ClassLoader classLoader = VideoProfile.class.getClassLoader();
187                     return new VideoProfile(state, quality);
188                 }
189 
190                 @Override
191                 public VideoProfile[] newArray(int size) {
192                     return new VideoProfile[size];
193                 }
194             };
195 
196     /**
197      * Describe the kinds of special objects contained in this Parcelable's
198      * marshalled representation.
199      *
200      * @return a bitmask indicating the set of special object types marshalled
201      * by the Parcelable.
202      */
203     @Override
describeContents()204     public int describeContents() {
205         return 0;
206     }
207 
208     /**
209      * Flatten this object in to a Parcel.
210      *
211      * @param dest  The Parcel in which the object should be written.
212      * @param flags Additional flags about how the object should be written.
213      *              May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
214      */
215     @Override
writeToParcel(Parcel dest, int flags)216     public void writeToParcel(Parcel dest, int flags) {
217         dest.writeInt(mVideoState);
218         dest.writeInt(mQuality);
219     }
220 
221     @Override
toString()222     public String toString() {
223         StringBuilder sb = new StringBuilder();
224         sb.append("[VideoProfile videoState = ");
225         sb.append(videoStateToString(mVideoState));
226         sb.append(" videoQuality = ");
227         sb.append(mQuality);
228         sb.append("]");
229         return sb.toString();
230     }
231 
232     /**
233      * Generates a string representation of a video state.
234      *
235      * @param videoState The video state.
236      * @return String representation of the video state.
237      */
videoStateToString(@ideoState int videoState)238     public static String videoStateToString(@VideoState int videoState) {
239         StringBuilder sb = new StringBuilder();
240         sb.append("Audio");
241 
242         if (videoState == STATE_AUDIO_ONLY) {
243             sb.append(" Only");
244         } else {
245             if (isTransmissionEnabled(videoState)) {
246                 sb.append(" Tx");
247             }
248 
249             if (isReceptionEnabled(videoState)) {
250                 sb.append(" Rx");
251             }
252 
253             if (isPaused(videoState)) {
254                 sb.append(" Pause");
255             }
256         }
257 
258         return sb.toString();
259     }
260 
261     /**
262      * Indicates whether the video state is audio only.
263      * <p>
264      * Note: Considers only whether either both the {@link #STATE_RX_ENABLED} or
265      * {@link #STATE_TX_ENABLED} bits are off, but not {@link #STATE_PAUSED}.
266      *
267      * @param videoState The video state.
268      * @return {@code True} if the video state is audio only, {@code false} otherwise.
269      */
isAudioOnly(@ideoState int videoState)270     public static boolean isAudioOnly(@VideoState int videoState) {
271         return !hasState(videoState, VideoProfile.STATE_TX_ENABLED)
272                 && !hasState(videoState, VideoProfile.STATE_RX_ENABLED);
273     }
274 
275     /**
276      * Indicates whether video transmission or reception is enabled for a video state.
277      *
278      * @param videoState The video state.
279      * @return {@code True} if video transmission or reception is enabled, {@code false} otherwise.
280      */
isVideo(@ideoState int videoState)281     public static boolean isVideo(@VideoState int videoState) {
282         return hasState(videoState, VideoProfile.STATE_TX_ENABLED)
283                 || hasState(videoState, VideoProfile.STATE_RX_ENABLED)
284                 || hasState(videoState, VideoProfile.STATE_BIDIRECTIONAL);
285     }
286 
287     /**
288      * Indicates whether the video state has video transmission enabled.
289      *
290      * @param videoState The video state.
291      * @return {@code True} if video transmission is enabled, {@code false} otherwise.
292      */
isTransmissionEnabled(@ideoState int videoState)293     public static boolean isTransmissionEnabled(@VideoState int videoState) {
294         return hasState(videoState, VideoProfile.STATE_TX_ENABLED);
295     }
296 
297     /**
298      * Indicates whether the video state has video reception enabled.
299      *
300      * @param videoState The video state.
301      * @return {@code True} if video reception is enabled, {@code false} otherwise.
302      */
isReceptionEnabled(@ideoState int videoState)303     public static boolean isReceptionEnabled(@VideoState int videoState) {
304         return hasState(videoState, VideoProfile.STATE_RX_ENABLED);
305     }
306 
307     /**
308      * Indicates whether the video state is bi-directional.
309      *
310      * @param videoState The video state.
311      * @return {@code True} if the video is bi-directional, {@code false} otherwise.
312      */
isBidirectional(@ideoState int videoState)313     public static boolean isBidirectional(@VideoState int videoState) {
314         return hasState(videoState, VideoProfile.STATE_BIDIRECTIONAL);
315     }
316 
317     /**
318      * Indicates whether the video state is paused.
319      *
320      * @param videoState The video state.
321      * @return {@code True} if the video is paused, {@code false} otherwise.
322      */
isPaused(@ideoState int videoState)323     public static boolean isPaused(@VideoState int videoState) {
324         return hasState(videoState, VideoProfile.STATE_PAUSED);
325     }
326 
327     /**
328      * Indicates if a specified state is set in a videoState bit-mask.
329      *
330      * @param videoState The video state bit-mask.
331      * @param state The state to check.
332      * @return {@code True} if the state is set.
333      */
hasState(@ideoState int videoState, @VideoState int state)334     private static boolean hasState(@VideoState int videoState, @VideoState int state) {
335         return (videoState & state) == state;
336     }
337 
338     /**
339      * Represents the camera capabilities important to a Video Telephony provider.
340      */
341     public static final class CameraCapabilities implements Parcelable {
342 
343         /**
344          * The width of the camera video in pixels.
345          */
346         private final int mWidth;
347 
348         /**
349          * The height of the camera video in pixels.
350          */
351         private final int mHeight;
352 
353         /**
354          * Whether the camera supports zoom.
355          */
356         private final boolean mZoomSupported;
357 
358         /**
359          * The maximum zoom supported by the camera.
360          */
361         private final float mMaxZoom;
362 
363         /**
364          * Create a call camera capabilities instance.
365          *
366          * @param width The width of the camera video (in pixels).
367          * @param height The height of the camera video (in pixels).
368          */
CameraCapabilities(@ntRangefrom = 0) int width, @IntRange(from = 0) int height)369         public CameraCapabilities(@IntRange(from = 0) int width, @IntRange(from = 0) int height) {
370             this(width, height, false, 1.0f);
371         }
372 
373         /**
374          * Create a call camera capabilities instance that optionally supports zoom.
375          *
376          * @param width The width of the camera video (in pixels).
377          * @param height The height of the camera video (in pixels).
378          * @param zoomSupported True when camera supports zoom.
379          * @param maxZoom Maximum zoom supported by camera.
380          */
CameraCapabilities(@ntRangefrom = 0) int width, @IntRange(from = 0) int height, boolean zoomSupported, @FloatRange(from = 1.0f) float maxZoom)381         public CameraCapabilities(@IntRange(from = 0) int width,  @IntRange(from = 0) int height,
382                                    boolean zoomSupported,  @FloatRange(from = 1.0f) float maxZoom) {
383             mWidth = width;
384             mHeight = height;
385             mZoomSupported = zoomSupported;
386             mMaxZoom = maxZoom;
387         }
388 
389         /**
390          * Responsible for creating CallCameraCapabilities objects from deserialized Parcels.
391          **/
392         public static final @android.annotation.NonNull Parcelable.Creator<CameraCapabilities> CREATOR =
393                 new Parcelable.Creator<CameraCapabilities> () {
394                     /**
395                      * Creates a CallCameraCapabilities instances from a parcel.
396                      *
397                      * @param source The parcel.
398                      * @return The CallCameraCapabilities.
399                      */
400                     @Override
401                     public CameraCapabilities createFromParcel(Parcel source) {
402                         int width = source.readInt();
403                         int height = source.readInt();
404                         boolean supportsZoom = source.readByte() != 0;
405                         float maxZoom = source.readFloat();
406 
407                         return new CameraCapabilities(width, height, supportsZoom, maxZoom);
408                     }
409 
410                     @Override
411                     public CameraCapabilities[] newArray(int size) {
412                         return new CameraCapabilities[size];
413                     }
414                 };
415 
416         /**
417          * Describe the kinds of special objects contained in this Parcelable's
418          * marshalled representation.
419          *
420          * @return a bitmask indicating the set of special object types marshalled
421          * by the Parcelable.
422          */
423         @Override
describeContents()424         public int describeContents() {
425             return 0;
426         }
427 
428         /**
429          * Flatten this object in to a Parcel.
430          *
431          * @param dest  The Parcel in which the object should be written.
432          * @param flags Additional flags about how the object should be written.
433          *              May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
434          */
435         @Override
writeToParcel(Parcel dest, int flags)436         public void writeToParcel(Parcel dest, int flags) {
437             dest.writeInt(getWidth());
438             dest.writeInt(getHeight());
439             dest.writeByte((byte) (isZoomSupported() ? 1 : 0));
440             dest.writeFloat(getMaxZoom());
441         }
442 
443         /**
444          * The width of the camera video in pixels.
445          */
getWidth()446         public int getWidth() {
447             return mWidth;
448         }
449 
450         /**
451          * The height of the camera video in pixels.
452          */
getHeight()453         public int getHeight() {
454             return mHeight;
455         }
456 
457         /**
458          * Returns {@code true} is zoom is supported, {@code false} otherwise.
459          */
isZoomSupported()460         public boolean isZoomSupported() {
461             return mZoomSupported;
462         }
463 
464         /**
465          * Returns the maximum zoom supported by the camera.
466          */
getMaxZoom()467         public float getMaxZoom() {
468             return mMaxZoom;
469         }
470     }
471 
472 }
473