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