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 import java.util.Locale;
     23 
     24 /**
     25  *  Encapsulates the telecom audio state, including the current audio routing, supported audio
     26  *  routing and mute.
     27  */
     28 public final class CallAudioState implements Parcelable {
     29     /** Direct the audio stream through the device's earpiece. */
     30     public static final int ROUTE_EARPIECE      = 0x00000001;
     31 
     32     /** Direct the audio stream through Bluetooth. */
     33     public static final int ROUTE_BLUETOOTH     = 0x00000002;
     34 
     35     /** Direct the audio stream through a wired headset. */
     36     public static final int ROUTE_WIRED_HEADSET = 0x00000004;
     37 
     38     /** Direct the audio stream through the device's speakerphone. */
     39     public static final int ROUTE_SPEAKER       = 0x00000008;
     40 
     41     /**
     42      * Direct the audio stream through the device's earpiece or wired headset if one is
     43      * connected.
     44      */
     45     public static final int ROUTE_WIRED_OR_EARPIECE = ROUTE_EARPIECE | ROUTE_WIRED_HEADSET;
     46 
     47     /** Bit mask of all possible audio routes. */
     48     private static final int ROUTE_ALL = ROUTE_EARPIECE | ROUTE_BLUETOOTH | ROUTE_WIRED_HEADSET |
     49             ROUTE_SPEAKER;
     50 
     51     private final boolean isMuted;
     52     private final int route;
     53     private final int supportedRouteMask;
     54 
     55     /**
     56      * Constructor for a {@link CallAudioState} object.
     57      *
     58      * @param muted {@code true} if the call is muted, {@code false} otherwise.
     59      * @param route The current audio route being used.
     60      * Allowed values:
     61      * {@link #ROUTE_EARPIECE}
     62      * {@link #ROUTE_BLUETOOTH}
     63      * {@link #ROUTE_WIRED_HEADSET}
     64      * {@link #ROUTE_SPEAKER}
     65      * @param supportedRouteMask Bit mask of all routes supported by this call. This should be a
     66      * bitwise combination of the following values:
     67      * {@link #ROUTE_EARPIECE}
     68      * {@link #ROUTE_BLUETOOTH}
     69      * {@link #ROUTE_WIRED_HEADSET}
     70      * {@link #ROUTE_SPEAKER}
     71      */
     72     public CallAudioState(boolean muted, int route, int supportedRouteMask) {
     73         this.isMuted = muted;
     74         this.route = route;
     75         this.supportedRouteMask = supportedRouteMask;
     76     }
     77 
     78     /** @hide */
     79     public CallAudioState(CallAudioState state) {
     80         isMuted = state.isMuted();
     81         route = state.getRoute();
     82         supportedRouteMask = state.getSupportedRouteMask();
     83     }
     84 
     85     /** @hide */
     86     @SuppressWarnings("deprecation")
     87     public CallAudioState(AudioState state) {
     88         isMuted = state.isMuted();
     89         route = state.getRoute();
     90         supportedRouteMask = state.getSupportedRouteMask();
     91     }
     92 
     93     @Override
     94     public boolean equals(Object obj) {
     95         if (obj == null) {
     96             return false;
     97         }
     98         if (!(obj instanceof CallAudioState)) {
     99             return false;
    100         }
    101         CallAudioState state = (CallAudioState) obj;
    102         return isMuted() == state.isMuted() && getRoute() == state.getRoute() &&
    103                 getSupportedRouteMask() == state.getSupportedRouteMask();
    104     }
    105 
    106     @Override
    107     public String toString() {
    108         return String.format(Locale.US,
    109                 "[AudioState isMuted: %b, route: %s, supportedRouteMask: %s]",
    110                 isMuted,
    111                 audioRouteToString(route),
    112                 audioRouteToString(supportedRouteMask));
    113     }
    114 
    115     /**
    116      * @return {@code true} if the call is muted, {@code false} otherwise.
    117      */
    118     public boolean isMuted() {
    119         return isMuted;
    120     }
    121 
    122     /**
    123      * @return The current audio route being used.
    124      */
    125     public int getRoute() {
    126         return route;
    127     }
    128 
    129     /**
    130      * @return Bit mask of all routes supported by this call.
    131      */
    132     public int getSupportedRouteMask() {
    133         return supportedRouteMask;
    134     }
    135 
    136     /**
    137      * Converts the provided audio route into a human readable string representation.
    138      *
    139      * @param route to convert into a string.
    140      *
    141      * @return String representation of the provided audio route.
    142      */
    143     public static String audioRouteToString(int route) {
    144         if (route == 0 || (route & ~ROUTE_ALL) != 0x0) {
    145             return "UNKNOWN";
    146         }
    147 
    148         StringBuffer buffer = new StringBuffer();
    149         if ((route & ROUTE_EARPIECE) == ROUTE_EARPIECE) {
    150             listAppend(buffer, "EARPIECE");
    151         }
    152         if ((route & ROUTE_BLUETOOTH) == ROUTE_BLUETOOTH) {
    153             listAppend(buffer, "BLUETOOTH");
    154         }
    155         if ((route & ROUTE_WIRED_HEADSET) == ROUTE_WIRED_HEADSET) {
    156             listAppend(buffer, "WIRED_HEADSET");
    157         }
    158         if ((route & ROUTE_SPEAKER) == ROUTE_SPEAKER) {
    159             listAppend(buffer, "SPEAKER");
    160         }
    161 
    162         return buffer.toString();
    163     }
    164 
    165     /**
    166      * Responsible for creating AudioState objects for deserialized Parcels.
    167      */
    168     public static final Parcelable.Creator<CallAudioState> CREATOR =
    169             new Parcelable.Creator<CallAudioState> () {
    170 
    171         @Override
    172         public CallAudioState createFromParcel(Parcel source) {
    173             boolean isMuted = source.readByte() == 0 ? false : true;
    174             int route = source.readInt();
    175             int supportedRouteMask = source.readInt();
    176             return new CallAudioState(isMuted, route, supportedRouteMask);
    177         }
    178 
    179         @Override
    180         public CallAudioState[] newArray(int size) {
    181             return new CallAudioState[size];
    182         }
    183     };
    184 
    185     /**
    186      * {@inheritDoc}
    187      */
    188     @Override
    189     public int describeContents() {
    190         return 0;
    191     }
    192 
    193     /**
    194      * Writes AudioState object into a serializeable Parcel.
    195      */
    196     @Override
    197     public void writeToParcel(Parcel destination, int flags) {
    198         destination.writeByte((byte) (isMuted ? 1 : 0));
    199         destination.writeInt(route);
    200         destination.writeInt(supportedRouteMask);
    201     }
    202 
    203     private static void listAppend(StringBuffer buffer, String str) {
    204         if (buffer.length() > 0) {
    205             buffer.append(", ");
    206         }
    207         buffer.append(str);
    208     }
    209 }
    210