Home | History | Annotate | Download | only in telecom
      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