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.SystemApi;
     20 import android.graphics.drawable.Icon;
     21 import android.net.Uri;
     22 import android.os.Bundle;
     23 import android.os.Parcel;
     24 import android.os.Parcelable;
     25 import android.text.TextUtils;
     26 
     27 import java.lang.String;
     28 import java.util.ArrayList;
     29 import java.util.Collections;
     30 import java.util.List;
     31 
     32 /**
     33  * Represents a distinct method to place or receive a phone call. Apps which can place calls and
     34  * want those calls to be integrated into the dialer and in-call UI should build an instance of
     35  * this class and register it with the system using {@link TelecomManager}.
     36  * <p>
     37  * {@link TelecomManager} uses registered {@link PhoneAccount}s to present the user with
     38  * alternative options when placing a phone call. When building a {@link PhoneAccount}, the app
     39  * should supply a valid {@link PhoneAccountHandle} that references the connection service
     40  * implementation Telecom will use to interact with the app.
     41  */
     42 public final class PhoneAccount implements Parcelable {
     43 
     44     /**
     45      * {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which determines the
     46      * sort order for {@link PhoneAccount}s from the same
     47      * {@link android.telecom.ConnectionService}.
     48      * @hide
     49      */
     50     public static final String EXTRA_SORT_ORDER =
     51             "android.telecom.extra.SORT_ORDER";
     52 
     53     /**
     54      * {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which determines the
     55      * maximum permitted length of a call subject specified via the
     56      * {@link TelecomManager#EXTRA_CALL_SUBJECT} extra on an
     57      * {@link android.content.Intent#ACTION_CALL} intent.  Ultimately a {@link ConnectionService} is
     58      * responsible for enforcing the maximum call subject length when sending the message, however
     59      * this extra is provided so that the user interface can proactively limit the length of the
     60      * call subject as the user types it.
     61      */
     62     public static final String EXTRA_CALL_SUBJECT_MAX_LENGTH =
     63             "android.telecom.extra.CALL_SUBJECT_MAX_LENGTH";
     64 
     65     /**
     66      * {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which determines the
     67      * character encoding to be used when determining the length of messages.
     68      * The user interface can use this when determining the number of characters the user may type
     69      * in a call subject.  If empty-string, the call subject message size limit will be enforced on
     70      * a 1:1 basis.  That is, each character will count towards the messages size limit as a single
     71      * character.  If a character encoding is specified, the message size limit will be based on the
     72      * number of bytes in the message per the specified encoding.  See
     73      * {@link #EXTRA_CALL_SUBJECT_MAX_LENGTH} for more information on the call subject maximum
     74      * length.
     75      */
     76     public static final String EXTRA_CALL_SUBJECT_CHARACTER_ENCODING =
     77             "android.telecom.extra.CALL_SUBJECT_CHARACTER_ENCODING";
     78 
     79      /**
     80      * Indicating flag for phone account whether to use voip audio mode for voip calls
     81      * @hide
     82      */
     83     public static final String EXTRA_ALWAYS_USE_VOIP_AUDIO_MODE =
     84             "android.telecom.extra.ALWAYS_USE_VOIP_AUDIO_MODE";
     85 
     86     /**
     87      * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
     88      * indicates whether this {@link PhoneAccount} is capable of supporting a request to handover a
     89      * connection (see {@code android.telecom.Call#handoverTo()}) to this {@link PhoneAccount} from
     90      * a {@link PhoneAccount} specifying {@link #EXTRA_SUPPORTS_HANDOVER_FROM}.
     91      * <p>
     92      * A handover request is initiated by the user from the default dialer app to indicate a desire
     93      * to handover a call from one {@link PhoneAccount}/{@link ConnectionService} to another.
     94      */
     95     public static final String EXTRA_SUPPORTS_HANDOVER_TO =
     96             "android.telecom.extra.SUPPORTS_HANDOVER_TO";
     97 
     98     /**
     99      * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
    100      * indicates whether this {@link PhoneAccount} supports using a fallback if video calling is
    101      * not available. This extra is for device level support, {@link
    102      * android.telephony.CarrierConfigManager#KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL} should also
    103      * be checked to ensure it is not disabled by individual carrier.
    104      *
    105      * @hide
    106      */
    107     public static final String EXTRA_SUPPORTS_VIDEO_CALLING_FALLBACK =
    108             "android.telecom.extra.SUPPORTS_VIDEO_CALLING_FALLBACK";
    109 
    110     /**
    111      * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
    112      * indicates whether this {@link PhoneAccount} is capable of supporting a request to handover a
    113      * connection from this {@link PhoneAccount} to another {@link PhoneAccount}.
    114      * (see {@code android.telecom.Call#handoverTo()}) which specifies
    115      * {@link #EXTRA_SUPPORTS_HANDOVER_TO}.
    116      * <p>
    117      * A handover request is initiated by the user from the default dialer app to indicate a desire
    118      * to handover a call from one {@link PhoneAccount}/{@link ConnectionService} to another.
    119      */
    120     public static final String EXTRA_SUPPORTS_HANDOVER_FROM =
    121             "android.telecom.extra.SUPPORTS_HANDOVER_FROM";
    122 
    123 
    124     /**
    125      * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
    126      * indicates whether a Self-Managed {@link PhoneAccount} should log its calls to the call log.
    127      * Self-Managed {@link PhoneAccount}s are responsible for their own notifications, so the system
    128      * will not create a notification when a missed call is logged.
    129      * <p>
    130      * By default, Self-Managed {@link PhoneAccount}s do not log their calls to the call log.
    131      * Setting this extra to {@code true} provides a means for them to log their calls.
    132      * <p>
    133      * Note: Only calls where the {@link Call.Details#getHandle()} {@link Uri#getScheme()} is
    134      * {@link #SCHEME_SIP} or {@link #SCHEME_TEL} will be logged at the current time.
    135      */
    136     public static final String EXTRA_LOG_SELF_MANAGED_CALLS =
    137             "android.telecom.extra.LOG_SELF_MANAGED_CALLS";
    138 
    139     /**
    140      * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
    141      * indicates whether calls for a {@link PhoneAccount} should generate a "call recording tone"
    142      * when the user is recording audio on the device.
    143      * <p>
    144      * The call recording tone is played over the telephony audio stream so that the remote party
    145      * has an audible indication that it is possible their call is being recorded using a call
    146      * recording app on the device.
    147      * <p>
    148      * This extra only has an effect for calls placed via Telephony (e.g.
    149      * {@link #CAPABILITY_SIM_SUBSCRIPTION}).
    150      * <p>
    151      * The call recording tone is a 1400 hz tone which repeats every 15 seconds while recording is
    152      * in progress.
    153      * @hide
    154      */
    155     public static final String EXTRA_PLAY_CALL_RECORDING_TONE =
    156             "android.telecom.extra.PLAY_CALL_RECORDING_TONE";
    157 
    158     /**
    159      * Flag indicating that this {@code PhoneAccount} can act as a connection manager for
    160      * other connections. The {@link ConnectionService} associated with this {@code PhoneAccount}
    161      * will be allowed to manage phone calls including using its own proprietary phone-call
    162      * implementation (like VoIP calling) to make calls instead of the telephony stack.
    163      * <p>
    164      * When a user opts to place a call using the SIM-based telephony stack, the
    165      * {@link ConnectionService} associated with this {@code PhoneAccount} will be attempted first
    166      * if the user has explicitly selected it to be used as the default connection manager.
    167      * <p>
    168      * See {@link #getCapabilities}
    169      */
    170     public static final int CAPABILITY_CONNECTION_MANAGER = 0x1;
    171 
    172     /**
    173      * Flag indicating that this {@code PhoneAccount} can make phone calls in place of
    174      * traditional SIM-based telephony calls. This account will be treated as a distinct method
    175      * for placing calls alongside the traditional SIM-based telephony stack. This flag is
    176      * distinct from {@link #CAPABILITY_CONNECTION_MANAGER} in that it is not allowed to manage
    177      * or place calls from the built-in telephony stack.
    178      * <p>
    179      * See {@link #getCapabilities}
    180      * <p>
    181      */
    182     public static final int CAPABILITY_CALL_PROVIDER = 0x2;
    183 
    184     /**
    185      * Flag indicating that this {@code PhoneAccount} represents a built-in PSTN SIM
    186      * subscription.
    187      * <p>
    188      * Only the Android framework can register a {@code PhoneAccount} having this capability.
    189      * <p>
    190      * See {@link #getCapabilities}
    191      */
    192     public static final int CAPABILITY_SIM_SUBSCRIPTION = 0x4;
    193 
    194     /**
    195      * Flag indicating that this {@code PhoneAccount} is currently able to place video calls.
    196      * <p>
    197      * See also {@link #CAPABILITY_SUPPORTS_VIDEO_CALLING} which indicates whether the
    198      * {@code PhoneAccount} supports placing video calls.
    199      * <p>
    200      * See {@link #getCapabilities}
    201      */
    202     public static final int CAPABILITY_VIDEO_CALLING = 0x8;
    203 
    204     /**
    205      * Flag indicating that this {@code PhoneAccount} is capable of placing emergency calls.
    206      * By default all PSTN {@code PhoneAccount}s are capable of placing emergency calls.
    207      * <p>
    208      * See {@link #getCapabilities}
    209      */
    210     public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 0x10;
    211 
    212     /**
    213      * Flag indicating that this {@code PhoneAccount} is capable of being used by all users. This
    214      * should only be used by system apps (and will be ignored for all other apps trying to use it).
    215      * <p>
    216      * See {@link #getCapabilities}
    217      * @hide
    218      */
    219     @SystemApi
    220     public static final int CAPABILITY_MULTI_USER = 0x20;
    221 
    222     /**
    223      * Flag indicating that this {@code PhoneAccount} supports a subject for Calls.  This means a
    224      * caller is able to specify a short subject line for an outgoing call.  A capable receiving
    225      * device displays the call subject on the incoming call screen.
    226      * <p>
    227      * See {@link #getCapabilities}
    228      */
    229     public static final int CAPABILITY_CALL_SUBJECT = 0x40;
    230 
    231     /**
    232      * Flag indicating that this {@code PhoneAccount} should only be used for emergency calls.
    233      * <p>
    234      * See {@link #getCapabilities}
    235      * @hide
    236      */
    237     public static final int CAPABILITY_EMERGENCY_CALLS_ONLY = 0x80;
    238 
    239     /**
    240      * Flag indicating that for this {@code PhoneAccount}, the ability to make a video call to a
    241      * number relies on presence.  Should only be set if the {@code PhoneAccount} also has
    242      * {@link #CAPABILITY_VIDEO_CALLING}.
    243      * <p>
    244      * When set, the {@link ConnectionService} is responsible for toggling the
    245      * {@link android.provider.ContactsContract.Data#CARRIER_PRESENCE_VT_CAPABLE} bit on the
    246      * {@link android.provider.ContactsContract.Data#CARRIER_PRESENCE} column to indicate whether
    247      * a contact's phone number supports video calling.
    248      * <p>
    249      * See {@link #getCapabilities}
    250      */
    251     public static final int CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE = 0x100;
    252 
    253     /**
    254      * Flag indicating that for this {@link PhoneAccount}, emergency video calling is allowed.
    255      * <p>
    256      * When set, Telecom will allow emergency video calls to be placed.  When not set, Telecom will
    257      * convert all outgoing video calls to emergency numbers to audio-only.
    258      * @hide
    259      */
    260     public static final int CAPABILITY_EMERGENCY_VIDEO_CALLING = 0x200;
    261 
    262     /**
    263      * Flag indicating that this {@link PhoneAccount} supports video calling.
    264      * This is not an indication that the {@link PhoneAccount} is currently able to make a video
    265      * call, but rather that it has the ability to make video calls (but not necessarily at this
    266      * time).
    267      * <p>
    268      * Whether a {@link PhoneAccount} can make a video call is ultimately controlled by
    269      * {@link #CAPABILITY_VIDEO_CALLING}, which indicates whether the {@link PhoneAccount} is
    270      * currently capable of making a video call.  Consider a case where, for example, a
    271      * {@link PhoneAccount} supports making video calls (e.g.
    272      * {@link #CAPABILITY_SUPPORTS_VIDEO_CALLING}), but a current lack of network connectivity
    273      * prevents video calls from being made (e.g. {@link #CAPABILITY_VIDEO_CALLING}).
    274      * <p>
    275      * See {@link #getCapabilities}
    276      */
    277     public static final int CAPABILITY_SUPPORTS_VIDEO_CALLING = 0x400;
    278 
    279     /**
    280      * Flag indicating that this {@link PhoneAccount} is responsible for managing its own
    281      * {@link Connection}s.  This type of {@link PhoneAccount} is ideal for use with standalone
    282      * calling apps which do not wish to use the default phone app for {@link Connection} UX,
    283      * but which want to leverage the call and audio routing capabilities of the Telecom framework.
    284      * <p>
    285      * When set, {@link Connection}s created by the self-managed {@link ConnectionService} will not
    286      * be surfaced to implementations of the {@link InCallService} API.  Thus it is the
    287      * responsibility of a self-managed {@link ConnectionService} to provide a user interface for
    288      * its {@link Connection}s.
    289      * <p>
    290      * Self-managed {@link Connection}s will, however, be displayed on connected Bluetooth devices.
    291      */
    292     public static final int CAPABILITY_SELF_MANAGED = 0x800;
    293 
    294     /**
    295      * Flag indicating that this {@link PhoneAccount} is capable of making a call with an
    296      * RTT (Real-time text) session.
    297      * When set, Telecom will attempt to open an RTT session on outgoing calls that specify
    298      * that they should be placed with an RTT session , and the in-call app will be displayed
    299      * with text entry fields for RTT. Likewise, the in-call app can request that an RTT
    300      * session be opened during a call if this bit is set.
    301      */
    302     public static final int CAPABILITY_RTT = 0x1000;
    303 
    304     /* NEXT CAPABILITY: 0x2000 */
    305 
    306     /**
    307      * URI scheme for telephone number URIs.
    308      */
    309     public static final String SCHEME_TEL = "tel";
    310 
    311     /**
    312      * URI scheme for voicemail URIs.
    313      */
    314     public static final String SCHEME_VOICEMAIL = "voicemail";
    315 
    316     /**
    317      * URI scheme for SIP URIs.
    318      */
    319     public static final String SCHEME_SIP = "sip";
    320 
    321     /**
    322      * Indicating no icon tint is set.
    323      * @hide
    324      */
    325     public static final int NO_ICON_TINT = 0;
    326 
    327     /**
    328      * Indicating no hightlight color is set.
    329      */
    330     public static final int NO_HIGHLIGHT_COLOR = 0;
    331 
    332     /**
    333      * Indicating no resource ID is set.
    334      */
    335     public static final int NO_RESOURCE_ID = -1;
    336 
    337     private final PhoneAccountHandle mAccountHandle;
    338     private final Uri mAddress;
    339     private final Uri mSubscriptionAddress;
    340     private final int mCapabilities;
    341     private final int mHighlightColor;
    342     private final CharSequence mLabel;
    343     private final CharSequence mShortDescription;
    344     private final List<String> mSupportedUriSchemes;
    345     private final int mSupportedAudioRoutes;
    346     private final Icon mIcon;
    347     private final Bundle mExtras;
    348     private boolean mIsEnabled;
    349     private String mGroupId;
    350 
    351     /**
    352      * Helper class for creating a {@link PhoneAccount}.
    353      */
    354     public static class Builder {
    355 
    356         private PhoneAccountHandle mAccountHandle;
    357         private Uri mAddress;
    358         private Uri mSubscriptionAddress;
    359         private int mCapabilities;
    360         private int mSupportedAudioRoutes = CallAudioState.ROUTE_ALL;
    361         private int mHighlightColor = NO_HIGHLIGHT_COLOR;
    362         private CharSequence mLabel;
    363         private CharSequence mShortDescription;
    364         private List<String> mSupportedUriSchemes = new ArrayList<String>();
    365         private Icon mIcon;
    366         private Bundle mExtras;
    367         private boolean mIsEnabled = false;
    368         private String mGroupId = "";
    369 
    370         /**
    371          * Creates a builder with the specified {@link PhoneAccountHandle} and label.
    372          */
    373         public Builder(PhoneAccountHandle accountHandle, CharSequence label) {
    374             this.mAccountHandle = accountHandle;
    375             this.mLabel = label;
    376         }
    377 
    378         /**
    379          * Creates an instance of the {@link PhoneAccount.Builder} from an existing
    380          * {@link PhoneAccount}.
    381          *
    382          * @param phoneAccount The {@link PhoneAccount} used to initialize the builder.
    383          */
    384         public Builder(PhoneAccount phoneAccount) {
    385             mAccountHandle = phoneAccount.getAccountHandle();
    386             mAddress = phoneAccount.getAddress();
    387             mSubscriptionAddress = phoneAccount.getSubscriptionAddress();
    388             mCapabilities = phoneAccount.getCapabilities();
    389             mHighlightColor = phoneAccount.getHighlightColor();
    390             mLabel = phoneAccount.getLabel();
    391             mShortDescription = phoneAccount.getShortDescription();
    392             mSupportedUriSchemes.addAll(phoneAccount.getSupportedUriSchemes());
    393             mIcon = phoneAccount.getIcon();
    394             mIsEnabled = phoneAccount.isEnabled();
    395             mExtras = phoneAccount.getExtras();
    396             mGroupId = phoneAccount.getGroupId();
    397             mSupportedAudioRoutes = phoneAccount.getSupportedAudioRoutes();
    398         }
    399 
    400         /**
    401          * Sets the label. See {@link PhoneAccount#getLabel()}.
    402          *
    403          * @param label The label of the phone account.
    404          * @return The builder.
    405          * @hide
    406          */
    407         public Builder setLabel(CharSequence label) {
    408             this.mLabel = label;
    409             return this;
    410         }
    411 
    412         /**
    413          * Sets the address. See {@link PhoneAccount#getAddress}.
    414          *
    415          * @param value The address of the phone account.
    416          * @return The builder.
    417          */
    418         public Builder setAddress(Uri value) {
    419             this.mAddress = value;
    420             return this;
    421         }
    422 
    423         /**
    424          * Sets the subscription address. See {@link PhoneAccount#getSubscriptionAddress}.
    425          *
    426          * @param value The subscription address.
    427          * @return The builder.
    428          */
    429         public Builder setSubscriptionAddress(Uri value) {
    430             this.mSubscriptionAddress = value;
    431             return this;
    432         }
    433 
    434         /**
    435          * Sets the capabilities. See {@link PhoneAccount#getCapabilities}.
    436          *
    437          * @param value The capabilities to set.
    438          * @return The builder.
    439          */
    440         public Builder setCapabilities(int value) {
    441             this.mCapabilities = value;
    442             return this;
    443         }
    444 
    445         /**
    446          * Sets the icon. See {@link PhoneAccount#getIcon}.
    447          *
    448          * @param icon The icon to set.
    449          */
    450         public Builder setIcon(Icon icon) {
    451             mIcon = icon;
    452             return this;
    453         }
    454 
    455         /**
    456          * Sets the highlight color. See {@link PhoneAccount#getHighlightColor}.
    457          *
    458          * @param value The highlight color.
    459          * @return The builder.
    460          */
    461         public Builder setHighlightColor(int value) {
    462             this.mHighlightColor = value;
    463             return this;
    464         }
    465 
    466         /**
    467          * Sets the short description. See {@link PhoneAccount#getShortDescription}.
    468          *
    469          * @param value The short description.
    470          * @return The builder.
    471          */
    472         public Builder setShortDescription(CharSequence value) {
    473             this.mShortDescription = value;
    474             return this;
    475         }
    476 
    477         /**
    478          * Specifies an additional URI scheme supported by the {@link PhoneAccount}.
    479          *
    480          * @param uriScheme The URI scheme.
    481          * @return The builder.
    482          */
    483         public Builder addSupportedUriScheme(String uriScheme) {
    484             if (!TextUtils.isEmpty(uriScheme) && !mSupportedUriSchemes.contains(uriScheme)) {
    485                 this.mSupportedUriSchemes.add(uriScheme);
    486             }
    487             return this;
    488         }
    489 
    490         /**
    491          * Specifies the URI schemes supported by the {@link PhoneAccount}.
    492          *
    493          * @param uriSchemes The URI schemes.
    494          * @return The builder.
    495          */
    496         public Builder setSupportedUriSchemes(List<String> uriSchemes) {
    497             mSupportedUriSchemes.clear();
    498 
    499             if (uriSchemes != null && !uriSchemes.isEmpty()) {
    500                 for (String uriScheme : uriSchemes) {
    501                     addSupportedUriScheme(uriScheme);
    502                 }
    503             }
    504             return this;
    505         }
    506 
    507         /**
    508          * Specifies the extras associated with the {@link PhoneAccount}.
    509          * <p>
    510          * {@code PhoneAccount}s only support extra values of type: {@link String}, {@link Integer},
    511          * and {@link Boolean}.  Extras which are not of these types are ignored.
    512          *
    513          * @param extras
    514          * @return
    515          */
    516         public Builder setExtras(Bundle extras) {
    517             mExtras = extras;
    518             return this;
    519         }
    520 
    521         /**
    522          * Sets the enabled state of the phone account.
    523          *
    524          * @param isEnabled The enabled state.
    525          * @return The builder.
    526          * @hide
    527          */
    528         public Builder setIsEnabled(boolean isEnabled) {
    529             mIsEnabled = isEnabled;
    530             return this;
    531         }
    532 
    533         /**
    534          * Sets the group Id of the {@link PhoneAccount}. When a new {@link PhoneAccount} is
    535          * registered to Telecom, it will replace another {@link PhoneAccount} that is already
    536          * registered in Telecom and take on the current user defaults and enabled status. There can
    537          * only be one {@link PhoneAccount} with a non-empty group number registered to Telecom at a
    538          * time. By default, there is no group Id for a {@link PhoneAccount} (an empty String). Only
    539          * grouped {@link PhoneAccount}s with the same {@link ConnectionService} can be replaced.
    540          * @param groupId The group Id of the {@link PhoneAccount} that will replace any other
    541          * registered {@link PhoneAccount} in Telecom with the same Group Id.
    542          * @return The builder
    543          * @hide
    544          */
    545         public Builder setGroupId(String groupId) {
    546             if (groupId != null) {
    547                 mGroupId = groupId;
    548             } else {
    549                 mGroupId = "";
    550             }
    551             return this;
    552         }
    553 
    554         /**
    555          * Sets the audio routes supported by this {@link PhoneAccount}.
    556          *
    557          * @param routes bit mask of available routes.
    558          * @return The builder.
    559          * @hide
    560          */
    561         public Builder setSupportedAudioRoutes(int routes) {
    562             mSupportedAudioRoutes = routes;
    563             return this;
    564         }
    565 
    566         /**
    567          * Creates an instance of a {@link PhoneAccount} based on the current builder settings.
    568          *
    569          * @return The {@link PhoneAccount}.
    570          */
    571         public PhoneAccount build() {
    572             // If no supported URI schemes were defined, assume "tel" is supported.
    573             if (mSupportedUriSchemes.isEmpty()) {
    574                 addSupportedUriScheme(SCHEME_TEL);
    575             }
    576 
    577             return new PhoneAccount(
    578                     mAccountHandle,
    579                     mAddress,
    580                     mSubscriptionAddress,
    581                     mCapabilities,
    582                     mIcon,
    583                     mHighlightColor,
    584                     mLabel,
    585                     mShortDescription,
    586                     mSupportedUriSchemes,
    587                     mExtras,
    588                     mSupportedAudioRoutes,
    589                     mIsEnabled,
    590                     mGroupId);
    591         }
    592     }
    593 
    594     private PhoneAccount(
    595             PhoneAccountHandle account,
    596             Uri address,
    597             Uri subscriptionAddress,
    598             int capabilities,
    599             Icon icon,
    600             int highlightColor,
    601             CharSequence label,
    602             CharSequence shortDescription,
    603             List<String> supportedUriSchemes,
    604             Bundle extras,
    605             int supportedAudioRoutes,
    606             boolean isEnabled,
    607             String groupId) {
    608         mAccountHandle = account;
    609         mAddress = address;
    610         mSubscriptionAddress = subscriptionAddress;
    611         mCapabilities = capabilities;
    612         mIcon = icon;
    613         mHighlightColor = highlightColor;
    614         mLabel = label;
    615         mShortDescription = shortDescription;
    616         mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes);
    617         mExtras = extras;
    618         mSupportedAudioRoutes = supportedAudioRoutes;
    619         mIsEnabled = isEnabled;
    620         mGroupId = groupId;
    621     }
    622 
    623     public static Builder builder(
    624             PhoneAccountHandle accountHandle,
    625             CharSequence label) {
    626         return new Builder(accountHandle, label);
    627     }
    628 
    629     /**
    630      * Returns a builder initialized with the current {@link PhoneAccount} instance.
    631      *
    632      * @return The builder.
    633      */
    634     public Builder toBuilder() { return new Builder(this); }
    635 
    636     /**
    637      * The unique identifier of this {@code PhoneAccount}.
    638      *
    639      * @return A {@code PhoneAccountHandle}.
    640      */
    641     public PhoneAccountHandle getAccountHandle() {
    642         return mAccountHandle;
    643     }
    644 
    645     /**
    646      * The address (e.g., a phone number) associated with this {@code PhoneAccount}. This
    647      * represents the destination from which outgoing calls using this {@code PhoneAccount}
    648      * will appear to come, if applicable, and the destination to which incoming calls using this
    649      * {@code PhoneAccount} may be addressed.
    650      *
    651      * @return A address expressed as a {@code Uri}, for example, a phone number.
    652      */
    653     public Uri getAddress() {
    654         return mAddress;
    655     }
    656 
    657     /**
    658      * The raw callback number used for this {@code PhoneAccount}, as distinct from
    659      * {@link #getAddress()}. For the majority of {@code PhoneAccount}s this should be registered
    660      * as {@code null}.  It is used by the system for SIM-based {@code PhoneAccount} registration
    661      * where {@link android.telephony.TelephonyManager#setLine1NumberForDisplay(String, String)}
    662      * has been used to alter the callback number.
    663      * <p>
    664      *
    665      * @return The subscription number, suitable for display to the user.
    666      */
    667     public Uri getSubscriptionAddress() {
    668         return mSubscriptionAddress;
    669     }
    670 
    671     /**
    672      * The capabilities of this {@code PhoneAccount}.
    673      *
    674      * @return A bit field of flags describing this {@code PhoneAccount}'s capabilities.
    675      */
    676     public int getCapabilities() {
    677         return mCapabilities;
    678     }
    679 
    680     /**
    681      * Determines if this {@code PhoneAccount} has a capabilities specified by the passed in
    682      * bit mask.
    683      *
    684      * @param capability The capabilities to check.
    685      * @return {@code true} if the phone account has the capability.
    686      */
    687     public boolean hasCapabilities(int capability) {
    688         return (mCapabilities & capability) == capability;
    689     }
    690 
    691     /**
    692      * Determines if this {@code PhoneAccount} has routes specified by the passed in bit mask.
    693      *
    694      * @param route The routes to check.
    695      * @return {@code true} if the phone account has the routes.
    696      * @hide
    697      */
    698     public boolean hasAudioRoutes(int routes) {
    699         return (mSupportedAudioRoutes & routes) == routes;
    700     }
    701 
    702     /**
    703      * A short label describing a {@code PhoneAccount}.
    704      *
    705      * @return A label for this {@code PhoneAccount}.
    706      */
    707     public CharSequence getLabel() {
    708         return mLabel;
    709     }
    710 
    711     /**
    712      * A short paragraph describing this {@code PhoneAccount}.
    713      *
    714      * @return A description for this {@code PhoneAccount}.
    715      */
    716     public CharSequence getShortDescription() {
    717         return mShortDescription;
    718     }
    719 
    720     /**
    721      * The URI schemes supported by this {@code PhoneAccount}.
    722      *
    723      * @return The URI schemes.
    724      */
    725     public List<String> getSupportedUriSchemes() {
    726         return mSupportedUriSchemes;
    727     }
    728 
    729     /**
    730      * The extras associated with this {@code PhoneAccount}.
    731      * <p>
    732      * A {@link ConnectionService} may provide implementation specific information about the
    733      * {@link PhoneAccount} via the extras.
    734      *
    735      * @return The extras.
    736      */
    737     public Bundle getExtras() {
    738         return mExtras;
    739     }
    740 
    741     /**
    742      * The audio routes supported by this {@code PhoneAccount}.
    743      *
    744      * @hide
    745      */
    746     public int getSupportedAudioRoutes() {
    747         return mSupportedAudioRoutes;
    748     }
    749 
    750     /**
    751      * The icon to represent this {@code PhoneAccount}.
    752      *
    753      * @return The icon.
    754      */
    755     public Icon getIcon() {
    756         return mIcon;
    757     }
    758 
    759     /**
    760      * Indicates whether the user has enabled this {@code PhoneAccount} or not. This value is only
    761      * populated for {@code PhoneAccount}s returned by {@link TelecomManager#getPhoneAccount}.
    762      *
    763      * @return {@code true} if the account is enabled by the user, {@code false} otherwise.
    764      */
    765     public boolean isEnabled() {
    766         return mIsEnabled;
    767     }
    768 
    769     /**
    770      * A non-empty {@link String} representing the group that A {@link PhoneAccount} is in or an
    771      * empty {@link String} if the {@link PhoneAccount} is not in a group. If this
    772      * {@link PhoneAccount} is in a group, this new {@link PhoneAccount} will replace a registered
    773      * {@link PhoneAccount} that is in the same group. When the {@link PhoneAccount} is replaced,
    774      * its user defined defaults and enabled status will also pass to this new {@link PhoneAccount}.
    775      * Only {@link PhoneAccount}s that share the same {@link ConnectionService} can be replaced.
    776      *
    777      * @return A non-empty String Id if this {@link PhoneAccount} belongs to a group.
    778      * @hide
    779      */
    780     public String getGroupId() {
    781         return mGroupId;
    782     }
    783 
    784     /**
    785      * Determines if the {@link PhoneAccount} supports calls to/from addresses with a specified URI
    786      * scheme.
    787      *
    788      * @param uriScheme The URI scheme to check.
    789      * @return {@code true} if the {@code PhoneAccount} supports calls to/from addresses with the
    790      * specified URI scheme.
    791      */
    792     public boolean supportsUriScheme(String uriScheme) {
    793         if (mSupportedUriSchemes == null || uriScheme == null) {
    794             return false;
    795         }
    796 
    797         for (String scheme : mSupportedUriSchemes) {
    798             if (scheme != null && scheme.equals(uriScheme)) {
    799                 return true;
    800             }
    801         }
    802         return false;
    803     }
    804 
    805     /**
    806      * A highlight color to use in displaying information about this {@code PhoneAccount}.
    807      *
    808      * @return A hexadecimal color value.
    809      */
    810     public int getHighlightColor() {
    811         return mHighlightColor;
    812     }
    813 
    814     /**
    815      * Sets the enabled state of the phone account.
    816      * @hide
    817      */
    818     public void setIsEnabled(boolean isEnabled) {
    819         mIsEnabled = isEnabled;
    820     }
    821 
    822     /**
    823      * @return {@code true} if the {@link PhoneAccount} is self-managed, {@code false} otherwise.
    824      * @hide
    825      */
    826     public boolean isSelfManaged() {
    827         return (mCapabilities & CAPABILITY_SELF_MANAGED) == CAPABILITY_SELF_MANAGED;
    828     }
    829 
    830     //
    831     // Parcelable implementation
    832     //
    833 
    834     @Override
    835     public int describeContents() {
    836         return 0;
    837     }
    838 
    839     @Override
    840     public void writeToParcel(Parcel out, int flags) {
    841         if (mAccountHandle == null) {
    842             out.writeInt(0);
    843         } else {
    844             out.writeInt(1);
    845             mAccountHandle.writeToParcel(out, flags);
    846         }
    847         if (mAddress == null) {
    848             out.writeInt(0);
    849         } else {
    850             out.writeInt(1);
    851             mAddress.writeToParcel(out, flags);
    852         }
    853         if (mSubscriptionAddress == null) {
    854             out.writeInt(0);
    855         } else {
    856             out.writeInt(1);
    857             mSubscriptionAddress.writeToParcel(out, flags);
    858         }
    859         out.writeInt(mCapabilities);
    860         out.writeInt(mHighlightColor);
    861         out.writeCharSequence(mLabel);
    862         out.writeCharSequence(mShortDescription);
    863         out.writeStringList(mSupportedUriSchemes);
    864 
    865         if (mIcon == null) {
    866             out.writeInt(0);
    867         } else {
    868             out.writeInt(1);
    869             mIcon.writeToParcel(out, flags);
    870         }
    871         out.writeByte((byte) (mIsEnabled ? 1 : 0));
    872         out.writeBundle(mExtras);
    873         out.writeString(mGroupId);
    874         out.writeInt(mSupportedAudioRoutes);
    875     }
    876 
    877     public static final Creator<PhoneAccount> CREATOR
    878             = new Creator<PhoneAccount>() {
    879         @Override
    880         public PhoneAccount createFromParcel(Parcel in) {
    881             return new PhoneAccount(in);
    882         }
    883 
    884         @Override
    885         public PhoneAccount[] newArray(int size) {
    886             return new PhoneAccount[size];
    887         }
    888     };
    889 
    890     private PhoneAccount(Parcel in) {
    891         if (in.readInt() > 0) {
    892             mAccountHandle = PhoneAccountHandle.CREATOR.createFromParcel(in);
    893         } else {
    894             mAccountHandle = null;
    895         }
    896         if (in.readInt() > 0) {
    897             mAddress = Uri.CREATOR.createFromParcel(in);
    898         } else {
    899             mAddress = null;
    900         }
    901         if (in.readInt() > 0) {
    902             mSubscriptionAddress = Uri.CREATOR.createFromParcel(in);
    903         } else {
    904             mSubscriptionAddress = null;
    905         }
    906         mCapabilities = in.readInt();
    907         mHighlightColor = in.readInt();
    908         mLabel = in.readCharSequence();
    909         mShortDescription = in.readCharSequence();
    910         mSupportedUriSchemes = Collections.unmodifiableList(in.createStringArrayList());
    911         if (in.readInt() > 0) {
    912             mIcon = Icon.CREATOR.createFromParcel(in);
    913         } else {
    914             mIcon = null;
    915         }
    916         mIsEnabled = in.readByte() == 1;
    917         mExtras = in.readBundle();
    918         mGroupId = in.readString();
    919         mSupportedAudioRoutes = in.readInt();
    920     }
    921 
    922     @Override
    923     public String toString() {
    924         StringBuilder sb = new StringBuilder().append("[[")
    925                 .append(mIsEnabled ? 'X' : ' ')
    926                 .append("] PhoneAccount: ")
    927                 .append(mAccountHandle)
    928                 .append(" Capabilities: ")
    929                 .append(capabilitiesToString())
    930                 .append(" Audio Routes: ")
    931                 .append(audioRoutesToString())
    932                 .append(" Schemes: ");
    933         for (String scheme : mSupportedUriSchemes) {
    934             sb.append(scheme)
    935                     .append(" ");
    936         }
    937         sb.append(" Extras: ");
    938         sb.append(mExtras);
    939         sb.append(" GroupId: ");
    940         sb.append(Log.pii(mGroupId));
    941         sb.append("]");
    942         return sb.toString();
    943     }
    944 
    945     /**
    946      * Generates a string representation of a capabilities bitmask.
    947      *
    948      * @param capabilities The capabilities bitmask.
    949      * @return String representation of the capabilities bitmask.
    950      */
    951     private String capabilitiesToString() {
    952         StringBuilder sb = new StringBuilder();
    953         if (hasCapabilities(CAPABILITY_SELF_MANAGED)) {
    954             sb.append("SelfManaged ");
    955         }
    956         if (hasCapabilities(CAPABILITY_SUPPORTS_VIDEO_CALLING)) {
    957             sb.append("SuppVideo ");
    958         }
    959         if (hasCapabilities(CAPABILITY_VIDEO_CALLING)) {
    960             sb.append("Video ");
    961         }
    962         if (hasCapabilities(CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE)) {
    963             sb.append("Presence ");
    964         }
    965         if (hasCapabilities(CAPABILITY_CALL_PROVIDER)) {
    966             sb.append("CallProvider ");
    967         }
    968         if (hasCapabilities(CAPABILITY_CALL_SUBJECT)) {
    969             sb.append("CallSubject ");
    970         }
    971         if (hasCapabilities(CAPABILITY_CONNECTION_MANAGER)) {
    972             sb.append("ConnectionMgr ");
    973         }
    974         if (hasCapabilities(CAPABILITY_EMERGENCY_CALLS_ONLY)) {
    975             sb.append("EmergOnly ");
    976         }
    977         if (hasCapabilities(CAPABILITY_MULTI_USER)) {
    978             sb.append("MultiUser ");
    979         }
    980         if (hasCapabilities(CAPABILITY_PLACE_EMERGENCY_CALLS)) {
    981             sb.append("PlaceEmerg ");
    982         }
    983         if (hasCapabilities(CAPABILITY_EMERGENCY_VIDEO_CALLING)) {
    984             sb.append("EmergVideo ");
    985         }
    986         if (hasCapabilities(CAPABILITY_SIM_SUBSCRIPTION)) {
    987             sb.append("SimSub ");
    988         }
    989         if (hasCapabilities(CAPABILITY_RTT)) {
    990             sb.append("Rtt");
    991         }
    992         return sb.toString();
    993     }
    994 
    995     private String audioRoutesToString() {
    996         StringBuilder sb = new StringBuilder();
    997 
    998         if (hasAudioRoutes(CallAudioState.ROUTE_BLUETOOTH)) {
    999             sb.append("B");
   1000         }
   1001         if (hasAudioRoutes(CallAudioState.ROUTE_EARPIECE)) {
   1002             sb.append("E");
   1003         }
   1004         if (hasAudioRoutes(CallAudioState.ROUTE_SPEAKER)) {
   1005             sb.append("S");
   1006         }
   1007         if (hasAudioRoutes(CallAudioState.ROUTE_WIRED_HEADSET)) {
   1008             sb.append("W");
   1009         }
   1010 
   1011         return sb.toString();
   1012     }
   1013 }
   1014