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 */ 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 */ 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 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 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 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 212 public void writeToParcel(Parcel dest, int flags) { 213 dest.writeInt(mVideoState); 214 dest.writeInt(mQuality); 215 } 216 217 @Override 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 */ 234 public static String videoStateToString(@VideoState int videoState) { 235 StringBuilder sb = new StringBuilder(); 236 sb.append("Audio"); 237 238 if (isAudioOnly(videoState)) { 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 * 260 * @param videoState The video state. 261 * @return {@code True} if the video state is audio only, {@code false} otherwise. 262 */ 263 public static boolean isAudioOnly(@VideoState int videoState) { 264 return !hasState(videoState, VideoProfile.STATE_TX_ENABLED) 265 && !hasState(videoState, VideoProfile.STATE_RX_ENABLED); 266 } 267 268 /** 269 * Indicates whether video transmission or reception is enabled for a video state. 270 * 271 * @param videoState The video state. 272 * @return {@code True} if video transmission or reception is enabled, {@code false} otherwise. 273 */ 274 public static boolean isVideo(@VideoState int videoState) { 275 return hasState(videoState, VideoProfile.STATE_TX_ENABLED) 276 || hasState(videoState, VideoProfile.STATE_RX_ENABLED) 277 || hasState(videoState, VideoProfile.STATE_BIDIRECTIONAL); 278 } 279 280 /** 281 * Indicates whether the video state has video transmission enabled. 282 * 283 * @param videoState The video state. 284 * @return {@code True} if video transmission is enabled, {@code false} otherwise. 285 */ 286 public static boolean isTransmissionEnabled(@VideoState int videoState) { 287 return hasState(videoState, VideoProfile.STATE_TX_ENABLED); 288 } 289 290 /** 291 * Indicates whether the video state has video reception enabled. 292 * 293 * @param videoState The video state. 294 * @return {@code True} if video reception is enabled, {@code false} otherwise. 295 */ 296 public static boolean isReceptionEnabled(@VideoState int videoState) { 297 return hasState(videoState, VideoProfile.STATE_RX_ENABLED); 298 } 299 300 /** 301 * Indicates whether the video state is bi-directional. 302 * 303 * @param videoState The video state. 304 * @return {@code True} if the video is bi-directional, {@code false} otherwise. 305 */ 306 public static boolean isBidirectional(@VideoState int videoState) { 307 return hasState(videoState, VideoProfile.STATE_BIDIRECTIONAL); 308 } 309 310 /** 311 * Indicates whether the video state is paused. 312 * 313 * @param videoState The video state. 314 * @return {@code True} if the video is paused, {@code false} otherwise. 315 */ 316 public static boolean isPaused(@VideoState int videoState) { 317 return hasState(videoState, VideoProfile.STATE_PAUSED); 318 } 319 320 /** 321 * Indicates if a specified state is set in a videoState bit-mask. 322 * 323 * @param videoState The video state bit-mask. 324 * @param state The state to check. 325 * @return {@code True} if the state is set. 326 */ 327 private static boolean hasState(@VideoState int videoState, @VideoState int state) { 328 return (videoState & state) == state; 329 } 330 331 /** 332 * Represents the camera capabilities important to a Video Telephony provider. 333 */ 334 public static final class CameraCapabilities implements Parcelable { 335 336 /** 337 * The width of the camera video in pixels. 338 */ 339 private final int mWidth; 340 341 /** 342 * The height of the camera video in pixels. 343 */ 344 private final int mHeight; 345 346 /** 347 * Whether the camera supports zoom. 348 */ 349 private final boolean mZoomSupported; 350 351 /** 352 * The maximum zoom supported by the camera. 353 */ 354 private final float mMaxZoom; 355 356 /** 357 * Create a call camera capabilities instance. 358 * 359 * @param width The width of the camera video (in pixels). 360 * @param height The height of the camera video (in pixels). 361 */ 362 public CameraCapabilities(int width, int height) { 363 this(width, height, false, 1.0f); 364 } 365 366 /** 367 * Create a call camera capabilities instance that optionally 368 * supports zoom. 369 * 370 * @param width The width of the camera video (in pixels). 371 * @param height The height of the camera video (in pixels). 372 * @param zoomSupported True when camera supports zoom. 373 * @param maxZoom Maximum zoom supported by camera. 374 * @hide 375 */ 376 public CameraCapabilities(int width, int height, boolean zoomSupported, float maxZoom) { 377 mWidth = width; 378 mHeight = height; 379 mZoomSupported = zoomSupported; 380 mMaxZoom = maxZoom; 381 } 382 383 /** 384 * Responsible for creating CallCameraCapabilities objects from deserialized Parcels. 385 **/ 386 public static final Parcelable.Creator<CameraCapabilities> CREATOR = 387 new Parcelable.Creator<CameraCapabilities> () { 388 /** 389 * Creates a CallCameraCapabilities instances from a parcel. 390 * 391 * @param source The parcel. 392 * @return The CallCameraCapabilities. 393 */ 394 @Override 395 public CameraCapabilities createFromParcel(Parcel source) { 396 int width = source.readInt(); 397 int height = source.readInt(); 398 boolean supportsZoom = source.readByte() != 0; 399 float maxZoom = source.readFloat(); 400 401 return new CameraCapabilities(width, height, supportsZoom, maxZoom); 402 } 403 404 @Override 405 public CameraCapabilities[] newArray(int size) { 406 return new CameraCapabilities[size]; 407 } 408 }; 409 410 /** 411 * Describe the kinds of special objects contained in this Parcelable's 412 * marshalled representation. 413 * 414 * @return a bitmask indicating the set of special object types marshalled 415 * by the Parcelable. 416 */ 417 @Override 418 public int describeContents() { 419 return 0; 420 } 421 422 /** 423 * Flatten this object in to a Parcel. 424 * 425 * @param dest The Parcel in which the object should be written. 426 * @param flags Additional flags about how the object should be written. 427 * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}. 428 */ 429 @Override 430 public void writeToParcel(Parcel dest, int flags) { 431 dest.writeInt(getWidth()); 432 dest.writeInt(getHeight()); 433 dest.writeByte((byte) (isZoomSupported() ? 1 : 0)); 434 dest.writeFloat(getMaxZoom()); 435 } 436 437 /** 438 * The width of the camera video in pixels. 439 */ 440 public int getWidth() { 441 return mWidth; 442 } 443 444 /** 445 * The height of the camera video in pixels. 446 */ 447 public int getHeight() { 448 return mHeight; 449 } 450 451 /** 452 * Whether the camera supports zoom. 453 * @hide 454 */ 455 public boolean isZoomSupported() { 456 return mZoomSupported; 457 } 458 459 /** 460 * The maximum zoom supported by the camera. 461 * @hide 462 */ 463 public float getMaxZoom() { 464 return mMaxZoom; 465 } 466 } 467 468 } 469