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