blob: 7b2306128b7b5aadbb4f73b34d306471c1557e5d [file] [log] [blame]
Tyler Gunn7c668b92014-06-27 14:38:28 -07001/*
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
Tyler Gunnef9f6f92014-09-12 22:16:17 -070017package android.telecom;
Tyler Gunn7c668b92014-06-27 14:38:28 -070018
Tyler Gunn48d02102016-01-08 13:20:25 -080019import android.annotation.IntDef;
Mathew Inwood42346d12018-08-01 11:33:05 +010020import android.annotation.UnsupportedAppUsage;
Tyler Gunn7c668b92014-06-27 14:38:28 -070021import android.os.Parcel;
22import android.os.Parcelable;
23
Tyler Gunn48d02102016-01-08 13:20:25 -080024import java.lang.annotation.Retention;
25import java.lang.annotation.RetentionPolicy;
26
Tyler Gunn7c668b92014-06-27 14:38:28 -070027/**
28 * Represents attributes of video calls.
29 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070030public class VideoProfile implements Parcelable {
Tyler Gunn48d02102016-01-08 13:20:25 -080031
32 /** @hide */
33 @Retention(RetentionPolicy.SOURCE)
34 @IntDef({QUALITY_UNKNOWN, QUALITY_HIGH, QUALITY_MEDIUM, QUALITY_LOW, QUALITY_DEFAULT})
35 public @interface VideoQuality {}
36
Tyler Gunn7c668b92014-06-27 14:38:28 -070037 /**
Rekha Kumar07366812015-03-24 16:42:31 -070038 * "Unknown" video quality.
39 * @hide
40 */
41 public static final int QUALITY_UNKNOWN = 0;
42 /**
Tyler Gunn7c668b92014-06-27 14:38:28 -070043 * "High" video quality.
44 */
45 public static final int QUALITY_HIGH = 1;
46
47 /**
48 * "Medium" video quality.
49 */
50 public static final int QUALITY_MEDIUM = 2;
51
52 /**
53 * "Low" video quality.
54 */
55 public static final int QUALITY_LOW = 3;
56
57 /**
58 * Use default video quality.
59 */
60 public static final int QUALITY_DEFAULT = 4;
61
Tyler Gunn48d02102016-01-08 13:20:25 -080062 /** @hide */
63 @Retention(RetentionPolicy.SOURCE)
64 @IntDef(
65 flag = true,
Tyler Gunn9d127732018-03-02 15:45:51 -080066 prefix = { "STATE_" },
Tyler Gunn48d02102016-01-08 13:20:25 -080067 value = {STATE_AUDIO_ONLY, STATE_TX_ENABLED, STATE_RX_ENABLED, STATE_BIDIRECTIONAL,
68 STATE_PAUSED})
69 public @interface VideoState {}
70
Yorke Lee32f24732015-05-12 16:18:03 -070071 /**
Tyler Gunnbc6f12e2015-06-09 14:34:11 -070072 * Used when answering or dialing a call to indicate that the call does not have a video
73 * component.
74 * <p>
75 * Should <b>not</b> be used in comparison checks to determine if a video state represents an
76 * audio-only call.
77 * <p>
78 * The following, for example, is not the correct way to check if a call is audio-only:
79 * <pre>
80 * {@code
81 * // This is the incorrect way to check for an audio-only call.
82 * if (videoState == VideoProfile.STATE_AUDIO_ONLY) {
83 * // Handle audio-only call.
84 * }
85 * }
86 * </pre>
87 * <p>
88 * Instead, use the {@link VideoProfile#isAudioOnly(int)} helper function to check if a
89 * video state represents an audio-only call:
90 * <pre>
91 * {@code
92 * // This is the correct way to check for an audio-only call.
93 * if (VideoProfile.isAudioOnly(videoState)) {
94 * // Handle audio-only call.
95 * }
96 * }
97 * </pre>
Yorke Lee32f24732015-05-12 16:18:03 -070098 */
99 public static final int STATE_AUDIO_ONLY = 0x0;
100
101 /**
102 * Video transmission is enabled.
103 */
104 public static final int STATE_TX_ENABLED = 0x1;
105
106 /**
107 * Video reception is enabled.
108 */
109 public static final int STATE_RX_ENABLED = 0x2;
110
111 /**
112 * Video signal is bi-directional.
113 */
114 public static final int STATE_BIDIRECTIONAL = STATE_TX_ENABLED | STATE_RX_ENABLED;
115
116 /**
117 * Video is paused.
118 */
119 public static final int STATE_PAUSED = 0x4;
120
Tyler Gunn7c668b92014-06-27 14:38:28 -0700121 private final int mVideoState;
122
123 private final int mQuality;
124
125 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700126 * Creates an instance of the VideoProfile
Tyler Gunn7c668b92014-06-27 14:38:28 -0700127 *
128 * @param videoState The video state.
Andrew Lee055e5a22014-07-21 12:14:11 -0700129 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800130 public VideoProfile(@VideoState int videoState) {
Andrew Lee055e5a22014-07-21 12:14:11 -0700131 this(videoState, QUALITY_DEFAULT);
132 }
133
134 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700135 * Creates an instance of the VideoProfile
Andrew Lee055e5a22014-07-21 12:14:11 -0700136 *
137 * @param videoState The video state.
Tyler Gunn7c668b92014-06-27 14:38:28 -0700138 * @param quality The video quality.
139 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800140 public VideoProfile(@VideoState int videoState, @VideoQuality int quality) {
Tyler Gunn7c668b92014-06-27 14:38:28 -0700141 mVideoState = videoState;
142 mQuality = quality;
143 }
144
145 /**
Andrew Lee48332d62014-07-28 14:04:20 -0700146 * The video state of the call.
Yorke Lee32f24732015-05-12 16:18:03 -0700147 * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
148 * {@link VideoProfile#STATE_BIDIRECTIONAL},
149 * {@link VideoProfile#STATE_TX_ENABLED},
150 * {@link VideoProfile#STATE_RX_ENABLED},
151 * {@link VideoProfile#STATE_PAUSED}.
Tyler Gunn7c668b92014-06-27 14:38:28 -0700152 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800153 @VideoState
Tyler Gunn7c668b92014-06-27 14:38:28 -0700154 public int getVideoState() {
155 return mVideoState;
156 }
157
158 /**
159 * The desired video quality for the call.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700160 * Valid values: {@link VideoProfile#QUALITY_HIGH}, {@link VideoProfile#QUALITY_MEDIUM},
161 * {@link VideoProfile#QUALITY_LOW}, {@link VideoProfile#QUALITY_DEFAULT}.
Tyler Gunn7c668b92014-06-27 14:38:28 -0700162 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800163 @VideoQuality
Tyler Gunn7c668b92014-06-27 14:38:28 -0700164 public int getQuality() {
165 return mQuality;
166 }
167
168 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700169 * Responsible for creating VideoProfile objects from deserialized Parcels.
Tyler Gunn7c668b92014-06-27 14:38:28 -0700170 **/
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700171 public static final Parcelable.Creator<VideoProfile> CREATOR =
172 new Parcelable.Creator<VideoProfile> () {
Tyler Gunn7c668b92014-06-27 14:38:28 -0700173 /**
174 * Creates a MediaProfile instances from a parcel.
175 *
176 * @param source The parcel.
177 * @return The MediaProfile.
178 */
179 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700180 public VideoProfile createFromParcel(Parcel source) {
Tyler Gunn7c668b92014-06-27 14:38:28 -0700181 int state = source.readInt();
182 int quality = source.readInt();
183
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700184 ClassLoader classLoader = VideoProfile.class.getClassLoader();
185 return new VideoProfile(state, quality);
Tyler Gunn7c668b92014-06-27 14:38:28 -0700186 }
187
188 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700189 public VideoProfile[] newArray(int size) {
190 return new VideoProfile[size];
Tyler Gunn7c668b92014-06-27 14:38:28 -0700191 }
192 };
193
194 /**
195 * Describe the kinds of special objects contained in this Parcelable's
196 * marshalled representation.
197 *
198 * @return a bitmask indicating the set of special object types marshalled
199 * by the Parcelable.
200 */
201 @Override
202 public int describeContents() {
203 return 0;
204 }
205
206 /**
207 * Flatten this object in to a Parcel.
208 *
209 * @param dest The Parcel in which the object should be written.
210 * @param flags Additional flags about how the object should be written.
211 * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
212 */
213 @Override
214 public void writeToParcel(Parcel dest, int flags) {
215 dest.writeInt(mVideoState);
216 dest.writeInt(mQuality);
217 }
Andrew Lee48332d62014-07-28 14:04:20 -0700218
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700219 @Override
220 public String toString() {
221 StringBuilder sb = new StringBuilder();
222 sb.append("[VideoProfile videoState = ");
Tyler Gunn87b73f32015-06-03 10:09:59 -0700223 sb.append(videoStateToString(mVideoState));
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700224 sb.append(" videoQuality = ");
225 sb.append(mQuality);
226 sb.append("]");
227 return sb.toString();
228 }
229
Andrew Lee48332d62014-07-28 14:04:20 -0700230 /**
Tyler Gunn87b73f32015-06-03 10:09:59 -0700231 * Generates a string representation of a video state.
232 *
233 * @param videoState The video state.
234 * @return String representation of the video state.
235 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800236 public static String videoStateToString(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700237 StringBuilder sb = new StringBuilder();
238 sb.append("Audio");
Andrew Lee48332d62014-07-28 14:04:20 -0700239
Tyler Gunn1aee66f2017-02-21 15:19:43 -0800240 if (videoState == STATE_AUDIO_ONLY) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700241 sb.append(" Only");
242 } else {
243 if (isTransmissionEnabled(videoState)) {
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700244 sb.append(" Tx");
245 }
246
Tyler Gunn87b73f32015-06-03 10:09:59 -0700247 if (isReceptionEnabled(videoState)) {
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700248 sb.append(" Rx");
249 }
250
Tyler Gunn87b73f32015-06-03 10:09:59 -0700251 if (isPaused(videoState)) {
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700252 sb.append(" Pause");
253 }
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700254 }
Tyler Gunn87b73f32015-06-03 10:09:59 -0700255
256 return sb.toString();
257 }
258
259 /**
260 * Indicates whether the video state is audio only.
Tyler Gunn1aee66f2017-02-21 15:19:43 -0800261 * <p>
262 * Note: Considers only whether either both the {@link #STATE_RX_ENABLED} or
263 * {@link #STATE_TX_ENABLED} bits are off, but not {@link #STATE_PAUSED}.
Tyler Gunn87b73f32015-06-03 10:09:59 -0700264 *
265 * @param videoState The video state.
266 * @return {@code True} if the video state is audio only, {@code false} otherwise.
267 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800268 public static boolean isAudioOnly(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700269 return !hasState(videoState, VideoProfile.STATE_TX_ENABLED)
270 && !hasState(videoState, VideoProfile.STATE_RX_ENABLED);
271 }
272
273 /**
274 * Indicates whether video transmission or reception is enabled for a video state.
275 *
276 * @param videoState The video state.
277 * @return {@code True} if video transmission or reception is enabled, {@code false} otherwise.
278 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800279 public static boolean isVideo(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700280 return hasState(videoState, VideoProfile.STATE_TX_ENABLED)
281 || hasState(videoState, VideoProfile.STATE_RX_ENABLED)
282 || hasState(videoState, VideoProfile.STATE_BIDIRECTIONAL);
283 }
284
285 /**
286 * Indicates whether the video state has video transmission enabled.
287 *
288 * @param videoState The video state.
289 * @return {@code True} if video transmission is enabled, {@code false} otherwise.
290 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800291 public static boolean isTransmissionEnabled(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700292 return hasState(videoState, VideoProfile.STATE_TX_ENABLED);
293 }
294
295 /**
296 * Indicates whether the video state has video reception enabled.
297 *
298 * @param videoState The video state.
299 * @return {@code True} if video reception is enabled, {@code false} otherwise.
300 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800301 public static boolean isReceptionEnabled(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700302 return hasState(videoState, VideoProfile.STATE_RX_ENABLED);
303 }
304
305 /**
306 * Indicates whether the video state is bi-directional.
307 *
308 * @param videoState The video state.
309 * @return {@code True} if the video is bi-directional, {@code false} otherwise.
310 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800311 public static boolean isBidirectional(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700312 return hasState(videoState, VideoProfile.STATE_BIDIRECTIONAL);
313 }
314
315 /**
316 * Indicates whether the video state is paused.
317 *
318 * @param videoState The video state.
319 * @return {@code True} if the video is paused, {@code false} otherwise.
320 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800321 public static boolean isPaused(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700322 return hasState(videoState, VideoProfile.STATE_PAUSED);
323 }
324
325 /**
326 * Indicates if a specified state is set in a videoState bit-mask.
327 *
328 * @param videoState The video state bit-mask.
329 * @param state The state to check.
330 * @return {@code True} if the state is set.
331 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800332 private static boolean hasState(@VideoState int videoState, @VideoState int state) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700333 return (videoState & state) == state;
Andrew Lee48332d62014-07-28 14:04:20 -0700334 }
Yorke Lee400470f2015-05-12 13:31:25 -0700335
336 /**
337 * Represents the camera capabilities important to a Video Telephony provider.
338 */
339 public static final class CameraCapabilities implements Parcelable {
340
341 /**
342 * The width of the camera video in pixels.
343 */
344 private final int mWidth;
345
346 /**
347 * The height of the camera video in pixels.
348 */
349 private final int mHeight;
350
351 /**
352 * Whether the camera supports zoom.
353 */
354 private final boolean mZoomSupported;
355
356 /**
357 * The maximum zoom supported by the camera.
358 */
359 private final float mMaxZoom;
360
361 /**
362 * Create a call camera capabilities instance.
363 *
364 * @param width The width of the camera video (in pixels).
365 * @param height The height of the camera video (in pixels).
366 */
367 public CameraCapabilities(int width, int height) {
368 this(width, height, false, 1.0f);
369 }
370
371 /**
chen xu055b1de2018-12-13 19:15:06 -0800372 * Create a call camera capabilities instance that optionally supports zoom.
Yorke Lee400470f2015-05-12 13:31:25 -0700373 *
374 * @param width The width of the camera video (in pixels).
375 * @param height The height of the camera video (in pixels).
376 * @param zoomSupported True when camera supports zoom.
377 * @param maxZoom Maximum zoom supported by camera.
Yorke Lee400470f2015-05-12 13:31:25 -0700378 */
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
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
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 */
443 public int getWidth() {
444 return mWidth;
445 }
446
447 /**
448 * The height of the camera video in pixels.
449 */
450 public int getHeight() {
451 return mHeight;
452 }
453
454 /**
chen xu055b1de2018-12-13 19:15:06 -0800455 * Returns {@code true} is zoom is supported, {@code false} otherwise.
Yorke Lee400470f2015-05-12 13:31:25 -0700456 */
457 public boolean isZoomSupported() {
458 return mZoomSupported;
459 }
460
461 /**
chen xu055b1de2018-12-13 19:15:06 -0800462 * Returns the maximum zoom supported by the camera.
Yorke Lee400470f2015-05-12 13:31:25 -0700463 */
464 public float getMaxZoom() {
465 return mMaxZoom;
466 }
467 }
468
Tyler Gunn7c668b92014-06-27 14:38:28 -0700469}