blob: 4197f3cfc6c34885bd456caf6e07c09c7ea9e74e [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;
Tyler Gunn7c668b92014-06-27 14:38:28 -070022import android.os.Parcel;
23import android.os.Parcelable;
24
Tyler Gunn48d02102016-01-08 13:20:25 -080025import java.lang.annotation.Retention;
26import java.lang.annotation.RetentionPolicy;
27
Tyler Gunn7c668b92014-06-27 14:38:28 -070028/**
29 * Represents attributes of video calls.
30 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070031public class VideoProfile implements Parcelable {
Tyler Gunn48d02102016-01-08 13:20:25 -080032
33 /** @hide */
34 @Retention(RetentionPolicy.SOURCE)
35 @IntDef({QUALITY_UNKNOWN, QUALITY_HIGH, QUALITY_MEDIUM, QUALITY_LOW, QUALITY_DEFAULT})
36 public @interface VideoQuality {}
37
Tyler Gunn7c668b92014-06-27 14:38:28 -070038 /**
Rekha Kumar07366812015-03-24 16:42:31 -070039 * "Unknown" video quality.
40 * @hide
41 */
42 public static final int QUALITY_UNKNOWN = 0;
43 /**
Tyler Gunn7c668b92014-06-27 14:38:28 -070044 * "High" video quality.
45 */
46 public static final int QUALITY_HIGH = 1;
47
48 /**
49 * "Medium" video quality.
50 */
51 public static final int QUALITY_MEDIUM = 2;
52
53 /**
54 * "Low" video quality.
55 */
56 public static final int QUALITY_LOW = 3;
57
58 /**
59 * Use default video quality.
60 */
61 public static final int QUALITY_DEFAULT = 4;
62
Tyler Gunn48d02102016-01-08 13:20:25 -080063 /** @hide */
64 @Retention(RetentionPolicy.SOURCE)
65 @IntDef(
66 flag = true,
Tyler Gunn9d127732018-03-02 15:45:51 -080067 prefix = { "STATE_" },
Tyler Gunn48d02102016-01-08 13:20:25 -080068 value = {STATE_AUDIO_ONLY, STATE_TX_ENABLED, STATE_RX_ENABLED, STATE_BIDIRECTIONAL,
69 STATE_PAUSED})
70 public @interface VideoState {}
71
Yorke Lee32f24732015-05-12 16:18:03 -070072 /**
Tyler Gunnbc6f12e2015-06-09 14:34:11 -070073 * Used when answering or dialing a call to indicate that the call does not have a video
74 * component.
75 * <p>
76 * Should <b>not</b> be used in comparison checks to determine if a video state represents an
77 * audio-only call.
78 * <p>
79 * The following, for example, is not the correct way to check if a call is audio-only:
80 * <pre>
81 * {@code
82 * // This is the incorrect way to check for an audio-only call.
83 * if (videoState == VideoProfile.STATE_AUDIO_ONLY) {
84 * // Handle audio-only call.
85 * }
86 * }
87 * </pre>
88 * <p>
89 * Instead, use the {@link VideoProfile#isAudioOnly(int)} helper function to check if a
90 * video state represents an audio-only call:
91 * <pre>
92 * {@code
93 * // This is the correct way to check for an audio-only call.
94 * if (VideoProfile.isAudioOnly(videoState)) {
95 * // Handle audio-only call.
96 * }
97 * }
98 * </pre>
Yorke Lee32f24732015-05-12 16:18:03 -070099 */
100 public static final int STATE_AUDIO_ONLY = 0x0;
101
102 /**
103 * Video transmission is enabled.
104 */
105 public static final int STATE_TX_ENABLED = 0x1;
106
107 /**
108 * Video reception is enabled.
109 */
110 public static final int STATE_RX_ENABLED = 0x2;
111
112 /**
113 * Video signal is bi-directional.
114 */
115 public static final int STATE_BIDIRECTIONAL = STATE_TX_ENABLED | STATE_RX_ENABLED;
116
117 /**
118 * Video is paused.
119 */
120 public static final int STATE_PAUSED = 0x4;
121
Tyler Gunn7c668b92014-06-27 14:38:28 -0700122 private final int mVideoState;
123
124 private final int mQuality;
125
126 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700127 * Creates an instance of the VideoProfile
Tyler Gunn7c668b92014-06-27 14:38:28 -0700128 *
129 * @param videoState The video state.
Andrew Lee055e5a22014-07-21 12:14:11 -0700130 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800131 public VideoProfile(@VideoState int videoState) {
Andrew Lee055e5a22014-07-21 12:14:11 -0700132 this(videoState, QUALITY_DEFAULT);
133 }
134
135 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700136 * Creates an instance of the VideoProfile
Andrew Lee055e5a22014-07-21 12:14:11 -0700137 *
138 * @param videoState The video state.
Tyler Gunn7c668b92014-06-27 14:38:28 -0700139 * @param quality The video quality.
140 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800141 public VideoProfile(@VideoState int videoState, @VideoQuality int quality) {
Tyler Gunn7c668b92014-06-27 14:38:28 -0700142 mVideoState = videoState;
143 mQuality = quality;
144 }
145
146 /**
Andrew Lee48332d62014-07-28 14:04:20 -0700147 * The video state of the call.
Yorke Lee32f24732015-05-12 16:18:03 -0700148 * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
149 * {@link VideoProfile#STATE_BIDIRECTIONAL},
150 * {@link VideoProfile#STATE_TX_ENABLED},
151 * {@link VideoProfile#STATE_RX_ENABLED},
152 * {@link VideoProfile#STATE_PAUSED}.
Tyler Gunn7c668b92014-06-27 14:38:28 -0700153 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800154 @VideoState
Tyler Gunn7c668b92014-06-27 14:38:28 -0700155 public int getVideoState() {
156 return mVideoState;
157 }
158
159 /**
160 * The desired video quality for the call.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700161 * Valid values: {@link VideoProfile#QUALITY_HIGH}, {@link VideoProfile#QUALITY_MEDIUM},
162 * {@link VideoProfile#QUALITY_LOW}, {@link VideoProfile#QUALITY_DEFAULT}.
Tyler Gunn7c668b92014-06-27 14:38:28 -0700163 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800164 @VideoQuality
Tyler Gunn7c668b92014-06-27 14:38:28 -0700165 public int getQuality() {
166 return mQuality;
167 }
168
169 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700170 * Responsible for creating VideoProfile objects from deserialized Parcels.
Tyler Gunn7c668b92014-06-27 14:38:28 -0700171 **/
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700172 public static final @android.annotation.NonNull Parcelable.Creator<VideoProfile> CREATOR =
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700173 new Parcelable.Creator<VideoProfile> () {
Tyler Gunn7c668b92014-06-27 14:38:28 -0700174 /**
175 * Creates a MediaProfile instances from a parcel.
176 *
177 * @param source The parcel.
178 * @return The MediaProfile.
179 */
180 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700181 public VideoProfile createFromParcel(Parcel source) {
Tyler Gunn7c668b92014-06-27 14:38:28 -0700182 int state = source.readInt();
183 int quality = source.readInt();
184
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700185 ClassLoader classLoader = VideoProfile.class.getClassLoader();
186 return new VideoProfile(state, quality);
Tyler Gunn7c668b92014-06-27 14:38:28 -0700187 }
188
189 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700190 public VideoProfile[] newArray(int size) {
191 return new VideoProfile[size];
Tyler Gunn7c668b92014-06-27 14:38:28 -0700192 }
193 };
194
195 /**
196 * Describe the kinds of special objects contained in this Parcelable's
197 * marshalled representation.
198 *
199 * @return a bitmask indicating the set of special object types marshalled
200 * by the Parcelable.
201 */
202 @Override
203 public int describeContents() {
204 return 0;
205 }
206
207 /**
208 * Flatten this object in to a Parcel.
209 *
210 * @param dest The Parcel in which the object should be written.
211 * @param flags Additional flags about how the object should be written.
212 * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
213 */
214 @Override
215 public void writeToParcel(Parcel dest, int flags) {
216 dest.writeInt(mVideoState);
217 dest.writeInt(mQuality);
218 }
Andrew Lee48332d62014-07-28 14:04:20 -0700219
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700220 @Override
221 public String toString() {
222 StringBuilder sb = new StringBuilder();
223 sb.append("[VideoProfile videoState = ");
Tyler Gunn87b73f32015-06-03 10:09:59 -0700224 sb.append(videoStateToString(mVideoState));
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700225 sb.append(" videoQuality = ");
226 sb.append(mQuality);
227 sb.append("]");
228 return sb.toString();
229 }
230
Andrew Lee48332d62014-07-28 14:04:20 -0700231 /**
Tyler Gunn87b73f32015-06-03 10:09:59 -0700232 * Generates a string representation of a video state.
233 *
234 * @param videoState The video state.
235 * @return String representation of the video state.
236 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800237 public static String videoStateToString(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700238 StringBuilder sb = new StringBuilder();
239 sb.append("Audio");
Andrew Lee48332d62014-07-28 14:04:20 -0700240
Tyler Gunn1aee66f2017-02-21 15:19:43 -0800241 if (videoState == STATE_AUDIO_ONLY) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700242 sb.append(" Only");
243 } else {
244 if (isTransmissionEnabled(videoState)) {
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700245 sb.append(" Tx");
246 }
247
Tyler Gunn87b73f32015-06-03 10:09:59 -0700248 if (isReceptionEnabled(videoState)) {
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700249 sb.append(" Rx");
250 }
251
Tyler Gunn87b73f32015-06-03 10:09:59 -0700252 if (isPaused(videoState)) {
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700253 sb.append(" Pause");
254 }
Tyler Gunnbde0b1e2015-04-24 15:09:58 -0700255 }
Tyler Gunn87b73f32015-06-03 10:09:59 -0700256
257 return sb.toString();
258 }
259
260 /**
261 * Indicates whether the video state is audio only.
Tyler Gunn1aee66f2017-02-21 15:19:43 -0800262 * <p>
263 * Note: Considers only whether either both the {@link #STATE_RX_ENABLED} or
264 * {@link #STATE_TX_ENABLED} bits are off, but not {@link #STATE_PAUSED}.
Tyler Gunn87b73f32015-06-03 10:09:59 -0700265 *
266 * @param videoState The video state.
267 * @return {@code True} if the video state is audio only, {@code false} otherwise.
268 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800269 public static boolean isAudioOnly(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700270 return !hasState(videoState, VideoProfile.STATE_TX_ENABLED)
271 && !hasState(videoState, VideoProfile.STATE_RX_ENABLED);
272 }
273
274 /**
275 * Indicates whether video transmission or reception is enabled for a video state.
276 *
277 * @param videoState The video state.
278 * @return {@code True} if video transmission or reception is enabled, {@code false} otherwise.
279 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800280 public static boolean isVideo(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700281 return hasState(videoState, VideoProfile.STATE_TX_ENABLED)
282 || hasState(videoState, VideoProfile.STATE_RX_ENABLED)
283 || hasState(videoState, VideoProfile.STATE_BIDIRECTIONAL);
284 }
285
286 /**
287 * Indicates whether the video state has video transmission enabled.
288 *
289 * @param videoState The video state.
290 * @return {@code True} if video transmission is enabled, {@code false} otherwise.
291 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800292 public static boolean isTransmissionEnabled(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700293 return hasState(videoState, VideoProfile.STATE_TX_ENABLED);
294 }
295
296 /**
297 * Indicates whether the video state has video reception enabled.
298 *
299 * @param videoState The video state.
300 * @return {@code True} if video reception is enabled, {@code false} otherwise.
301 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800302 public static boolean isReceptionEnabled(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700303 return hasState(videoState, VideoProfile.STATE_RX_ENABLED);
304 }
305
306 /**
307 * Indicates whether the video state is bi-directional.
308 *
309 * @param videoState The video state.
310 * @return {@code True} if the video is bi-directional, {@code false} otherwise.
311 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800312 public static boolean isBidirectional(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700313 return hasState(videoState, VideoProfile.STATE_BIDIRECTIONAL);
314 }
315
316 /**
317 * Indicates whether the video state is paused.
318 *
319 * @param videoState The video state.
320 * @return {@code True} if the video is paused, {@code false} otherwise.
321 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800322 public static boolean isPaused(@VideoState int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700323 return hasState(videoState, VideoProfile.STATE_PAUSED);
324 }
325
326 /**
327 * Indicates if a specified state is set in a videoState bit-mask.
328 *
329 * @param videoState The video state bit-mask.
330 * @param state The state to check.
331 * @return {@code True} if the state is set.
332 */
Tyler Gunn48d02102016-01-08 13:20:25 -0800333 private static boolean hasState(@VideoState int videoState, @VideoState int state) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700334 return (videoState & state) == state;
Andrew Lee48332d62014-07-28 14:04:20 -0700335 }
Yorke Lee400470f2015-05-12 13:31:25 -0700336
337 /**
338 * Represents the camera capabilities important to a Video Telephony provider.
339 */
340 public static final class CameraCapabilities implements Parcelable {
341
342 /**
343 * The width of the camera video in pixels.
344 */
345 private final int mWidth;
346
347 /**
348 * The height of the camera video in pixels.
349 */
350 private final int mHeight;
351
352 /**
353 * Whether the camera supports zoom.
354 */
355 private final boolean mZoomSupported;
356
357 /**
358 * The maximum zoom supported by the camera.
359 */
360 private final float mMaxZoom;
361
362 /**
363 * Create a call camera capabilities instance.
364 *
365 * @param width The width of the camera video (in pixels).
366 * @param height The height of the camera video (in pixels).
367 */
chen xue0a3eb92019-01-29 13:58:29 -0800368 public CameraCapabilities(@IntRange(from = 0) int width, @IntRange(from = 0) int height) {
Yorke Lee400470f2015-05-12 13:31:25 -0700369 this(width, height, false, 1.0f);
370 }
371
372 /**
chen xu055b1de2018-12-13 19:15:06 -0800373 * Create a call camera capabilities instance that optionally supports zoom.
Yorke Lee400470f2015-05-12 13:31:25 -0700374 *
375 * @param width The width of the camera video (in pixels).
376 * @param height The height of the camera video (in pixels).
377 * @param zoomSupported True when camera supports zoom.
378 * @param maxZoom Maximum zoom supported by camera.
Yorke Lee400470f2015-05-12 13:31:25 -0700379 */
chen xue0a3eb92019-01-29 13:58:29 -0800380 public CameraCapabilities(@IntRange(from = 0) int width, @IntRange(from = 0) int height,
381 boolean zoomSupported, @FloatRange(from = 1.0f) float maxZoom) {
Yorke Lee400470f2015-05-12 13:31:25 -0700382 mWidth = width;
383 mHeight = height;
384 mZoomSupported = zoomSupported;
385 mMaxZoom = maxZoom;
386 }
387
388 /**
389 * Responsible for creating CallCameraCapabilities objects from deserialized Parcels.
390 **/
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700391 public static final @android.annotation.NonNull Parcelable.Creator<CameraCapabilities> CREATOR =
Yorke Lee400470f2015-05-12 13:31:25 -0700392 new Parcelable.Creator<CameraCapabilities> () {
393 /**
394 * Creates a CallCameraCapabilities instances from a parcel.
395 *
396 * @param source The parcel.
397 * @return The CallCameraCapabilities.
398 */
399 @Override
400 public CameraCapabilities createFromParcel(Parcel source) {
401 int width = source.readInt();
402 int height = source.readInt();
403 boolean supportsZoom = source.readByte() != 0;
404 float maxZoom = source.readFloat();
405
406 return new CameraCapabilities(width, height, supportsZoom, maxZoom);
407 }
408
409 @Override
410 public CameraCapabilities[] newArray(int size) {
411 return new CameraCapabilities[size];
412 }
413 };
414
415 /**
416 * Describe the kinds of special objects contained in this Parcelable's
417 * marshalled representation.
418 *
419 * @return a bitmask indicating the set of special object types marshalled
420 * by the Parcelable.
421 */
422 @Override
423 public int describeContents() {
424 return 0;
425 }
426
427 /**
428 * Flatten this object in to a Parcel.
429 *
430 * @param dest The Parcel in which the object should be written.
431 * @param flags Additional flags about how the object should be written.
432 * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
433 */
434 @Override
435 public void writeToParcel(Parcel dest, int flags) {
436 dest.writeInt(getWidth());
437 dest.writeInt(getHeight());
438 dest.writeByte((byte) (isZoomSupported() ? 1 : 0));
439 dest.writeFloat(getMaxZoom());
440 }
441
442 /**
443 * The width of the camera video in pixels.
444 */
445 public int getWidth() {
446 return mWidth;
447 }
448
449 /**
450 * The height of the camera video in pixels.
451 */
452 public int getHeight() {
453 return mHeight;
454 }
455
456 /**
chen xu055b1de2018-12-13 19:15:06 -0800457 * Returns {@code true} is zoom is supported, {@code false} otherwise.
Yorke Lee400470f2015-05-12 13:31:25 -0700458 */
459 public boolean isZoomSupported() {
460 return mZoomSupported;
461 }
462
463 /**
chen xu055b1de2018-12-13 19:15:06 -0800464 * Returns the maximum zoom supported by the camera.
Yorke Lee400470f2015-05-12 13:31:25 -0700465 */
466 public float getMaxZoom() {
467 return mMaxZoom;
468 }
469 }
470
Tyler Gunn7c668b92014-06-27 14:38:28 -0700471}