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