PhoneAccount.java revision 82816c11bd89bce8af86392ca0d861517ec6bb50
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 private final PhoneAccountHandle mAccountHandle; 112 private final Uri mAddress; 113 private final Uri mSubscriptionAddress; 114 private final int mCapabilities; 115 private final int mIconResId; 116 private final int mColor; 117 private final CharSequence mLabel; 118 private final CharSequence mShortDescription; 119 private final List<String> mSupportedUriSchemes; 120 121 public static class Builder { 122 private PhoneAccountHandle mAccountHandle; 123 private Uri mAddress; 124 private Uri mSubscriptionAddress; 125 private int mCapabilities; 126 private int mIconResId; 127 private int mColor; 128 private CharSequence mLabel; 129 private CharSequence mShortDescription; 130 private List<String> mSupportedUriSchemes = new ArrayList<String>(); 131 132 public Builder(PhoneAccountHandle accountHandle, CharSequence label) { 133 this.mAccountHandle = accountHandle; 134 this.mLabel = label; 135 } 136 137 /** 138 * Creates an instance of the {@link PhoneAccount.Builder} from an existing 139 * {@link PhoneAccount}. 140 * 141 * @param phoneAccount The {@link PhoneAccount} used to initialize the builder. 142 */ 143 public Builder(PhoneAccount phoneAccount) { 144 mAccountHandle = phoneAccount.getAccountHandle(); 145 mAddress = phoneAccount.getAddress(); 146 mSubscriptionAddress = phoneAccount.getSubscriptionAddress(); 147 mCapabilities = phoneAccount.getCapabilities(); 148 mIconResId = phoneAccount.getIconResId(); 149 mColor = phoneAccount.getColor(); 150 mLabel = phoneAccount.getLabel(); 151 mShortDescription = phoneAccount.getShortDescription(); 152 mSupportedUriSchemes.addAll(phoneAccount.getSupportedUriSchemes()); 153 } 154 155 public Builder setAddress(Uri value) { 156 this.mAddress = value; 157 return this; 158 } 159 160 public Builder setSubscriptionAddress(Uri value) { 161 this.mSubscriptionAddress = value; 162 return this; 163 } 164 165 public Builder setCapabilities(int value) { 166 this.mCapabilities = value; 167 return this; 168 } 169 170 public Builder setIconResId(int value) { 171 this.mIconResId = value; 172 return this; 173 } 174 175 public Builder setColor(int value) { 176 this.mColor = value; 177 return this; 178 } 179 180 public Builder setShortDescription(CharSequence value) { 181 this.mShortDescription = value; 182 return this; 183 } 184 185 /** 186 * Specifies an additional URI scheme supported by the {@link PhoneAccount}. 187 * 188 * @param uriScheme The URI scheme. 189 * @return The Builder. 190 * @hide 191 */ 192 public Builder addSupportedUriScheme(String uriScheme) { 193 if (!TextUtils.isEmpty(uriScheme) && !mSupportedUriSchemes.contains(uriScheme)) { 194 this.mSupportedUriSchemes.add(uriScheme); 195 } 196 return this; 197 } 198 199 /** 200 * Specifies the URI schemes supported by the {@link PhoneAccount}. 201 * 202 * @param uriSchemes The URI schemes. 203 * @return The Builder. 204 */ 205 public Builder setSupportedUriSchemes(List<String> uriSchemes) { 206 mSupportedUriSchemes.clear(); 207 208 if (uriSchemes != null && !uriSchemes.isEmpty()) { 209 for (String uriScheme : uriSchemes) { 210 addSupportedUriScheme(uriScheme); 211 } 212 } 213 return this; 214 } 215 216 /** 217 * Creates an instance of a {@link PhoneAccount} based on the current builder settings. 218 * 219 * @return The {@link PhoneAccount}. 220 */ 221 public PhoneAccount build() { 222 // If no supported URI schemes were defined, assume "tel" is supported. 223 if (mSupportedUriSchemes.isEmpty()) { 224 addSupportedUriScheme(SCHEME_TEL); 225 } 226 227 return new PhoneAccount( 228 mAccountHandle, 229 mAddress, 230 mSubscriptionAddress, 231 mCapabilities, 232 mIconResId, 233 mColor, 234 mLabel, 235 mShortDescription, 236 mSupportedUriSchemes); 237 } 238 } 239 240 private PhoneAccount( 241 PhoneAccountHandle account, 242 Uri address, 243 Uri subscriptionAddress, 244 int capabilities, 245 int iconResId, 246 int color, 247 CharSequence label, 248 CharSequence shortDescription, 249 List<String> supportedUriSchemes) { 250 mAccountHandle = account; 251 mAddress = address; 252 mSubscriptionAddress = subscriptionAddress; 253 mCapabilities = capabilities; 254 mIconResId = iconResId; 255 mColor = color; 256 mLabel = label; 257 mShortDescription = shortDescription; 258 mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes); 259 } 260 261 public static Builder builder( 262 PhoneAccountHandle accountHandle, 263 CharSequence label) { 264 return new Builder(accountHandle, label); 265 } 266 267 /** 268 * Returns a builder initialized with the current {@link PhoneAccount} instance. 269 * 270 * @return The builder. 271 * @hide 272 */ 273 public Builder toBuilder() { return new Builder(this); } 274 275 /** 276 * The unique identifier of this {@code PhoneAccount}. 277 * 278 * @return A {@code PhoneAccountHandle}. 279 */ 280 public PhoneAccountHandle getAccountHandle() { 281 return mAccountHandle; 282 } 283 284 /** 285 * The address (e.g., a phone number) associated with this {@code PhoneAccount}. This 286 * represents the destination from which outgoing calls using this {@code PhoneAccount} 287 * will appear to come, if applicable, and the destination to which incoming calls using this 288 * {@code PhoneAccount} may be addressed. 289 * 290 * @return A address expressed as a {@code Uri}, for example, a phone number. 291 */ 292 public Uri getAddress() { 293 return mAddress; 294 } 295 296 /** 297 * The raw callback number used for this {@code PhoneAccount}, as distinct from 298 * {@link #getAddress()}. For the majority of {@code PhoneAccount}s this should be registered 299 * as {@code null}. It is used by the system for SIM-based {@code PhoneAccount} registration 300 * 301 * @return The subscription number, suitable for display to the user. 302 */ 303 public Uri getSubscriptionAddress() { 304 return mSubscriptionAddress; 305 } 306 307 /** 308 * The capabilities of this {@code PhoneAccount}. 309 * 310 * @return A bit field of flags describing this {@code PhoneAccount}'s capabilities. 311 */ 312 public int getCapabilities() { 313 return mCapabilities; 314 } 315 316 /** 317 * Determines if this {@code PhoneAccount} has a capabilities specified by the passed in 318 * bit mask. 319 * 320 * @param capability The capabilities to check. 321 * @return {@code True} if the phone account has the capability. 322 */ 323 public boolean hasCapabilities(int capability) { 324 return (mCapabilities & capability) == capability; 325 } 326 327 /** 328 * A short label describing a {@code PhoneAccount}. 329 * 330 * @return A label for this {@code PhoneAccount}. 331 */ 332 public CharSequence getLabel() { 333 return mLabel; 334 } 335 336 /** 337 * A short paragraph describing this {@code PhoneAccount}. 338 * 339 * @return A description for this {@code PhoneAccount}. 340 */ 341 public CharSequence getShortDescription() { 342 return mShortDescription; 343 } 344 345 /** 346 * The URI schemes supported by this {@code PhoneAccount}. 347 * 348 * @return The URI schemes. 349 */ 350 public List<String> getSupportedUriSchemes() { 351 return mSupportedUriSchemes; 352 } 353 354 /** 355 * Determines if the {@link PhoneAccount} supports calls to/from addresses with a specified URI 356 * scheme. 357 * 358 * @param uriScheme The URI scheme to check. 359 * @return {@code True} if the {@code PhoneAccount} supports calls to/from addresses with the 360 * specified URI scheme. 361 */ 362 public boolean supportsUriScheme(String uriScheme) { 363 if (mSupportedUriSchemes == null || uriScheme == null) { 364 return false; 365 } 366 367 for (String scheme : mSupportedUriSchemes) { 368 if (scheme != null && scheme.equals(uriScheme)) { 369 return true; 370 } 371 } 372 return false; 373 } 374 375 /** 376 * The icon resource ID for the icon of this {@code PhoneAccount}. 377 * 378 * @return A resource ID. 379 */ 380 public int getIconResId() { 381 return mIconResId; 382 } 383 384 /** 385 * A highlight color to use in displaying information about this {@code PhoneAccount}. 386 * 387 * @return A hexadecimal color value. 388 */ 389 public int getColor() { 390 return mColor; 391 } 392 393 /** 394 * An icon to represent this {@code PhoneAccount} in a user interface. 395 * 396 * @return An icon for this {@code PhoneAccount}. 397 */ 398 public Drawable getIcon(Context context) { 399 return getIcon(context, mIconResId); 400 } 401 402 private Drawable getIcon(Context context, int resId) { 403 Context packageContext; 404 try { 405 packageContext = context.createPackageContext( 406 mAccountHandle.getComponentName().getPackageName(), 0); 407 } catch (PackageManager.NameNotFoundException e) { 408 Log.w(this, "Cannot find package %s", mAccountHandle.getComponentName().getPackageName()); 409 return null; 410 } 411 try { 412 return packageContext.getDrawable(resId); 413 } catch (NotFoundException|MissingResourceException e) { 414 Log.e(this, e, "Cannot find icon %d in package %s", 415 resId, mAccountHandle.getComponentName().getPackageName()); 416 return null; 417 } 418 } 419 420 // 421 // Parcelable implementation 422 // 423 424 @Override 425 public int describeContents() { 426 return 0; 427 } 428 429 @Override 430 public void writeToParcel(Parcel out, int flags) { 431 out.writeParcelable(mAccountHandle, 0); 432 out.writeParcelable(mAddress, 0); 433 out.writeParcelable(mSubscriptionAddress, 0); 434 out.writeInt(mCapabilities); 435 out.writeInt(mIconResId); 436 out.writeInt(mColor); 437 out.writeCharSequence(mLabel); 438 out.writeCharSequence(mShortDescription); 439 out.writeList(mSupportedUriSchemes); 440 } 441 442 public static final Creator<PhoneAccount> CREATOR 443 = new Creator<PhoneAccount>() { 444 @Override 445 public PhoneAccount createFromParcel(Parcel in) { 446 return new PhoneAccount(in); 447 } 448 449 @Override 450 public PhoneAccount[] newArray(int size) { 451 return new PhoneAccount[size]; 452 } 453 }; 454 455 private PhoneAccount(Parcel in) { 456 ClassLoader classLoader = PhoneAccount.class.getClassLoader(); 457 458 mAccountHandle = in.readParcelable(getClass().getClassLoader()); 459 mAddress = in.readParcelable(getClass().getClassLoader()); 460 mSubscriptionAddress = in.readParcelable(getClass().getClassLoader()); 461 mCapabilities = in.readInt(); 462 mIconResId = in.readInt(); 463 mColor = in.readInt(); 464 mLabel = in.readCharSequence(); 465 mShortDescription = in.readCharSequence(); 466 467 List<String> supportedUriSchemes = new ArrayList<>(); 468 in.readList(supportedUriSchemes, classLoader); 469 mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes); 470 } 471} 472