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