PhoneAccount.java revision 3ace54b895c97f0e98e989667238be9c96c3b40c
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.Context; 21import android.content.pm.PackageManager; 22import android.content.res.Resources.NotFoundException; 23import android.graphics.drawable.Drawable; 24import android.net.Uri; 25import android.os.Parcel; 26import android.os.Parcelable; 27import android.text.TextUtils; 28 29import java.lang.String; 30import java.util.ArrayList; 31import java.util.Collections; 32import java.util.List; 33import java.util.MissingResourceException; 34 35/** 36 * Describes a distinct account, line of service or call placement method that the system 37 * can use to place phone calls. 38 * @hide 39 */ 40@SystemApi 41public class PhoneAccount implements Parcelable { 42 43 /** 44 * Flag indicating that this {@code PhoneAccount} can act as a connection manager for 45 * other connections. The {@link ConnectionService} associated with this {@code PhoneAccount} 46 * will be allowed to manage phone calls including using its own proprietary phone-call 47 * implementation (like VoIP calling) to make calls instead of the telephony stack. 48 * <p> 49 * When a user opts to place a call using the SIM-based telephony stack, the 50 * {@link ConnectionService} associated with this {@code PhoneAccount} will be attempted first 51 * if the user has explicitly selected it to be used as the default connection manager. 52 * <p> 53 * See {@link #getCapabilities} 54 */ 55 public static final int CAPABILITY_CONNECTION_MANAGER = 0x1; 56 57 /** 58 * Flag indicating that this {@code PhoneAccount} can make phone calls in place of 59 * traditional SIM-based telephony calls. This account will be treated as a distinct method 60 * for placing calls alongside the traditional SIM-based telephony stack. This flag is 61 * distinct from {@link #CAPABILITY_CONNECTION_MANAGER} in that it is not allowed to manage 62 * calls from or use the built-in telephony stack to place its calls. 63 * <p> 64 * See {@link #getCapabilities} 65 * <p> 66 * {@hide} 67 */ 68 public static final int CAPABILITY_CALL_PROVIDER = 0x2; 69 70 /** 71 * Flag indicating that this {@code PhoneAccount} represents a built-in PSTN SIM 72 * subscription. 73 * <p> 74 * Only the Android framework can register a {@code PhoneAccount} having this capability. 75 * <p> 76 * See {@link #getCapabilities} 77 */ 78 public static final int CAPABILITY_SIM_SUBSCRIPTION = 0x4; 79 80 /** 81 * Flag indicating that this {@code PhoneAccount} is capable of placing video calls. 82 * <p> 83 * See {@link #getCapabilities} 84 * @hide 85 */ 86 public static final int CAPABILITY_VIDEO_CALLING = 0x8; 87 88 /** 89 * Flag indicating that this {@code PhoneAccount} is capable of placing emergency calls. 90 * By default all PSTN {@code PhoneAccount}s are capable of placing emergency calls. 91 * <p> 92 * See {@link #getCapabilities} 93 */ 94 public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 0x10; 95 96 /** 97 * URI scheme for telephone number URIs. 98 */ 99 public static final String SCHEME_TEL = "tel"; 100 101 /** 102 * URI scheme for voicemail URIs. 103 */ 104 public static final String SCHEME_VOICEMAIL = "voicemail"; 105 106 /** 107 * URI scheme for SIP URIs. 108 */ 109 public static final String SCHEME_SIP = "sip"; 110 111 /** 112 * Indicating no color is set. 113 */ 114 public static final int NO_COLOR = -1; 115 116 private final PhoneAccountHandle mAccountHandle; 117 private final Uri mAddress; 118 private final Uri mSubscriptionAddress; 119 private final int mCapabilities; 120 private final int mIconResId; 121 private final int mColor; 122 private final CharSequence mLabel; 123 private final CharSequence mShortDescription; 124 private final List<String> mSupportedUriSchemes; 125 126 public static class Builder { 127 private PhoneAccountHandle mAccountHandle; 128 private Uri mAddress; 129 private Uri mSubscriptionAddress; 130 private int mCapabilities; 131 private int mIconResId; 132 private int mColor = NO_COLOR; 133 private CharSequence mLabel; 134 private CharSequence mShortDescription; 135 private List<String> mSupportedUriSchemes = new ArrayList<String>(); 136 137 public Builder(PhoneAccountHandle accountHandle, CharSequence label) { 138 this.mAccountHandle = accountHandle; 139 this.mLabel = label; 140 } 141 142 /** 143 * Creates an instance of the {@link PhoneAccount.Builder} from an existing 144 * {@link PhoneAccount}. 145 * 146 * @param phoneAccount The {@link PhoneAccount} used to initialize the builder. 147 */ 148 public Builder(PhoneAccount phoneAccount) { 149 mAccountHandle = phoneAccount.getAccountHandle(); 150 mAddress = phoneAccount.getAddress(); 151 mSubscriptionAddress = phoneAccount.getSubscriptionAddress(); 152 mCapabilities = phoneAccount.getCapabilities(); 153 mIconResId = phoneAccount.getIconResId(); 154 mColor = phoneAccount.getColor(); 155 mLabel = phoneAccount.getLabel(); 156 mShortDescription = phoneAccount.getShortDescription(); 157 mSupportedUriSchemes.addAll(phoneAccount.getSupportedUriSchemes()); 158 } 159 160 public Builder setAddress(Uri value) { 161 this.mAddress = value; 162 return this; 163 } 164 165 public Builder setSubscriptionAddress(Uri value) { 166 this.mSubscriptionAddress = value; 167 return this; 168 } 169 170 public Builder setCapabilities(int value) { 171 this.mCapabilities = value; 172 return this; 173 } 174 175 public Builder setIconResId(int value) { 176 this.mIconResId = value; 177 return this; 178 } 179 180 public Builder setColor(int value) { 181 this.mColor = value; 182 return this; 183 } 184 185 public Builder setShortDescription(CharSequence value) { 186 this.mShortDescription = value; 187 return this; 188 } 189 190 /** 191 * Specifies an additional URI scheme supported by the {@link PhoneAccount}. 192 * 193 * @param uriScheme The URI scheme. 194 * @return The Builder. 195 * @hide 196 */ 197 public Builder addSupportedUriScheme(String uriScheme) { 198 if (!TextUtils.isEmpty(uriScheme) && !mSupportedUriSchemes.contains(uriScheme)) { 199 this.mSupportedUriSchemes.add(uriScheme); 200 } 201 return this; 202 } 203 204 /** 205 * Specifies the URI schemes supported by the {@link PhoneAccount}. 206 * 207 * @param uriSchemes The URI schemes. 208 * @return The Builder. 209 */ 210 public Builder setSupportedUriSchemes(List<String> uriSchemes) { 211 mSupportedUriSchemes.clear(); 212 213 if (uriSchemes != null && !uriSchemes.isEmpty()) { 214 for (String uriScheme : uriSchemes) { 215 addSupportedUriScheme(uriScheme); 216 } 217 } 218 return this; 219 } 220 221 /** 222 * Creates an instance of a {@link PhoneAccount} based on the current builder settings. 223 * 224 * @return The {@link PhoneAccount}. 225 */ 226 public PhoneAccount build() { 227 // If no supported URI schemes were defined, assume "tel" is supported. 228 if (mSupportedUriSchemes.isEmpty()) { 229 addSupportedUriScheme(SCHEME_TEL); 230 } 231 232 return new PhoneAccount( 233 mAccountHandle, 234 mAddress, 235 mSubscriptionAddress, 236 mCapabilities, 237 mIconResId, 238 mColor, 239 mLabel, 240 mShortDescription, 241 mSupportedUriSchemes); 242 } 243 } 244 245 private PhoneAccount( 246 PhoneAccountHandle account, 247 Uri address, 248 Uri subscriptionAddress, 249 int capabilities, 250 int iconResId, 251 int color, 252 CharSequence label, 253 CharSequence shortDescription, 254 List<String> supportedUriSchemes) { 255 mAccountHandle = account; 256 mAddress = address; 257 mSubscriptionAddress = subscriptionAddress; 258 mCapabilities = capabilities; 259 mIconResId = iconResId; 260 mColor = color; 261 mLabel = label; 262 mShortDescription = shortDescription; 263 mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes); 264 } 265 266 public static Builder builder( 267 PhoneAccountHandle accountHandle, 268 CharSequence label) { 269 return new Builder(accountHandle, label); 270 } 271 272 /** 273 * Returns a builder initialized with the current {@link PhoneAccount} instance. 274 * 275 * @return The builder. 276 * @hide 277 */ 278 public Builder toBuilder() { return new Builder(this); } 279 280 /** 281 * The unique identifier of this {@code PhoneAccount}. 282 * 283 * @return A {@code PhoneAccountHandle}. 284 */ 285 public PhoneAccountHandle getAccountHandle() { 286 return mAccountHandle; 287 } 288 289 /** 290 * The address (e.g., a phone number) associated with this {@code PhoneAccount}. This 291 * represents the destination from which outgoing calls using this {@code PhoneAccount} 292 * will appear to come, if applicable, and the destination to which incoming calls using this 293 * {@code PhoneAccount} may be addressed. 294 * 295 * @return A address expressed as a {@code Uri}, for example, a phone number. 296 */ 297 public Uri getAddress() { 298 return mAddress; 299 } 300 301 /** 302 * The raw callback number used for this {@code PhoneAccount}, as distinct from 303 * {@link #getAddress()}. For the majority of {@code PhoneAccount}s this should be registered 304 * as {@code null}. It is used by the system for SIM-based {@code PhoneAccount} registration 305 * 306 * @return The subscription number, suitable for display to the user. 307 */ 308 public Uri getSubscriptionAddress() { 309 return mSubscriptionAddress; 310 } 311 312 /** 313 * The capabilities of this {@code PhoneAccount}. 314 * 315 * @return A bit field of flags describing this {@code PhoneAccount}'s capabilities. 316 */ 317 public int getCapabilities() { 318 return mCapabilities; 319 } 320 321 /** 322 * Determines if this {@code PhoneAccount} has a capabilities specified by the passed in 323 * bit mask. 324 * 325 * @param capability The capabilities to check. 326 * @return {@code True} if the phone account has the capability. 327 */ 328 public boolean hasCapabilities(int capability) { 329 return (mCapabilities & capability) == capability; 330 } 331 332 /** 333 * A short label describing a {@code PhoneAccount}. 334 * 335 * @return A label for this {@code PhoneAccount}. 336 */ 337 public CharSequence getLabel() { 338 return mLabel; 339 } 340 341 /** 342 * A short paragraph describing this {@code PhoneAccount}. 343 * 344 * @return A description for this {@code PhoneAccount}. 345 */ 346 public CharSequence getShortDescription() { 347 return mShortDescription; 348 } 349 350 /** 351 * The URI schemes supported by this {@code PhoneAccount}. 352 * 353 * @return The URI schemes. 354 */ 355 public List<String> getSupportedUriSchemes() { 356 return mSupportedUriSchemes; 357 } 358 359 /** 360 * Determines if the {@link PhoneAccount} supports calls to/from addresses with a specified URI 361 * scheme. 362 * 363 * @param uriScheme The URI scheme to check. 364 * @return {@code True} if the {@code PhoneAccount} supports calls to/from addresses with the 365 * specified URI scheme. 366 */ 367 public boolean supportsUriScheme(String uriScheme) { 368 if (mSupportedUriSchemes == null || uriScheme == null) { 369 return false; 370 } 371 372 for (String scheme : mSupportedUriSchemes) { 373 if (scheme != null && scheme.equals(uriScheme)) { 374 return true; 375 } 376 } 377 return false; 378 } 379 380 /** 381 * The icon resource ID for the icon of this {@code PhoneAccount}. 382 * 383 * @return A resource ID. 384 */ 385 public int getIconResId() { 386 return mIconResId; 387 } 388 389 /** 390 * A highlight color to use in displaying information about this {@code PhoneAccount}. 391 * 392 * @return A hexadecimal color value. 393 */ 394 public int getColor() { 395 return mColor; 396 } 397 398 /** 399 * An icon to represent this {@code PhoneAccount} in a user interface. 400 * 401 * @return An icon for this {@code PhoneAccount}. 402 */ 403 public Drawable getIcon(Context context) { 404 return getIcon(context, mIconResId); 405 } 406 407 private Drawable getIcon(Context context, int resId) { 408 Context packageContext; 409 try { 410 packageContext = context.createPackageContext( 411 mAccountHandle.getComponentName().getPackageName(), 0); 412 } catch (PackageManager.NameNotFoundException e) { 413 Log.w(this, "Cannot find package %s", mAccountHandle.getComponentName().getPackageName()); 414 return null; 415 } 416 try { 417 return packageContext.getDrawable(resId); 418 } catch (NotFoundException|MissingResourceException e) { 419 Log.e(this, e, "Cannot find icon %d in package %s", 420 resId, mAccountHandle.getComponentName().getPackageName()); 421 return null; 422 } 423 } 424 425 // 426 // Parcelable implementation 427 // 428 429 @Override 430 public int describeContents() { 431 return 0; 432 } 433 434 @Override 435 public void writeToParcel(Parcel out, int flags) { 436 out.writeParcelable(mAccountHandle, 0); 437 out.writeParcelable(mAddress, 0); 438 out.writeParcelable(mSubscriptionAddress, 0); 439 out.writeInt(mCapabilities); 440 out.writeInt(mIconResId); 441 out.writeInt(mColor); 442 out.writeCharSequence(mLabel); 443 out.writeCharSequence(mShortDescription); 444 out.writeList(mSupportedUriSchemes); 445 } 446 447 public static final Creator<PhoneAccount> CREATOR 448 = new Creator<PhoneAccount>() { 449 @Override 450 public PhoneAccount createFromParcel(Parcel in) { 451 return new PhoneAccount(in); 452 } 453 454 @Override 455 public PhoneAccount[] newArray(int size) { 456 return new PhoneAccount[size]; 457 } 458 }; 459 460 private PhoneAccount(Parcel in) { 461 ClassLoader classLoader = PhoneAccount.class.getClassLoader(); 462 463 mAccountHandle = in.readParcelable(getClass().getClassLoader()); 464 mAddress = in.readParcelable(getClass().getClassLoader()); 465 mSubscriptionAddress = in.readParcelable(getClass().getClassLoader()); 466 mCapabilities = in.readInt(); 467 mIconResId = in.readInt(); 468 mColor = in.readInt(); 469 mLabel = in.readCharSequence(); 470 mShortDescription = in.readCharSequence(); 471 472 List<String> supportedUriSchemes = new ArrayList<>(); 473 in.readList(supportedUriSchemes, classLoader); 474 mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes); 475 } 476} 477