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