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.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      */
    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      */
    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      */
    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      */
    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
    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
    192     public void writeToParcel(Parcel dest, int flags) {
    193         dest.writeInt(mVideoState);
    194         dest.writeInt(mQuality);
    195     }
    196 
    197     @Override
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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          */
    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          */
    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
    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
    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          */
    420         public int getWidth() {
    421             return mWidth;
    422         }
    423 
    424         /**
    425          * The height of the camera video in pixels.
    426          */
    427         public int getHeight() {
    428             return mHeight;
    429         }
    430 
    431         /**
    432          * Whether the camera supports zoom.
    433          * @hide
    434          */
    435         public boolean isZoomSupported() {
    436             return mZoomSupported;
    437         }
    438 
    439         /**
    440          * The maximum zoom supported by the camera.
    441          * @hide
    442          */
    443         public float getMaxZoom() {
    444             return mMaxZoom;
    445         }
    446     }
    447 
    448 }
    449