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