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