blob: 157f12c9f105a5a943cf8e63d383b3f5d1ffe0b0 [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
chen xue0a3eb92019-01-29 13:58:29 -080019import android.annotation.FloatRange;
Tyler Gunn48d02102016-01-08 13:20:25 -080020import android.annotation.IntDef;
chen xue0a3eb92019-01-29 13:58:29 -080021import android.annotation.IntRange;
Mathew Inwood42346d12018-08-01 11:33:05 +010022import android.annotation.UnsupportedAppUsage;
Tyler Gunn7c668b92014-06-27 14:38:28 -070023import android.os.Parcel;
24import android.os.Parcelable;
25
Tyler Gunn48d02102016-01-08 13:20:25 -080026import java.lang.annotation.Retention;
27import java.lang.annotation.RetentionPolicy;
28
Tyler Gunn7c668b92014-06-27 14:38:28 -070029/**
30 * Represents attributes of video calls.
31 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070032public class VideoProfile implements Parcelable {
Tyler Gunn48d02102016-01-08 13:20:25 -080033
34 /** @hide */
35 @Retention(RetentionPolicy.SOURCE)
36 @IntDef({QUALITY_UNKNOWN, QUALITY_HIGH, QUALITY_MEDIUM, QUALITY_LOW, QUALITY_DEFAULT})
37 public @interface VideoQuality {}
38
Tyler Gunn7c668b92014-06-27 14:38:28 -070039 /**
Rekha Kumar07366812015-03-24 16:42:31 -070040 * "Unknown" video quality.
41 * @hide
42 */
43 public static final int QUALITY_UNKNOWN = 0;
44 /**
Tyler Gunn7c668b92014-06-27 14:38:28 -070045 * "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
Tyler Gunn48d02102016-01-08 13:20:25 -080064 /** @hide */
65 @Retention(RetentionPolicy.SOURCE)
66 @IntDef(
67 flag = true,
Tyler Gunn9d127732018-03-02 15:45:51 -080068 prefix = { "STATE_" },
Tyler Gunn48d02102016-01-08 13:20:25 -080069 value = {STATE_AUDIO_ONLY, STATE_TX_ENABLED, STATE_RX_ENABLED, STATE_BIDIRECTIONAL,
70 STATE_PAUSED})
71 public @interface VideoState {}
72
Yorke Lee32f24732015-05-12 16:18:03 -070073 /**
Tyler Gunnbc6f12e2015-06-09 14:34:11 -070074 * 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>
Yorke Lee32f24732015-05-12 16:18:03 -0700100 */
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
Tyler Gunn7c668b92014-06-27 14:38:28 -0700123 private final int mVideoState;
124
125 private final int mQuality;
126
127 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700128 * Creates an instance of the VideoProfile
Tyler Gunn7c668b92014-06-27 14:38:28 -0700129 *
130 * @param videoState The video state.
Andrew Lee055e5a22014-07-21 12:14:11 -0700131 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800132 public VideoProfile(@VideoState int videoState) {
Andrew Lee055e5a22014-07-21 12:14:11 -0700133 this(videoState, QUALITY_DEFAULT);
134 }
135
136 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700137 * Creates an instance of the VideoProfile
Andrew Lee055e5a22014-07-21 12:14:11 -0700138 *
139 * @param videoState The video state.
Tyler Gunn7c668b92014-06-27 14:38:28 -0700140 * @param quality The video quality.
141 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800142 public VideoProfile(@VideoState int videoState, @VideoQuality int quality) {
Tyler Gunn7c668b92014-06-27 14:38:28 -0700143 mVideoState = videoState;
144 mQuality = quality;
145 }
146
147 /**
Andrew Lee48332d62014-07-28 14:04:20 -0700148 * The video state of the call.
Yorke Lee32f24732015-05-12 16:18:03 -0700149 * 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}.
Tyler Gunn7c668b92014-06-27 14:38:28 -0700154 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800155 @VideoState
Tyler Gunn7c668b92014-06-27 14:38:28 -0700156 public int getVideoState() {
157 return mVideoState;
158 }
159
160 /**
161 * The desired video quality for the call.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700162 * Valid values: {@link VideoProfile#QUALITY_HIGH}, {@link VideoProfile#QUALITY_MEDIUM},
163 * {@link VideoProfile#QUALITY_LOW}, {@link VideoProfile#QUALITY_DEFAULT}.
Tyler Gunn7c668b92014-06-27 14:38:28 -0700164 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800165 @VideoQuality
Tyler Gunn7c668b92014-06-27 14:38:28 -0700166 public int getQuality() {
167 return mQuality;
168 }
169
170 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700171 * Responsible for creating VideoProfile objects from deserialized Parcels.
Tyler Gunn7c668b92014-06-27 14:38:28 -0700172 **/
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700173 public static final Parcelable.Creator<VideoProfile> CREATOR =
174 new Parcelable.Creator<VideoProfile> () {
Tyler Gunn7c668b92014-06-27 14:38:28 -0700175 /**
176 * Creates a MediaProfile instances from a parcel.
177 *
178 * @param source The parcel.
179 * @return The MediaProfile.
180 */
181 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700182 public VideoProfile createFromParcel(Parcel source) {
Tyler Gunn7c668b92014-06-27 14:38:28 -0700183 int state = source.readInt();
184 int quality = source.readInt();
185
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700186 ClassLoader classLoader = VideoProfile.class.getClassLoader();
187 return new VideoProfile(state, quality);
Tyler Gunn7c668b92014-06-27 14:38:28 -0700188 }
189
190 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700191 public VideoProfile[] newArray(int size) {
192 return new VideoProfile[size];
Tyler Gunn7c668b92014-06-27 14:38:28 -0700193 }
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
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
216 public void writeToParcel(Parcel dest, int flags) {
217 dest.writeInt(mVideoState);
218 dest.writeInt(mQuality);
219 }
Andrew Lee48332d62014-07-28 14:04:20 -0700220
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700221 @Override
222 public String toString() {
223 StringBuilder sb = new StringBuilder();
224 sb.append("[VideoProfile videoState = ");
Tyler Gunn87b73f32015-06-03 10:09:59 -0700225 sb.append(videoStateToString(mVideoState));
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700226 sb.append(" videoQuality = ");
227 sb.append(mQuality);
228 sb.append("]");
229 return sb.toString();
230 }
231
Andrew Lee48332d62014-07-28 14:04:20 -0700232 /**
Tyler Gunn87b73f32015-06-03 10:09:59 -0700233 * Generates a string representation of a video state.
234 *
235 * @param videoState The video state.
236 * @return String representation of the video state.
237 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800238 public static String videoStateToString(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700239 StringBuilder sb = new StringBuilder();
240 sb.append("Audio");
Andrew Lee48332d62014-07-28 14:04:20 -0700241
Tyler Gunn1aee66f2017-02-21 15:19:43 -0800242 if (videoState == STATE_AUDIO_ONLY) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700243 sb.append(" Only");
244 } else {
245 if (isTransmissionEnabled(videoState)) {
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700246 sb.append(" Tx");
247 }
248
Tyler Gunn87b73f32015-06-03 10:09:59 -0700249 if (isReceptionEnabled(videoState)) {
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700250 sb.append(" Rx");
251 }
252
Tyler Gunn87b73f32015-06-03 10:09:59 -0700253 if (isPaused(videoState)) {
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700254 sb.append(" Pause");
255 }
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700256 }
Tyler Gunn87b73f32015-06-03 10:09:59 -0700257
258 return sb.toString();
259 }
260
261 /**
262 * Indicates whether the video state is audio only.
Tyler Gunn1aee66f2017-02-21 15:19:43 -0800263 * <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}.
Tyler Gunn87b73f32015-06-03 10:09:59 -0700266 *
267 * @param videoState The video state.
268 * @return {@code True} if the video state is audio only, {@code false} otherwise.
269 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800270 public static boolean isAudioOnly(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700271 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 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800281 public static boolean isVideo(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700282 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 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800293 public static boolean isTransmissionEnabled(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700294 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 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800303 public static boolean isReceptionEnabled(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700304 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 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800313 public static boolean isBidirectional(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700314 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 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800323 public static boolean isPaused(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700324 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 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800334 private static boolean hasState(@VideoState int videoState, @VideoState int state) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700335 return (videoState & state) == state;
Andrew Lee48332d62014-07-28 14:04:20 -0700336 }
Yorke Lee400470f2015-05-12 13:31:25 -0700337
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 */
chen xue0a3eb92019-01-29 13:58:29 -0800369 public CameraCapabilities(@IntRange(from = 0) int width, @IntRange(from = 0) int height) {
Yorke Lee400470f2015-05-12 13:31:25 -0700370 this(width, height, false, 1.0f);
371 }
372
373 /**
chen xu055b1de2018-12-13 19:15:06 -0800374 * Create a call camera capabilities instance that optionally supports zoom.
Yorke Lee400470f2015-05-12 13:31:25 -0700375 *
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.
Yorke Lee400470f2015-05-12 13:31:25 -0700380 */
chen xue0a3eb92019-01-29 13:58:29 -0800381 public CameraCapabilities(@IntRange(from = 0) int width, @IntRange(from = 0) int height,
382 boolean zoomSupported, @FloatRange(from = 1.0f) float maxZoom) {
Yorke Lee400470f2015-05-12 13:31:25 -0700383 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 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
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
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 */
446 public int getWidth() {
447 return mWidth;
448 }
449
450 /**
451 * The height of the camera video in pixels.
452 */
453 public int getHeight() {
454 return mHeight;
455 }
456
457 /**
chen xu055b1de2018-12-13 19:15:06 -0800458 * Returns {@code true} is zoom is supported, {@code false} otherwise.
Yorke Lee400470f2015-05-12 13:31:25 -0700459 */
460 public boolean isZoomSupported() {
461 return mZoomSupported;
462 }
463
464 /**
chen xu055b1de2018-12-13 19:15:06 -0800465 * Returns the maximum zoom supported by the camera.
Yorke Lee400470f2015-05-12 13:31:25 -0700466 */
467 public float getMaxZoom() {
468 return mMaxZoom;
469 }
470 }
471
Tyler Gunn7c668b92014-06-27 14:38:28 -0700472}