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.net.Uri; 30 import android.os.Parcel; 31 import android.os.Parcelable; 32 import android.text.TextUtils; 33 34 import java.lang.String; 35 import java.util.ArrayList; 36 import java.util.Collections; 37 import java.util.List; 38 import java.util.MissingResourceException; 39 40 /** 41 * Represents a distinct method to place or receive a phone call. Apps which can place calls and 42 * want those calls to be integrated into the dialer and in-call UI should build an instance of 43 * this class and register it with the system using {@link TelecomManager#registerPhoneAccount}. 44 * <p> 45 * {@link TelecomManager} uses registered {@link PhoneAccount}s to present the user with 46 * alternative options when placing a phone call. When building a {@link PhoneAccount}, the app 47 * should supply a valid {@link PhoneAccountHandle} that references the {@link ConnectionService} 48 * implementation Telecom will use to interact with the app. 49 * @hide 50 */ 51 @SystemApi 52 public class PhoneAccount implements Parcelable { 53 54 /** 55 * Flag indicating that this {@code PhoneAccount} can act as a connection manager for 56 * other connections. The {@link ConnectionService} associated with this {@code PhoneAccount} 57 * will be allowed to manage phone calls including using its own proprietary phone-call 58 * implementation (like VoIP calling) to make calls instead of the telephony stack. 59 * <p> 60 * When a user opts to place a call using the SIM-based telephony stack, the 61 * {@link ConnectionService} associated with this {@code PhoneAccount} will be attempted first 62 * if the user has explicitly selected it to be used as the default connection manager. 63 * <p> 64 * See {@link #getCapabilities} 65 */ 66 public static final int CAPABILITY_CONNECTION_MANAGER = 0x1; 67 68 /** 69 * Flag indicating that this {@code PhoneAccount} can make phone calls in place of 70 * traditional SIM-based telephony calls. This account will be treated as a distinct method 71 * for placing calls alongside the traditional SIM-based telephony stack. This flag is 72 * distinct from {@link #CAPABILITY_CONNECTION_MANAGER} in that it is not allowed to manage 73 * or place calls from the built-in telephony stack. 74 * <p> 75 * See {@link #getCapabilities} 76 * <p> 77 * {@hide} 78 */ 79 public static final int CAPABILITY_CALL_PROVIDER = 0x2; 80 81 /** 82 * Flag indicating that this {@code PhoneAccount} represents a built-in PSTN SIM 83 * subscription. 84 * <p> 85 * Only the Android framework can register a {@code PhoneAccount} having this capability. 86 * <p> 87 * See {@link #getCapabilities} 88 */ 89 public static final int CAPABILITY_SIM_SUBSCRIPTION = 0x4; 90 91 /** 92 * Flag indicating that this {@code PhoneAccount} is capable of placing video calls. 93 * <p> 94 * See {@link #getCapabilities} 95 * @hide 96 */ 97 public static final int CAPABILITY_VIDEO_CALLING = 0x8; 98 99 /** 100 * Flag indicating that this {@code PhoneAccount} is capable of placing emergency calls. 101 * By default all PSTN {@code PhoneAccount}s are capable of placing emergency calls. 102 * <p> 103 * See {@link #getCapabilities} 104 */ 105 public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 0x10; 106 107 /** 108 * Flag indicating that this {@code PhoneAccount} is capable of being used by all users. This 109 * should only be used by system apps (and will be ignored for all other apps trying to use it). 110 * <p> 111 * See {@link #getCapabilities} 112 * @hide 113 */ 114 public static final int CAPABILITY_MULTI_USER = 0x20; 115 116 /** 117 * URI scheme for telephone number URIs. 118 */ 119 public static final String SCHEME_TEL = "tel"; 120 121 /** 122 * URI scheme for voicemail URIs. 123 */ 124 public static final String SCHEME_VOICEMAIL = "voicemail"; 125 126 /** 127 * URI scheme for SIP URIs. 128 */ 129 public static final String SCHEME_SIP = "sip"; 130 131 /** 132 * Indicating no icon tint is set. 133 */ 134 public static final int NO_ICON_TINT = 0; 135 136 /** 137 * Indicating no hightlight color is set. 138 */ 139 public static final int NO_HIGHLIGHT_COLOR = 0; 140 141 /** 142 * Indicating no resource ID is set. 143 */ 144 public static final int NO_RESOURCE_ID = -1; 145 146 private final PhoneAccountHandle mAccountHandle; 147 private final Uri mAddress; 148 private final Uri mSubscriptionAddress; 149 private final int mCapabilities; 150 private final int mIconResId; 151 private final String mIconPackageName; 152 private final Bitmap mIconBitmap; 153 private final int mIconTint; 154 private final int mHighlightColor; 155 private final CharSequence mLabel; 156 private final CharSequence mShortDescription; 157 private final List<String> mSupportedUriSchemes; 158 159 /** 160 * Helper class for creating a {@link PhoneAccount}. 161 */ 162 public static class Builder { 163 private PhoneAccountHandle mAccountHandle; 164 private Uri mAddress; 165 private Uri mSubscriptionAddress; 166 private int mCapabilities; 167 private int mIconResId; 168 private String mIconPackageName; 169 private Bitmap mIconBitmap; 170 private int mIconTint = NO_ICON_TINT; 171 private int mHighlightColor = NO_HIGHLIGHT_COLOR; 172 private CharSequence mLabel; 173 private CharSequence mShortDescription; 174 private List<String> mSupportedUriSchemes = new ArrayList<String>(); 175 176 /** 177 * Creates a builder with the specified {@link PhoneAccountHandle} and label. 178 */ Builder(PhoneAccountHandle accountHandle, CharSequence label)179 public Builder(PhoneAccountHandle accountHandle, CharSequence label) { 180 this.mAccountHandle = accountHandle; 181 this.mLabel = label; 182 } 183 184 /** 185 * Creates an instance of the {@link PhoneAccount.Builder} from an existing 186 * {@link PhoneAccount}. 187 * 188 * @param phoneAccount The {@link PhoneAccount} used to initialize the builder. 189 */ Builder(PhoneAccount phoneAccount)190 public Builder(PhoneAccount phoneAccount) { 191 mAccountHandle = phoneAccount.getAccountHandle(); 192 mAddress = phoneAccount.getAddress(); 193 mSubscriptionAddress = phoneAccount.getSubscriptionAddress(); 194 mCapabilities = phoneAccount.getCapabilities(); 195 mIconResId = phoneAccount.getIconResId(); 196 mIconPackageName = phoneAccount.getIconPackageName(); 197 mIconBitmap = phoneAccount.getIconBitmap(); 198 mIconTint = phoneAccount.getIconTint(); 199 mHighlightColor = phoneAccount.getHighlightColor(); 200 mLabel = phoneAccount.getLabel(); 201 mShortDescription = phoneAccount.getShortDescription(); 202 mSupportedUriSchemes.addAll(phoneAccount.getSupportedUriSchemes()); 203 } 204 205 /** @hide */ setAccountHandle(PhoneAccountHandle accountHandle)206 public Builder setAccountHandle(PhoneAccountHandle accountHandle) { 207 mAccountHandle = accountHandle; 208 return this; 209 } 210 211 /** 212 * Sets the address. See {@link PhoneAccount#getAddress}. 213 * 214 * @param value The address of the phone account. 215 * @return The builder. 216 */ setAddress(Uri value)217 public Builder setAddress(Uri value) { 218 this.mAddress = value; 219 return this; 220 } 221 222 /** 223 * Sets the subscription address. See {@link PhoneAccount#getSubscriptionAddress}. 224 * 225 * @param value The subscription address. 226 * @return The builder. 227 */ setSubscriptionAddress(Uri value)228 public Builder setSubscriptionAddress(Uri value) { 229 this.mSubscriptionAddress = value; 230 return this; 231 } 232 233 /** 234 * Sets the capabilities. See {@link PhoneAccount#getCapabilities}. 235 * 236 * @param value The capabilities to set. 237 * @return The builder. 238 */ setCapabilities(int value)239 public Builder setCapabilities(int value) { 240 this.mCapabilities = value; 241 return this; 242 } 243 244 /** 245 * Sets the icon. See {@link PhoneAccount#createIconDrawable}. 246 * 247 * @param packageContext The package from which to load an icon. 248 * @param iconResId The resource in {@code iconPackageName} representing the icon. 249 * @return The builder. 250 */ setIcon(Context packageContext, int iconResId)251 public Builder setIcon(Context packageContext, int iconResId) { 252 return setIcon(packageContext.getPackageName(), iconResId); 253 } 254 255 /** 256 * Sets the icon. See {@link PhoneAccount#createIconDrawable}. 257 * 258 * @param iconPackageName The package from which to load an icon. 259 * @param iconResId The resource in {@code iconPackageName} representing the icon. 260 * @return The builder. 261 */ setIcon(String iconPackageName, int iconResId)262 public Builder setIcon(String iconPackageName, int iconResId) { 263 return setIcon(iconPackageName, iconResId, NO_ICON_TINT); 264 } 265 266 /** 267 * Sets the icon. See {@link PhoneAccount#createIconDrawable}. 268 * 269 * @param packageContext The package from which to load an icon. 270 * @param iconResId The resource in {@code iconPackageName} representing the icon. 271 * @param iconTint A color with which to tint this icon. 272 * @return The builder. 273 */ setIcon(Context packageContext, int iconResId, int iconTint)274 public Builder setIcon(Context packageContext, int iconResId, int iconTint) { 275 return setIcon(packageContext.getPackageName(), iconResId, iconTint); 276 } 277 278 /** 279 * Sets the icon. See {@link PhoneAccount#createIconDrawable}. 280 * 281 * @param iconPackageName The package from which to load an icon. 282 * @param iconResId The resource in {@code iconPackageName} representing the icon. 283 * @param iconTint A color with which to tint this icon. 284 * @return The builder. 285 */ setIcon(String iconPackageName, int iconResId, int iconTint)286 public Builder setIcon(String iconPackageName, int iconResId, int iconTint) { 287 this.mIconPackageName = iconPackageName; 288 this.mIconResId = iconResId; 289 this.mIconTint = iconTint; 290 return this; 291 } 292 293 /** 294 * Sets the icon. See {@link PhoneAccount#createIconDrawable}. 295 * 296 * @param iconBitmap The icon bitmap. 297 * @return The builder. 298 */ setIcon(Bitmap iconBitmap)299 public Builder setIcon(Bitmap iconBitmap) { 300 this.mIconBitmap = iconBitmap; 301 this.mIconPackageName = null; 302 this.mIconResId = NO_RESOURCE_ID; 303 this.mIconTint = NO_ICON_TINT; 304 return this; 305 } 306 307 /** 308 * Sets the highlight color. See {@link PhoneAccount#getHighlightColor}. 309 * 310 * @param value The highlight color. 311 * @return The builder. 312 */ setHighlightColor(int value)313 public Builder setHighlightColor(int value) { 314 this.mHighlightColor = value; 315 return this; 316 } 317 318 /** 319 * Sets the short description. See {@link PhoneAccount#getShortDescription}. 320 * 321 * @param value The short description. 322 * @return The builder. 323 */ setShortDescription(CharSequence value)324 public Builder setShortDescription(CharSequence value) { 325 this.mShortDescription = value; 326 return this; 327 } 328 329 /** 330 * Specifies an additional URI scheme supported by the {@link PhoneAccount}. 331 * 332 * @param uriScheme The URI scheme. 333 * @return The builder. 334 * @hide 335 */ addSupportedUriScheme(String uriScheme)336 public Builder addSupportedUriScheme(String uriScheme) { 337 if (!TextUtils.isEmpty(uriScheme) && !mSupportedUriSchemes.contains(uriScheme)) { 338 this.mSupportedUriSchemes.add(uriScheme); 339 } 340 return this; 341 } 342 343 /** 344 * Specifies the URI schemes supported by the {@link PhoneAccount}. 345 * 346 * @param uriSchemes The URI schemes. 347 * @return The builder. 348 */ setSupportedUriSchemes(List<String> uriSchemes)349 public Builder setSupportedUriSchemes(List<String> uriSchemes) { 350 mSupportedUriSchemes.clear(); 351 352 if (uriSchemes != null && !uriSchemes.isEmpty()) { 353 for (String uriScheme : uriSchemes) { 354 addSupportedUriScheme(uriScheme); 355 } 356 } 357 return this; 358 } 359 360 /** 361 * Creates an instance of a {@link PhoneAccount} based on the current builder settings. 362 * 363 * @return The {@link PhoneAccount}. 364 */ build()365 public PhoneAccount build() { 366 // If no supported URI schemes were defined, assume "tel" is supported. 367 if (mSupportedUriSchemes.isEmpty()) { 368 addSupportedUriScheme(SCHEME_TEL); 369 } 370 371 return new PhoneAccount( 372 mAccountHandle, 373 mAddress, 374 mSubscriptionAddress, 375 mCapabilities, 376 mIconResId, 377 mIconPackageName, 378 mIconBitmap, 379 mIconTint, 380 mHighlightColor, 381 mLabel, 382 mShortDescription, 383 mSupportedUriSchemes); 384 } 385 } 386 PhoneAccount( PhoneAccountHandle account, Uri address, Uri subscriptionAddress, int capabilities, int iconResId, String iconPackageName, Bitmap iconBitmap, int iconTint, int highlightColor, CharSequence label, CharSequence shortDescription, List<String> supportedUriSchemes)387 private PhoneAccount( 388 PhoneAccountHandle account, 389 Uri address, 390 Uri subscriptionAddress, 391 int capabilities, 392 int iconResId, 393 String iconPackageName, 394 Bitmap iconBitmap, 395 int iconTint, 396 int highlightColor, 397 CharSequence label, 398 CharSequence shortDescription, 399 List<String> supportedUriSchemes) { 400 mAccountHandle = account; 401 mAddress = address; 402 mSubscriptionAddress = subscriptionAddress; 403 mCapabilities = capabilities; 404 mIconResId = iconResId; 405 mIconPackageName = iconPackageName; 406 mIconBitmap = iconBitmap; 407 mIconTint = iconTint; 408 mHighlightColor = highlightColor; 409 mLabel = label; 410 mShortDescription = shortDescription; 411 mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes); 412 } 413 builder( PhoneAccountHandle accountHandle, CharSequence label)414 public static Builder builder( 415 PhoneAccountHandle accountHandle, 416 CharSequence label) { 417 return new Builder(accountHandle, label); 418 } 419 420 /** 421 * Returns a builder initialized with the current {@link PhoneAccount} instance. 422 * 423 * @return The builder. 424 * @hide 425 */ toBuilder()426 public Builder toBuilder() { return new Builder(this); } 427 428 /** 429 * The unique identifier of this {@code PhoneAccount}. 430 * 431 * @return A {@code PhoneAccountHandle}. 432 */ getAccountHandle()433 public PhoneAccountHandle getAccountHandle() { 434 return mAccountHandle; 435 } 436 437 /** 438 * The address (e.g., a phone number) associated with this {@code PhoneAccount}. This 439 * represents the destination from which outgoing calls using this {@code PhoneAccount} 440 * will appear to come, if applicable, and the destination to which incoming calls using this 441 * {@code PhoneAccount} may be addressed. 442 * 443 * @return A address expressed as a {@code Uri}, for example, a phone number. 444 */ getAddress()445 public Uri getAddress() { 446 return mAddress; 447 } 448 449 /** 450 * The raw callback number used for this {@code PhoneAccount}, as distinct from 451 * {@link #getAddress()}. For the majority of {@code PhoneAccount}s this should be registered 452 * as {@code null}. It is used by the system for SIM-based {@code PhoneAccount} registration 453 * where {@link android.telephony.TelephonyManager#setLine1NumberForDisplay(String, String)} 454 * has been used to alter the callback number. 455 * <p> 456 * 457 * @return The subscription number, suitable for display to the user. 458 */ getSubscriptionAddress()459 public Uri getSubscriptionAddress() { 460 return mSubscriptionAddress; 461 } 462 463 /** 464 * The capabilities of this {@code PhoneAccount}. 465 * 466 * @return A bit field of flags describing this {@code PhoneAccount}'s capabilities. 467 */ getCapabilities()468 public int getCapabilities() { 469 return mCapabilities; 470 } 471 472 /** 473 * Determines if this {@code PhoneAccount} has a capabilities specified by the passed in 474 * bit mask. 475 * 476 * @param capability The capabilities to check. 477 * @return {@code True} if the phone account has the capability. 478 */ hasCapabilities(int capability)479 public boolean hasCapabilities(int capability) { 480 return (mCapabilities & capability) == capability; 481 } 482 483 /** 484 * A short label describing a {@code PhoneAccount}. 485 * 486 * @return A label for this {@code PhoneAccount}. 487 */ getLabel()488 public CharSequence getLabel() { 489 return mLabel; 490 } 491 492 /** 493 * A short paragraph describing this {@code PhoneAccount}. 494 * 495 * @return A description for this {@code PhoneAccount}. 496 */ getShortDescription()497 public CharSequence getShortDescription() { 498 return mShortDescription; 499 } 500 501 /** 502 * The URI schemes supported by this {@code PhoneAccount}. 503 * 504 * @return The URI schemes. 505 */ getSupportedUriSchemes()506 public List<String> getSupportedUriSchemes() { 507 return mSupportedUriSchemes; 508 } 509 510 /** 511 * Determines if the {@link PhoneAccount} supports calls to/from addresses with a specified URI 512 * scheme. 513 * 514 * @param uriScheme The URI scheme to check. 515 * @return {@code True} if the {@code PhoneAccount} supports calls to/from addresses with the 516 * specified URI scheme. 517 */ supportsUriScheme(String uriScheme)518 public boolean supportsUriScheme(String uriScheme) { 519 if (mSupportedUriSchemes == null || uriScheme == null) { 520 return false; 521 } 522 523 for (String scheme : mSupportedUriSchemes) { 524 if (scheme != null && scheme.equals(uriScheme)) { 525 return true; 526 } 527 } 528 return false; 529 } 530 531 /** 532 * The icon resource ID for the icon of this {@code PhoneAccount}. 533 * <p> 534 * Creators of a {@code PhoneAccount} who possess the icon in static resources should prefer 535 * this method of indicating the icon rather than using {@link #getIconBitmap()}, since it 536 * leads to less resource usage. 537 * <p> 538 * Clients wishing to display a {@code PhoneAccount} should use {@link #createIconDrawable(Context)}. 539 * 540 * @return A resource ID. 541 */ getIconResId()542 public int getIconResId() { 543 return mIconResId; 544 } 545 546 /** 547 * The package name from which to load the icon of this {@code PhoneAccount}. 548 * <p> 549 * If this property is {@code null}, the resource {@link #getIconResId()} will be loaded from 550 * the package in the {@link ComponentName} of the {@link #getAccountHandle()}. 551 * <p> 552 * Clients wishing to display a {@code PhoneAccount} should use {@link #createIconDrawable(Context)}. 553 * 554 * @return A package name. 555 */ getIconPackageName()556 public String getIconPackageName() { 557 return mIconPackageName; 558 } 559 560 /** 561 * A tint to apply to the icon of this {@code PhoneAccount}. 562 * 563 * @return A hexadecimal color value. 564 */ getIconTint()565 public int getIconTint() { 566 return mIconTint; 567 } 568 569 /** 570 * A literal icon bitmap to represent this {@code PhoneAccount} in a user interface. 571 * <p> 572 * If this property is specified, it is to be considered the preferred icon. Otherwise, the 573 * resource specified by {@link #getIconResId()} should be used. 574 * <p> 575 * Clients wishing to display a {@code PhoneAccount} should use 576 * {@link #createIconDrawable(Context)}. 577 * 578 * @return A bitmap. 579 */ getIconBitmap()580 public Bitmap getIconBitmap() { 581 return mIconBitmap; 582 } 583 584 /** 585 * A highlight color to use in displaying information about this {@code PhoneAccount}. 586 * 587 * @return A hexadecimal color value. 588 */ getHighlightColor()589 public int getHighlightColor() { 590 return mHighlightColor; 591 } 592 593 /** 594 * Builds and returns an icon {@code Drawable} to represent this {@code PhoneAccount} in a user 595 * interface. Uses the properties {@link #getIconResId()}, {@link #getIconPackageName()}, and 596 * {@link #getIconBitmap()} as necessary. 597 * 598 * @param context A {@code Context} to use for loading {@code Drawable}s. 599 * 600 * @return An icon for this {@code PhoneAccount}. 601 */ createIconDrawable(Context context)602 public Drawable createIconDrawable(Context context) { 603 if (mIconBitmap != null) { 604 return new BitmapDrawable(context.getResources(), mIconBitmap); 605 } 606 607 if (mIconResId != 0) { 608 try { 609 Context packageContext = context.createPackageContext(mIconPackageName, 0); 610 try { 611 Drawable iconDrawable = packageContext.getDrawable(mIconResId); 612 if (mIconTint != NO_ICON_TINT) { 613 iconDrawable.setTint(mIconTint); 614 } 615 return iconDrawable; 616 } catch (NotFoundException | MissingResourceException e) { 617 Log.e(this, e, "Cannot find icon %d in package %s", 618 mIconResId, mIconPackageName); 619 } 620 } catch (PackageManager.NameNotFoundException e) { 621 Log.w(this, "Cannot find package %s", mIconPackageName); 622 } 623 } 624 625 return new ColorDrawable(Color.TRANSPARENT); 626 } 627 628 // 629 // Parcelable implementation 630 // 631 632 @Override describeContents()633 public int describeContents() { 634 return 0; 635 } 636 637 @Override writeToParcel(Parcel out, int flags)638 public void writeToParcel(Parcel out, int flags) { 639 if (mAccountHandle == null) { 640 out.writeInt(0); 641 } else { 642 out.writeInt(1); 643 mAccountHandle.writeToParcel(out, flags); 644 } 645 if (mAddress == null) { 646 out.writeInt(0); 647 } else { 648 out.writeInt(1); 649 mAddress.writeToParcel(out, flags); 650 } 651 if (mSubscriptionAddress == null) { 652 out.writeInt(0); 653 } else { 654 out.writeInt(1); 655 mSubscriptionAddress.writeToParcel(out, flags); 656 } 657 out.writeInt(mCapabilities); 658 out.writeInt(mIconResId); 659 out.writeString(mIconPackageName); 660 if (mIconBitmap == null) { 661 out.writeInt(0); 662 } else { 663 out.writeInt(1); 664 mIconBitmap.writeToParcel(out, flags); 665 } 666 out.writeInt(mIconTint); 667 out.writeInt(mHighlightColor); 668 out.writeCharSequence(mLabel); 669 out.writeCharSequence(mShortDescription); 670 out.writeStringList(mSupportedUriSchemes); 671 } 672 673 public static final Creator<PhoneAccount> CREATOR 674 = new Creator<PhoneAccount>() { 675 @Override 676 public PhoneAccount createFromParcel(Parcel in) { 677 return new PhoneAccount(in); 678 } 679 680 @Override 681 public PhoneAccount[] newArray(int size) { 682 return new PhoneAccount[size]; 683 } 684 }; 685 PhoneAccount(Parcel in)686 private PhoneAccount(Parcel in) { 687 if (in.readInt() > 0) { 688 mAccountHandle = PhoneAccountHandle.CREATOR.createFromParcel(in); 689 } else { 690 mAccountHandle = null; 691 } 692 if (in.readInt() > 0) { 693 mAddress = Uri.CREATOR.createFromParcel(in); 694 } else { 695 mAddress = null; 696 } 697 if (in.readInt() > 0) { 698 mSubscriptionAddress = Uri.CREATOR.createFromParcel(in); 699 } else { 700 mSubscriptionAddress = null; 701 } 702 mCapabilities = in.readInt(); 703 mIconResId = in.readInt(); 704 mIconPackageName = in.readString(); 705 if (in.readInt() > 0) { 706 mIconBitmap = Bitmap.CREATOR.createFromParcel(in); 707 } else { 708 mIconBitmap = null; 709 } 710 mIconTint = in.readInt(); 711 mHighlightColor = in.readInt(); 712 mLabel = in.readCharSequence(); 713 mShortDescription = in.readCharSequence(); 714 mSupportedUriSchemes = Collections.unmodifiableList(in.createStringArrayList()); 715 } 716 717 @Override toString()718 public String toString() { 719 StringBuilder sb = new StringBuilder().append("[PhoneAccount: ") 720 .append(mAccountHandle) 721 .append(" Capabilities: ") 722 .append(mCapabilities) 723 .append(" Schemes: "); 724 for (String scheme : mSupportedUriSchemes) { 725 sb.append(scheme) 726 .append(" "); 727 } 728 sb.append("]"); 729 return sb.toString(); 730 } 731 } 732