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 static android.Manifest.permission.MODIFY_PHONE_STATE; 20 21 import android.annotation.FlaggedApi; 22 import android.annotation.NonNull; 23 import android.annotation.RequiresPermission; 24 import android.annotation.SystemApi; 25 import android.content.Intent; 26 import android.graphics.drawable.Icon; 27 import android.net.Uri; 28 import android.os.Bundle; 29 import android.os.Parcel; 30 import android.os.Parcelable; 31 import android.telephony.CarrierConfigManager; 32 import android.telephony.TelephonyManager; 33 import android.text.TextUtils; 34 import android.util.ArraySet; 35 36 import com.android.internal.telephony.flags.Flags; 37 38 import java.util.ArrayList; 39 import java.util.Collections; 40 import java.util.List; 41 import java.util.Objects; 42 import java.util.Set; 43 44 /** 45 * Represents a distinct method to place or receive a phone call. Apps which can place calls and 46 * want those calls to be integrated into the dialer and in-call UI should build an instance of 47 * this class and register it with the system using {@link TelecomManager}. 48 * <p> 49 * {@link TelecomManager} uses registered {@link PhoneAccount}s to present the user with 50 * alternative options when placing a phone call. When building a {@link PhoneAccount}, the app 51 * should supply a valid {@link PhoneAccountHandle} that references the connection service 52 * implementation Telecom will use to interact with the app. 53 */ 54 public final class PhoneAccount implements Parcelable { 55 56 /** 57 * Integer extra which determines the order in which {@link PhoneAccount}s are sorted 58 * 59 * This is an extras key set via {@link Builder#setExtras} which determines the order in which 60 * {@link PhoneAccount}s from the same {@link ConnectionService} are sorted. The accounts 61 * are sorted in ascending order by this key, and this ordering is used to 62 * determine priority when a call can be placed via multiple accounts. 63 * 64 * When multiple {@link PhoneAccount}s are supplied with the same sort order key, no ordering is 65 * guaranteed between those {@link PhoneAccount}s. Additionally, no ordering is guaranteed 66 * between {@link PhoneAccount}s that do not supply this extra, and all such accounts 67 * will be sorted after the accounts that do supply this extra. 68 * 69 * An example of a sort order key is slot index (see {@link TelephonyManager#getSlotIndex()}), 70 * which is the one used by the cell Telephony stack. 71 * @hide 72 */ 73 @SystemApi 74 public static final String EXTRA_SORT_ORDER = 75 "android.telecom.extra.SORT_ORDER"; 76 77 /** 78 * {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which determines the 79 * maximum permitted length of a call subject specified via the 80 * {@link TelecomManager#EXTRA_CALL_SUBJECT} extra on an 81 * {@link android.content.Intent#ACTION_CALL} intent. Ultimately a {@link ConnectionService} is 82 * responsible for enforcing the maximum call subject length when sending the message, however 83 * this extra is provided so that the user interface can proactively limit the length of the 84 * call subject as the user types it. 85 */ 86 public static final String EXTRA_CALL_SUBJECT_MAX_LENGTH = 87 "android.telecom.extra.CALL_SUBJECT_MAX_LENGTH"; 88 89 /** 90 * {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which determines the 91 * character encoding to be used when determining the length of messages. 92 * The user interface can use this when determining the number of characters the user may type 93 * in a call subject. If empty-string, the call subject message size limit will be enforced on 94 * a 1:1 basis. That is, each character will count towards the messages size limit as a single 95 * character. If a character encoding is specified, the message size limit will be based on the 96 * number of bytes in the message per the specified encoding. See 97 * {@link #EXTRA_CALL_SUBJECT_MAX_LENGTH} for more information on the call subject maximum 98 * length. 99 */ 100 public static final String EXTRA_CALL_SUBJECT_CHARACTER_ENCODING = 101 "android.telecom.extra.CALL_SUBJECT_CHARACTER_ENCODING"; 102 103 /** 104 * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which 105 * indicates that all calls from this {@link PhoneAccount} should be treated as VoIP calls 106 * rather than cellular calls by the Telecom audio handling logic. 107 */ 108 public static final String EXTRA_ALWAYS_USE_VOIP_AUDIO_MODE = 109 "android.telecom.extra.ALWAYS_USE_VOIP_AUDIO_MODE"; 110 111 /** 112 * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which 113 * indicates whether this {@link PhoneAccount} is capable of supporting a request to handover a 114 * connection (see {@code android.telecom.Call#handoverTo()}) to this {@link PhoneAccount} from 115 * a {@link PhoneAccount} specifying {@link #EXTRA_SUPPORTS_HANDOVER_FROM}. 116 * <p> 117 * A handover request is initiated by the user from the default dialer app to indicate a desire 118 * to handover a call from one {@link PhoneAccount}/{@link ConnectionService} to another. 119 */ 120 public static final String EXTRA_SUPPORTS_HANDOVER_TO = 121 "android.telecom.extra.SUPPORTS_HANDOVER_TO"; 122 123 /** 124 * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which 125 * indicates whether this {@link PhoneAccount} supports using a fallback if video calling is 126 * not available. This extra is for device level support, {@link 127 * android.telephony.CarrierConfigManager#KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL} should also 128 * be checked to ensure it is not disabled by individual carrier. 129 * 130 * @hide 131 */ 132 public static final String EXTRA_SUPPORTS_VIDEO_CALLING_FALLBACK = 133 "android.telecom.extra.SUPPORTS_VIDEO_CALLING_FALLBACK"; 134 135 /** 136 * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which 137 * indicates whether this {@link PhoneAccount} is capable of supporting a request to handover a 138 * connection from this {@link PhoneAccount} to another {@link PhoneAccount}. 139 * (see {@code android.telecom.Call#handoverTo()}) which specifies 140 * {@link #EXTRA_SUPPORTS_HANDOVER_TO}. 141 * <p> 142 * A handover request is initiated by the user from the default dialer app to indicate a desire 143 * to handover a call from one {@link PhoneAccount}/{@link ConnectionService} to another. 144 */ 145 public static final String EXTRA_SUPPORTS_HANDOVER_FROM = 146 "android.telecom.extra.SUPPORTS_HANDOVER_FROM"; 147 148 149 /** 150 * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which 151 * indicates whether a Self-Managed {@link PhoneAccount} should log its calls to the call log. 152 * Self-Managed {@link PhoneAccount}s are responsible for their own notifications, so the system 153 * will not create a notification when a missed call is logged. 154 * <p> 155 * By default, Self-Managed {@link PhoneAccount}s do not log their calls to the call log. 156 * Setting this extra to {@code true} provides a means for them to log their calls. 157 * <p> 158 * Note: Only calls where the {@link Call.Details#getHandle()} {@link Uri#getScheme()} is 159 * {@link #SCHEME_SIP} or {@link #SCHEME_TEL} will be logged at the current time. 160 */ 161 public static final String EXTRA_LOG_SELF_MANAGED_CALLS = 162 "android.telecom.extra.LOG_SELF_MANAGED_CALLS"; 163 164 /** 165 * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which 166 * indicates whether calls for a {@link PhoneAccount} should generate a "call recording tone" 167 * when the user is recording audio on the device. 168 * <p> 169 * The call recording tone is played over the telephony audio stream so that the remote party 170 * has an audible indication that it is possible their call is being recorded using a call 171 * recording app on the device. 172 * <p> 173 * This extra only has an effect for calls placed via Telephony (e.g. 174 * {@link #CAPABILITY_SIM_SUBSCRIPTION}). 175 * <p> 176 * The call recording tone is a 1400 hz tone which repeats every 15 seconds while recording is 177 * in progress. 178 * 179 * @deprecated this API was only intended to prevent call recording via the microphone by an app 180 * while in a phone call. Audio policies no longer make this possible. Further, this API was 181 * never actually used. Call recording solutions integrated in an OEM dialer app must use 182 * appropriate recording signals to inform the caller/callee of the recording. 183 * @hide 184 */ 185 @FlaggedApi(com.android.server.telecom.flags.Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) 186 @Deprecated 187 @SystemApi 188 public static final String EXTRA_PLAY_CALL_RECORDING_TONE = 189 "android.telecom.extra.PLAY_CALL_RECORDING_TONE"; 190 191 /** 192 * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()} which 193 * indicates whether calls for a {@link PhoneAccount} should skip call filtering. 194 * <p> 195 * If not specified, this will default to false; all calls will undergo call filtering unless 196 * specifically exempted (e.g. {@link Connection#PROPERTY_EMERGENCY_CALLBACK_MODE}.) However, 197 * this may be used to skip call filtering when it has already been performed on another device. 198 * @hide 199 */ 200 @SystemApi 201 @FlaggedApi(com.android.server.telecom.flags.Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) 202 public static final String EXTRA_SKIP_CALL_FILTERING = 203 "android.telecom.extra.SKIP_CALL_FILTERING"; 204 205 /** 206 * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which 207 * indicates whether a Self-managed {@link PhoneAccount} want to expose its calls to all 208 * {@link InCallService} which declares the metadata 209 * {@link TelecomManager#METADATA_INCLUDE_SELF_MANAGED_CALLS}. 210 */ 211 public static final String EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE = 212 "android.telecom.extra.ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE"; 213 214 /** 215 * Flag indicating that this {@code PhoneAccount} can act as a connection manager for 216 * other connections. The {@link ConnectionService} associated with this {@code PhoneAccount} 217 * will be allowed to manage phone calls including using its own proprietary phone-call 218 * implementation (like VoIP calling) to make calls instead of the telephony stack. 219 * <p> 220 * When a user opts to place a call using the SIM-based telephony stack, the 221 * {@link ConnectionService} associated with this {@code PhoneAccount} will be attempted first 222 * if the user has explicitly selected it to be used as the default connection manager. 223 * <p> 224 * See {@link #getCapabilities} 225 */ 226 public static final int CAPABILITY_CONNECTION_MANAGER = 0x1; 227 228 /** 229 * Flag indicating that this {@code PhoneAccount} can make phone calls in place of 230 * traditional SIM-based telephony calls. This account will be treated as a distinct method 231 * for placing calls alongside the traditional SIM-based telephony stack. This flag is 232 * distinct from {@link #CAPABILITY_CONNECTION_MANAGER} in that it is not allowed to manage 233 * or place calls from the built-in telephony stack. 234 * <p> 235 * See {@link #getCapabilities} 236 * <p> 237 */ 238 public static final int CAPABILITY_CALL_PROVIDER = 0x2; 239 240 /** 241 * Flag indicating that this {@code PhoneAccount} represents a built-in PSTN SIM 242 * subscription. 243 * <p> 244 * Only the Android framework can register a {@code PhoneAccount} having this capability. 245 * <p> 246 * See {@link #getCapabilities} 247 */ 248 public static final int CAPABILITY_SIM_SUBSCRIPTION = 0x4; 249 250 /** 251 * Flag indicating that this {@code PhoneAccount} is currently able to place video calls. 252 * <p> 253 * See also {@link #CAPABILITY_SUPPORTS_VIDEO_CALLING} which indicates whether the 254 * {@code PhoneAccount} supports placing video calls. 255 * <p> 256 * See {@link #getCapabilities} 257 */ 258 public static final int CAPABILITY_VIDEO_CALLING = 0x8; 259 260 /** 261 * Flag indicating that this {@code PhoneAccount} is capable of placing emergency calls. 262 * By default all PSTN {@code PhoneAccount}s are capable of placing emergency calls. 263 * <p> 264 * See {@link #getCapabilities} 265 */ 266 public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 0x10; 267 268 /** 269 * Flag indicating that this {@code PhoneAccount} is capable of being used by all users. This 270 * should only be used by system apps (and will be ignored for all other apps trying to use it). 271 * <p> 272 * See {@link #getCapabilities} 273 * @hide 274 */ 275 @SystemApi 276 public static final int CAPABILITY_MULTI_USER = 0x20; 277 278 /** 279 * Flag indicating that this {@code PhoneAccount} supports a subject for Calls. This means a 280 * caller is able to specify a short subject line for an outgoing call. A capable receiving 281 * device displays the call subject on the incoming call screen. 282 * <p> 283 * See {@link #getCapabilities} 284 */ 285 public static final int CAPABILITY_CALL_SUBJECT = 0x40; 286 287 /** 288 * Flag indicating that this {@code PhoneAccount} should only be used for emergency calls. 289 * <p> 290 * See {@link #getCapabilities} 291 * @hide 292 */ 293 @SystemApi 294 public static final int CAPABILITY_EMERGENCY_CALLS_ONLY = 0x80; 295 296 /** 297 * Flag indicating that for this {@code PhoneAccount}, the ability to make a video call to a 298 * number relies on presence. Should only be set if the {@code PhoneAccount} also has 299 * {@link #CAPABILITY_VIDEO_CALLING}. 300 * <p> 301 * Note: As of Android 12, using the 302 * {@link android.provider.ContactsContract.Data#CARRIER_PRESENCE_VT_CAPABLE} bit on the 303 * {@link android.provider.ContactsContract.Data#CARRIER_PRESENCE} column to indicate whether 304 * a contact's phone number supports video calling has been deprecated and should only be used 305 * on devices where {@link CarrierConfigManager#KEY_USE_RCS_PRESENCE_BOOL} is set. On newer 306 * devices, applications must use {@link android.telephony.ims.RcsUceAdapter} instead to 307 * determine whether or not a contact's phone number supports carrier video calling. 308 * <p> 309 * See {@link #getCapabilities} 310 */ 311 public static final int CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE = 0x100; 312 313 /** 314 * Flag indicating that for this {@link PhoneAccount}, emergency video calling is allowed. 315 * <p> 316 * When set, Telecom will allow emergency video calls to be placed. When not set, Telecom will 317 * convert all outgoing video calls to emergency numbers to audio-only. 318 * @hide 319 */ 320 @SystemApi 321 public static final int CAPABILITY_EMERGENCY_VIDEO_CALLING = 0x200; 322 323 /** 324 * Flag indicating that this {@link PhoneAccount} supports video calling. 325 * This is not an indication that the {@link PhoneAccount} is currently able to make a video 326 * call, but rather that it has the ability to make video calls (but not necessarily at this 327 * time). 328 * <p> 329 * Whether a {@link PhoneAccount} can make a video call is ultimately controlled by 330 * {@link #CAPABILITY_VIDEO_CALLING}, which indicates whether the {@link PhoneAccount} is 331 * currently capable of making a video call. Consider a case where, for example, a 332 * {@link PhoneAccount} supports making video calls (e.g. 333 * {@link #CAPABILITY_SUPPORTS_VIDEO_CALLING}), but a current lack of network connectivity 334 * prevents video calls from being made (e.g. {@link #CAPABILITY_VIDEO_CALLING}). 335 * <p> 336 * See {@link #getCapabilities} 337 */ 338 public static final int CAPABILITY_SUPPORTS_VIDEO_CALLING = 0x400; 339 340 /** 341 * Flag indicating that this {@link PhoneAccount} is responsible for managing its own 342 * {@link Connection}s. This type of {@link PhoneAccount} is ideal for use with standalone 343 * calling apps which do not wish to use the default phone app for {@link Connection} UX, 344 * but which want to leverage the call and audio routing capabilities of the Telecom framework. 345 * <p> 346 * When set, {@link Connection}s created by the self-managed {@link ConnectionService} will not 347 * be surfaced to implementations of the {@link InCallService} API. Thus it is the 348 * responsibility of a self-managed {@link ConnectionService} to provide a user interface for 349 * its {@link Connection}s. 350 * <p> 351 * Self-managed {@link Connection}s will, however, be displayed on connected Bluetooth devices. 352 */ 353 public static final int CAPABILITY_SELF_MANAGED = 0x800; 354 355 /** 356 * Flag indicating that this {@link PhoneAccount} is capable of making a call with an 357 * RTT (Real-time text) session. 358 * When set, Telecom will attempt to open an RTT session on outgoing calls that specify 359 * that they should be placed with an RTT session , and the in-call app will be displayed 360 * with text entry fields for RTT. Likewise, the in-call app can request that an RTT 361 * session be opened during a call if this bit is set. 362 */ 363 public static final int CAPABILITY_RTT = 0x1000; 364 365 /** 366 * Flag indicating that this {@link PhoneAccount} is the preferred SIM subscription for 367 * emergency calls. A {@link PhoneAccount} that sets this capability must also 368 * set the {@link #CAPABILITY_SIM_SUBSCRIPTION} and {@link #CAPABILITY_PLACE_EMERGENCY_CALLS} 369 * capabilities. There must only be one emergency preferred {@link PhoneAccount} on the device. 370 * <p> 371 * When set, Telecom will prefer this {@link PhoneAccount} over others for emergency calling, 372 * even if the emergency call was placed with a specific {@link PhoneAccount} set using the 373 * extra{@link TelecomManager#EXTRA_PHONE_ACCOUNT_HANDLE} in 374 * {@link Intent#ACTION_CALL_EMERGENCY} or {@link TelecomManager#placeCall(Uri, Bundle)}. 375 * 376 * @hide 377 */ 378 @SystemApi 379 public static final int CAPABILITY_EMERGENCY_PREFERRED = 0x2000; 380 381 /** 382 * An adhoc conference call is established by providing a list of addresses to 383 * {@code TelecomManager#startConference(List<Uri>, int videoState)} where the 384 * {@link ConnectionService} is responsible for connecting all indicated participants 385 * to a conference simultaneously. 386 * This is in contrast to conferences formed by merging calls together (e.g. using 387 * {@link android.telecom.Call#mergeConference()}). 388 */ 389 public static final int CAPABILITY_ADHOC_CONFERENCE_CALLING = 0x4000; 390 391 /** 392 * Flag indicating whether this {@link PhoneAccount} is capable of supporting the call composer 393 * functionality for enriched calls. 394 */ 395 public static final int CAPABILITY_CALL_COMPOSER = 0x8000; 396 397 /** 398 * Flag indicating that this {@link PhoneAccount} provides SIM-based voice calls, potentially as 399 * an over-the-top solution such as wi-fi calling. 400 * 401 * <p>Similar to {@link #CAPABILITY_SUPPORTS_VIDEO_CALLING}, this capability indicates this 402 * {@link PhoneAccount} has the ability to make voice calls (but not necessarily at this time). 403 * Whether this {@link PhoneAccount} can make a voice call is ultimately controlled by {@link 404 * #CAPABILITY_VOICE_CALLING_AVAILABLE}, which indicates whether this {@link PhoneAccount} is 405 * currently capable of making a voice call. Consider a case where, for example, a {@link 406 * PhoneAccount} supports making voice calls (e.g. {@link 407 * #CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS}), but a current lack of network connectivity 408 * prevents voice calls from being made (e.g. {@link #CAPABILITY_VOICE_CALLING_AVAILABLE}). 409 * 410 * <p>In order to declare this capability, this {@link PhoneAccount} must also declare {@link 411 * #CAPABILITY_SIM_SUBSCRIPTION} or {@link #CAPABILITY_CONNECTION_MANAGER} and satisfy the 412 * associated requirements. 413 * 414 * @see #CAPABILITY_VOICE_CALLING_AVAILABLE 415 * @see #getCapabilities 416 */ 417 public static final int CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS = 0x10000; 418 419 /** 420 * Flag indicating that this {@link PhoneAccount} is <em>currently</em> able to place SIM-based 421 * voice calls, similar to {@link #CAPABILITY_VIDEO_CALLING}. 422 * 423 * <p>See also {@link #CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS}, which indicates whether 424 * the {@code PhoneAccount} supports placing SIM-based voice calls or not. 425 * 426 * <p>In order to declare this capability, this {@link PhoneAccount} must also declare {@link 427 * #CAPABILITY_SIM_SUBSCRIPTION} or {@link #CAPABILITY_CONNECTION_MANAGER} and satisfy the 428 * associated requirements. 429 * 430 * @see #CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS 431 * @see #getCapabilities 432 */ 433 public static final int CAPABILITY_VOICE_CALLING_AVAILABLE = 0x20000; 434 435 436 /** 437 * Flag indicating that this {@link PhoneAccount} supports the use TelecomManager APIs that 438 * utilize {@link android.os.OutcomeReceiver}s or {@link java.util.function.Consumer}s. 439 * Be aware, if this capability is set, {@link #CAPABILITY_SELF_MANAGED} will be amended by 440 * Telecom when this {@link PhoneAccount} is registered via 441 * {@link TelecomManager#registerPhoneAccount(PhoneAccount)}. 442 * 443 * <p> 444 * {@link android.os.OutcomeReceiver}s and {@link java.util.function.Consumer}s represent 445 * transactional operations because the operation can succeed or fail. An app wishing to use 446 * transactional operations should define behavior for a successful and failed TelecomManager 447 * API call. 448 * 449 * @see #CAPABILITY_SELF_MANAGED 450 * @see #getCapabilities 451 */ 452 public static final int CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS = 0x40000; 453 454 /** 455 * Flag indicating that this voip app {@link PhoneAccount} supports the call streaming session 456 * to stream call audio to another remote device via streaming app. 457 * 458 * @see #getCapabilities 459 */ 460 public static final int CAPABILITY_SUPPORTS_CALL_STREAMING = 0x80000; 461 462 /* NEXT CAPABILITY: [0x100000, 0x200000, 0x400000] */ 463 464 /** 465 * URI scheme for telephone number URIs. 466 */ 467 public static final String SCHEME_TEL = "tel"; 468 469 /** 470 * URI scheme for voicemail URIs. 471 */ 472 public static final String SCHEME_VOICEMAIL = "voicemail"; 473 474 /** 475 * URI scheme for SIP URIs. 476 */ 477 public static final String SCHEME_SIP = "sip"; 478 479 /** 480 * Indicating no icon tint is set. 481 * @hide 482 */ 483 public static final int NO_ICON_TINT = 0; 484 485 /** 486 * Indicating no hightlight color is set. 487 */ 488 public static final int NO_HIGHLIGHT_COLOR = 0; 489 490 /** 491 * Indicating no resource ID is set. 492 */ 493 public static final int NO_RESOURCE_ID = -1; 494 495 private final PhoneAccountHandle mAccountHandle; 496 private final Uri mAddress; 497 private final Uri mSubscriptionAddress; 498 private final int mCapabilities; 499 private final int mHighlightColor; 500 private final CharSequence mLabel; 501 private final CharSequence mShortDescription; 502 private final List<String> mSupportedUriSchemes; 503 private final int mSupportedAudioRoutes; 504 private final Icon mIcon; 505 private final Bundle mExtras; 506 private boolean mIsEnabled; 507 private String mGroupId; 508 private final Set<PhoneAccountHandle> mSimultaneousCallingRestriction; 509 510 @Override equals(Object o)511 public boolean equals(Object o) { 512 if (this == o) return true; 513 if (o == null || getClass() != o.getClass()) return false; 514 PhoneAccount that = (PhoneAccount) o; 515 return mCapabilities == that.mCapabilities && 516 mHighlightColor == that.mHighlightColor && 517 mSupportedAudioRoutes == that.mSupportedAudioRoutes && 518 mIsEnabled == that.mIsEnabled && 519 Objects.equals(mAccountHandle, that.mAccountHandle) && 520 Objects.equals(mAddress, that.mAddress) && 521 Objects.equals(mSubscriptionAddress, that.mSubscriptionAddress) && 522 Objects.equals(mLabel, that.mLabel) && 523 Objects.equals(mShortDescription, that.mShortDescription) && 524 Objects.equals(mSupportedUriSchemes, that.mSupportedUriSchemes) && 525 areBundlesEqual(mExtras, that.mExtras) && 526 Objects.equals(mGroupId, that.mGroupId) 527 && Objects.equals(mSimultaneousCallingRestriction, 528 that.mSimultaneousCallingRestriction); 529 } 530 531 @Override hashCode()532 public int hashCode() { 533 return Objects.hash(mAccountHandle, mAddress, mSubscriptionAddress, mCapabilities, 534 mHighlightColor, mLabel, mShortDescription, mSupportedUriSchemes, 535 mSupportedAudioRoutes, 536 mExtras, mIsEnabled, mGroupId, mSimultaneousCallingRestriction); 537 } 538 539 /** 540 * Helper class for creating a {@link PhoneAccount}. 541 */ 542 public static class Builder { 543 544 private PhoneAccountHandle mAccountHandle; 545 private Uri mAddress; 546 private Uri mSubscriptionAddress; 547 private int mCapabilities; 548 private int mSupportedAudioRoutes = CallAudioState.ROUTE_ALL; 549 private int mHighlightColor = NO_HIGHLIGHT_COLOR; 550 private CharSequence mLabel; 551 private CharSequence mShortDescription; 552 private List<String> mSupportedUriSchemes = new ArrayList<String>(); 553 private Icon mIcon; 554 private Bundle mExtras; 555 private boolean mIsEnabled = false; 556 private String mGroupId = ""; 557 private Set<PhoneAccountHandle> mSimultaneousCallingRestriction = null; 558 559 /** 560 * Creates a builder with the specified {@link PhoneAccountHandle} and label. 561 * <p> 562 * Note: each CharSequence or String field is limited to 256 characters. This check is 563 * enforced when registering the PhoneAccount via 564 * {@link TelecomManager#registerPhoneAccount(PhoneAccount)} and will cause an 565 * {@link IllegalArgumentException} to be thrown if the character field limit is over 256. 566 */ Builder(PhoneAccountHandle accountHandle, CharSequence label)567 public Builder(PhoneAccountHandle accountHandle, CharSequence label) { 568 this.mAccountHandle = accountHandle; 569 this.mLabel = label; 570 } 571 572 /** 573 * Creates an instance of the {@link PhoneAccount.Builder} from an existing 574 * {@link PhoneAccount}. 575 * 576 * @param phoneAccount The {@link PhoneAccount} used to initialize the builder. 577 */ Builder(PhoneAccount phoneAccount)578 public Builder(PhoneAccount phoneAccount) { 579 mAccountHandle = phoneAccount.getAccountHandle(); 580 mAddress = phoneAccount.getAddress(); 581 mSubscriptionAddress = phoneAccount.getSubscriptionAddress(); 582 mCapabilities = phoneAccount.getCapabilities(); 583 mHighlightColor = phoneAccount.getHighlightColor(); 584 mLabel = phoneAccount.getLabel(); 585 mShortDescription = phoneAccount.getShortDescription(); 586 mSupportedUriSchemes.addAll(phoneAccount.getSupportedUriSchemes()); 587 mIcon = phoneAccount.getIcon(); 588 mIsEnabled = phoneAccount.isEnabled(); 589 mExtras = phoneAccount.getExtras(); 590 mGroupId = phoneAccount.getGroupId(); 591 mSupportedAudioRoutes = phoneAccount.getSupportedAudioRoutes(); 592 if (phoneAccount.hasSimultaneousCallingRestriction()) { 593 mSimultaneousCallingRestriction = phoneAccount.getSimultaneousCallingRestriction(); 594 } 595 } 596 597 /** 598 * Sets the label. See {@link PhoneAccount#getLabel()}. 599 * <p> 600 * Note: Each CharSequence or String field is limited to 256 characters. This check is 601 * enforced when registering the PhoneAccount via 602 * {@link TelecomManager#registerPhoneAccount(PhoneAccount)} and will cause an 603 * {@link IllegalArgumentException} to be thrown if the character field limit is over 256. 604 * 605 * @param label The label of the phone account. 606 * @return The builder. 607 * @hide 608 */ setLabel(CharSequence label)609 public Builder setLabel(CharSequence label) { 610 this.mLabel = label; 611 return this; 612 } 613 614 /** 615 * Sets the address. See {@link PhoneAccount#getAddress}. 616 * <p> 617 * Note: The entire URI value is limited to 256 characters. This check is 618 * enforced when registering the PhoneAccount via 619 * {@link TelecomManager#registerPhoneAccount(PhoneAccount)} and will cause an 620 * {@link IllegalArgumentException} to be thrown if URI is over 256. 621 * 622 * @param value The address of the phone account. 623 * @return The builder. 624 */ setAddress(Uri value)625 public Builder setAddress(Uri value) { 626 this.mAddress = value; 627 return this; 628 } 629 630 /** 631 * Sets the subscription address. See {@link PhoneAccount#getSubscriptionAddress}. 632 * 633 * @param value The subscription address. 634 * @return The builder. 635 */ setSubscriptionAddress(Uri value)636 public Builder setSubscriptionAddress(Uri value) { 637 this.mSubscriptionAddress = value; 638 return this; 639 } 640 641 /** 642 * Sets the capabilities. See {@link PhoneAccount#getCapabilities}. 643 * 644 * @param value The capabilities to set. 645 * @return The builder. 646 */ setCapabilities(int value)647 public Builder setCapabilities(int value) { 648 this.mCapabilities = value; 649 return this; 650 } 651 652 /** 653 * Sets the icon. See {@link PhoneAccount#getIcon}. 654 * <p> 655 * Note: An {@link IllegalArgumentException} if the Icon cannot be written to memory. 656 * This check is enforced when registering the PhoneAccount via 657 * {@link TelecomManager#registerPhoneAccount(PhoneAccount)} 658 * 659 * @param icon The icon to set. 660 */ setIcon(Icon icon)661 public Builder setIcon(Icon icon) { 662 mIcon = icon; 663 return this; 664 } 665 666 /** 667 * Sets the highlight color. See {@link PhoneAccount#getHighlightColor}. 668 * 669 * @param value The highlight color. 670 * @return The builder. 671 */ setHighlightColor(int value)672 public Builder setHighlightColor(int value) { 673 this.mHighlightColor = value; 674 return this; 675 } 676 677 /** 678 * Sets the short description. See {@link PhoneAccount#getShortDescription}. 679 * <p> 680 * Note: Each CharSequence or String field is limited to 256 characters. This check is 681 * enforced when registering the PhoneAccount via 682 * {@link TelecomManager#registerPhoneAccount(PhoneAccount)} and will cause an 683 * {@link IllegalArgumentException} to be thrown if the character field limit is over 256. 684 * 685 * @param value The short description. 686 * @return The builder. 687 */ setShortDescription(CharSequence value)688 public Builder setShortDescription(CharSequence value) { 689 this.mShortDescription = value; 690 return this; 691 } 692 693 /** 694 * Specifies an additional URI scheme supported by the {@link PhoneAccount}. 695 * 696 * <p> 697 * Each URI scheme is limited to 256 characters. Adding a scheme over 256 characters will 698 * cause an {@link IllegalArgumentException} to be thrown when the account is registered. 699 * 700 * @param uriScheme The URI scheme. 701 * @return The builder. 702 */ addSupportedUriScheme(String uriScheme)703 public Builder addSupportedUriScheme(String uriScheme) { 704 if (!TextUtils.isEmpty(uriScheme) && !mSupportedUriSchemes.contains(uriScheme)) { 705 this.mSupportedUriSchemes.add(uriScheme); 706 } 707 return this; 708 } 709 710 /** 711 * Specifies the URI schemes supported by the {@link PhoneAccount}. 712 * 713 * <p> 714 * A max of 10 URI schemes can be added per account. Additionally, each URI scheme is 715 * limited to 256 characters. Adding more than 10 URI schemes or 256 characters on any 716 * scheme will cause an {@link IllegalArgumentException} to be thrown when the account 717 * is registered. 718 * 719 * @param uriSchemes The URI schemes. 720 * @return The builder. 721 */ setSupportedUriSchemes(List<String> uriSchemes)722 public Builder setSupportedUriSchemes(List<String> uriSchemes) { 723 mSupportedUriSchemes.clear(); 724 725 if (uriSchemes != null && !uriSchemes.isEmpty()) { 726 for (String uriScheme : uriSchemes) { 727 addSupportedUriScheme(uriScheme); 728 } 729 } 730 return this; 731 } 732 733 /** 734 * Specifies the extras associated with the {@link PhoneAccount}. 735 * <p> 736 * {@code PhoneAccount}s only support extra values of type: {@link String}, {@link Integer}, 737 * and {@link Boolean}. Extras which are not of these types are ignored. 738 * <p> 739 * Note: Each Bundle (Key, Value) String field is limited to 256 characters. Additionally, 740 * the bundle is limited to 100 (Key, Value) pairs total. This check is 741 * enforced when registering the PhoneAccount via 742 * {@link TelecomManager#registerPhoneAccount(PhoneAccount)} and will cause an 743 * {@link IllegalArgumentException} to be thrown if the character field limit is over 256 744 * or more than 100 (Key, Value) pairs are in the Bundle. 745 * 746 * @param extras 747 * @return 748 */ setExtras(Bundle extras)749 public Builder setExtras(Bundle extras) { 750 mExtras = extras; 751 return this; 752 } 753 754 /** 755 * Sets the enabled state of the phone account. 756 * 757 * @param isEnabled The enabled state. 758 * @return The builder. 759 * @hide 760 */ setIsEnabled(boolean isEnabled)761 public Builder setIsEnabled(boolean isEnabled) { 762 mIsEnabled = isEnabled; 763 return this; 764 } 765 766 /** 767 * Sets the group Id of the {@link PhoneAccount}. When a new {@link PhoneAccount} is 768 * registered to Telecom, it will replace another {@link PhoneAccount} that is already 769 * registered in Telecom and take on the current user defaults and enabled status. There can 770 * only be one {@link PhoneAccount} with a non-empty group number registered to Telecom at a 771 * time. By default, there is no group Id for a {@link PhoneAccount} (an empty String). Only 772 * grouped {@link PhoneAccount}s with the same {@link ConnectionService} can be replaced. 773 * <p> 774 * Note: This is an API specific to the Telephony stack; the group Id will be ignored for 775 * callers not holding the correct permission. 776 * <p> 777 * Additionally, each CharSequence or String field is limited to 256 characters. 778 * This check is enforced when registering the PhoneAccount via 779 * {@link TelecomManager#registerPhoneAccount(PhoneAccount)} and will cause an 780 * {@link IllegalArgumentException} to be thrown if the character field limit is over 256. 781 * 782 * @param groupId The group Id of the {@link PhoneAccount} that will replace any other 783 * registered {@link PhoneAccount} in Telecom with the same Group Id. 784 * @return The builder 785 * @hide 786 */ 787 @SystemApi 788 @RequiresPermission(MODIFY_PHONE_STATE) setGroupId(@onNull String groupId)789 public @NonNull Builder setGroupId(@NonNull String groupId) { 790 if (groupId != null) { 791 mGroupId = groupId; 792 } else { 793 mGroupId = ""; 794 } 795 return this; 796 } 797 798 /** 799 * Sets the audio routes supported by this {@link PhoneAccount}. 800 * 801 * @param routes bit mask of available routes. 802 * @return The builder. 803 * @hide 804 */ setSupportedAudioRoutes(int routes)805 public Builder setSupportedAudioRoutes(int routes) { 806 mSupportedAudioRoutes = routes; 807 return this; 808 } 809 810 /** 811 * Restricts the ability of this {@link PhoneAccount} to ONLY support simultaneous calling 812 * with the other {@link PhoneAccountHandle}s in this Set. 813 * <p> 814 * If two or more {@link PhoneAccount}s support calling simultaneously, it means that 815 * Telecom allows the user to place additional outgoing calls and receive additional 816 * incoming calls using other {@link PhoneAccount}s while this PhoneAccount also has one or 817 * more active calls. 818 * <p> 819 * If this setter method is never called or cleared using 820 * {@link #clearSimultaneousCallingRestriction()}, there is no restriction and all 821 * {@link PhoneAccount}s registered to Telecom by this package support simultaneous calling. 822 * If this setter is called and set as an empty Set, then this {@link PhoneAccount} does 823 * not support simultaneous calling with any other {@link PhoneAccount}s registered by the 824 * same application. 825 * <p> 826 * Note: Simultaneous calling restrictions can only be placed on {@link PhoneAccount}s that 827 * were registered by the same application. Simultaneous calling across applications is 828 * always possible as long as the {@link Connection} supports hold. If a 829 * {@link PhoneAccountHandle} is included here and the package name doesn't match this 830 * application's package name, {@link TelecomManager#registerPhoneAccount(PhoneAccount)} 831 * will throw a {@link SecurityException}. 832 * 833 * @param handles The other {@link PhoneAccountHandle}s that support calling simultaneously 834 * with this one. Use {@link #clearSimultaneousCallingRestriction()} to remove the 835 * restriction and allow simultaneous calling to be supported across all 836 * {@link PhoneAccount}s registered by this package. 837 * @return The Builder used to set up the new PhoneAccount. 838 */ 839 @FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) setSimultaneousCallingRestriction( @onNull Set<PhoneAccountHandle> handles)840 public @NonNull Builder setSimultaneousCallingRestriction( 841 @NonNull Set<PhoneAccountHandle> handles) { 842 if (handles == null) { 843 throw new IllegalArgumentException("the Set of PhoneAccountHandles must not be " 844 + "null"); 845 } 846 mSimultaneousCallingRestriction = handles; 847 return this; 848 } 849 850 /** 851 * Clears a previously set simultaneous calling restriction set when 852 * {@link PhoneAccount.Builder#Builder(PhoneAccount)} is used to create a new PhoneAccount 853 * from an existing one. 854 * 855 * @return The Builder used to set up the new PhoneAccount. 856 * @see #setSimultaneousCallingRestriction(Set) 857 */ 858 @FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) clearSimultaneousCallingRestriction()859 public @NonNull Builder clearSimultaneousCallingRestriction() { 860 mSimultaneousCallingRestriction = null; 861 return this; 862 } 863 864 /** 865 * Creates an instance of a {@link PhoneAccount} based on the current builder settings. 866 * 867 * @return The {@link PhoneAccount}. 868 */ build()869 public PhoneAccount build() { 870 // If no supported URI schemes were defined, assume "tel" is supported. 871 if (mSupportedUriSchemes.isEmpty()) { 872 addSupportedUriScheme(SCHEME_TEL); 873 } 874 875 return new PhoneAccount( 876 mAccountHandle, 877 mAddress, 878 mSubscriptionAddress, 879 mCapabilities, 880 mIcon, 881 mHighlightColor, 882 mLabel, 883 mShortDescription, 884 mSupportedUriSchemes, 885 mExtras, 886 mSupportedAudioRoutes, 887 mIsEnabled, 888 mGroupId, 889 mSimultaneousCallingRestriction); 890 } 891 } 892 PhoneAccount( PhoneAccountHandle account, Uri address, Uri subscriptionAddress, int capabilities, Icon icon, int highlightColor, CharSequence label, CharSequence shortDescription, List<String> supportedUriSchemes, Bundle extras, int supportedAudioRoutes, boolean isEnabled, String groupId, Set<PhoneAccountHandle> simultaneousCallingRestriction)893 private PhoneAccount( 894 PhoneAccountHandle account, 895 Uri address, 896 Uri subscriptionAddress, 897 int capabilities, 898 Icon icon, 899 int highlightColor, 900 CharSequence label, 901 CharSequence shortDescription, 902 List<String> supportedUriSchemes, 903 Bundle extras, 904 int supportedAudioRoutes, 905 boolean isEnabled, 906 String groupId, 907 Set<PhoneAccountHandle> simultaneousCallingRestriction) { 908 mAccountHandle = account; 909 mAddress = address; 910 mSubscriptionAddress = subscriptionAddress; 911 mCapabilities = capabilities; 912 mIcon = icon; 913 mHighlightColor = highlightColor; 914 mLabel = label; 915 mShortDescription = shortDescription; 916 mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes); 917 mExtras = extras; 918 mSupportedAudioRoutes = supportedAudioRoutes; 919 mIsEnabled = isEnabled; 920 mGroupId = groupId; 921 mSimultaneousCallingRestriction = simultaneousCallingRestriction; 922 } 923 builder( PhoneAccountHandle accountHandle, CharSequence label)924 public static Builder builder( 925 PhoneAccountHandle accountHandle, 926 CharSequence label) { 927 return new Builder(accountHandle, label); 928 } 929 930 /** 931 * Returns a builder initialized with the current {@link PhoneAccount} instance. 932 * 933 * @return The builder. 934 */ toBuilder()935 public Builder toBuilder() { return new Builder(this); } 936 937 /** 938 * The unique identifier of this {@code PhoneAccount}. 939 * 940 * @return A {@code PhoneAccountHandle}. 941 */ getAccountHandle()942 public PhoneAccountHandle getAccountHandle() { 943 return mAccountHandle; 944 } 945 946 /** 947 * The address (e.g., a phone number) associated with this {@code PhoneAccount}. This 948 * represents the destination from which outgoing calls using this {@code PhoneAccount} 949 * will appear to come, if applicable, and the destination to which incoming calls using this 950 * {@code PhoneAccount} may be addressed. 951 * 952 * @return A address expressed as a {@code Uri}, for example, a phone number. 953 */ getAddress()954 public Uri getAddress() { 955 return mAddress; 956 } 957 958 /** 959 * The raw callback number used for this {@code PhoneAccount}, as distinct from 960 * {@link #getAddress()}. For the majority of {@code PhoneAccount}s this should be registered 961 * as {@code null}. It is used by the system for SIM-based {@code PhoneAccount} registration 962 * where {@link android.telephony.TelephonyManager#setLine1NumberForDisplay(String, String)} 963 * has been used to alter the callback number. 964 * <p> 965 * 966 * @return The subscription number, suitable for display to the user. 967 */ getSubscriptionAddress()968 public Uri getSubscriptionAddress() { 969 return mSubscriptionAddress; 970 } 971 972 /** 973 * The capabilities of this {@code PhoneAccount}. 974 * 975 * @return A bit field of flags describing this {@code PhoneAccount}'s capabilities. 976 */ getCapabilities()977 public int getCapabilities() { 978 return mCapabilities; 979 } 980 981 /** 982 * Determines if this {@code PhoneAccount} has a capabilities specified by the passed in 983 * bit mask. 984 * 985 * @param capability The capabilities to check. 986 * @return {@code true} if the phone account has the capability. 987 */ hasCapabilities(int capability)988 public boolean hasCapabilities(int capability) { 989 return (mCapabilities & capability) == capability; 990 } 991 992 /** 993 * Determines if this {@code PhoneAccount} has routes specified by the passed in bit mask. 994 * 995 * @param route The routes to check. 996 * @return {@code true} if the phone account has the routes. 997 * @hide 998 */ hasAudioRoutes(int routes)999 public boolean hasAudioRoutes(int routes) { 1000 return (mSupportedAudioRoutes & routes) == routes; 1001 } 1002 1003 /** 1004 * A short label describing a {@code PhoneAccount}. 1005 * 1006 * @return A label for this {@code PhoneAccount}. 1007 */ getLabel()1008 public CharSequence getLabel() { 1009 return mLabel; 1010 } 1011 1012 /** 1013 * A short paragraph describing this {@code PhoneAccount}. 1014 * 1015 * @return A description for this {@code PhoneAccount}. 1016 */ getShortDescription()1017 public CharSequence getShortDescription() { 1018 return mShortDescription; 1019 } 1020 1021 /** 1022 * The URI schemes supported by this {@code PhoneAccount}. 1023 * 1024 * @return The URI schemes. 1025 */ getSupportedUriSchemes()1026 public List<String> getSupportedUriSchemes() { 1027 return mSupportedUriSchemes; 1028 } 1029 1030 /** 1031 * The extras associated with this {@code PhoneAccount}. 1032 * <p> 1033 * A {@link ConnectionService} may provide implementation specific information about the 1034 * {@link PhoneAccount} via the extras. 1035 * 1036 * @return The extras. 1037 */ getExtras()1038 public Bundle getExtras() { 1039 return mExtras; 1040 } 1041 1042 /** 1043 * The audio routes supported by this {@code PhoneAccount}. 1044 * 1045 * @hide 1046 */ getSupportedAudioRoutes()1047 public int getSupportedAudioRoutes() { 1048 return mSupportedAudioRoutes; 1049 } 1050 1051 /** 1052 * The icon to represent this {@code PhoneAccount}. 1053 * 1054 * @return The icon. 1055 */ getIcon()1056 public Icon getIcon() { 1057 return mIcon; 1058 } 1059 1060 /** 1061 * Indicates whether the user has enabled this {@code PhoneAccount} or not. This value is only 1062 * populated for {@code PhoneAccount}s returned by {@link TelecomManager#getPhoneAccount}. 1063 * 1064 * @return {@code true} if the account is enabled by the user, {@code false} otherwise. 1065 */ isEnabled()1066 public boolean isEnabled() { 1067 return mIsEnabled; 1068 } 1069 1070 /** 1071 * A non-empty {@link String} representing the group that A {@link PhoneAccount} is in or an 1072 * empty {@link String} if the {@link PhoneAccount} is not in a group. If this 1073 * {@link PhoneAccount} is in a group, this new {@link PhoneAccount} will replace a registered 1074 * {@link PhoneAccount} that is in the same group. When the {@link PhoneAccount} is replaced, 1075 * its user defined defaults and enabled status will also pass to this new {@link PhoneAccount}. 1076 * Only {@link PhoneAccount}s that share the same {@link ConnectionService} can be replaced. 1077 * 1078 * @return A non-empty String Id if this {@link PhoneAccount} belongs to a group. 1079 * @hide 1080 */ getGroupId()1081 public String getGroupId() { 1082 return mGroupId; 1083 } 1084 1085 /** 1086 * Determines if the {@link PhoneAccount} supports calls to/from addresses with a specified URI 1087 * scheme. 1088 * 1089 * @param uriScheme The URI scheme to check. 1090 * @return {@code true} if the {@code PhoneAccount} supports calls to/from addresses with the 1091 * specified URI scheme. 1092 */ supportsUriScheme(String uriScheme)1093 public boolean supportsUriScheme(String uriScheme) { 1094 if (mSupportedUriSchemes == null || uriScheme == null) { 1095 return false; 1096 } 1097 1098 for (String scheme : mSupportedUriSchemes) { 1099 if (scheme != null && scheme.equals(uriScheme)) { 1100 return true; 1101 } 1102 } 1103 return false; 1104 } 1105 1106 /** 1107 * A highlight color to use in displaying information about this {@code PhoneAccount}. 1108 * 1109 * @return A hexadecimal color value. 1110 */ getHighlightColor()1111 public int getHighlightColor() { 1112 return mHighlightColor; 1113 } 1114 1115 /** 1116 * Sets the enabled state of the phone account. 1117 * @hide 1118 */ setIsEnabled(boolean isEnabled)1119 public void setIsEnabled(boolean isEnabled) { 1120 mIsEnabled = isEnabled; 1121 } 1122 1123 /** 1124 * @return {@code true} if the {@link PhoneAccount} is self-managed, {@code false} otherwise. 1125 * @hide 1126 */ isSelfManaged()1127 public boolean isSelfManaged() { 1128 return (mCapabilities & CAPABILITY_SELF_MANAGED) == CAPABILITY_SELF_MANAGED; 1129 } 1130 1131 /** 1132 * If a restriction is set (see {@link #hasSimultaneousCallingRestriction()}), this method 1133 * returns the Set of {@link PhoneAccountHandle}s that are allowed to support calls 1134 * simultaneously with this {@link PhoneAccount}. 1135 * <p> 1136 * If this {@link PhoneAccount} is busy with one or more ongoing calls, a restriction is set on 1137 * this PhoneAccount (see {@link #hasSimultaneousCallingRestriction()} to check), and a new 1138 * incoming or outgoing call is received or placed on a PhoneAccount that is not in this Set, 1139 * Telecom will reject or cancel the pending call in favor of keeping the ongoing call alive. 1140 * <p> 1141 * Note: Simultaneous calling restrictions can only be placed on {@link PhoneAccount}s that 1142 * were registered by the same application. Simultaneous calling across applications is 1143 * always possible as long as the {@link Connection} supports hold. 1144 * 1145 * @return the Set of {@link PhoneAccountHandle}s that this {@link PhoneAccount} supports 1146 * simultaneous calls with. 1147 * @throws IllegalStateException If there is no restriction set on this {@link PhoneAccount} 1148 * and this method is called. Whether or not there is a restriction can be checked using 1149 * {@link #hasSimultaneousCallingRestriction()}. 1150 */ 1151 @FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) getSimultaneousCallingRestriction()1152 public @NonNull Set<PhoneAccountHandle> getSimultaneousCallingRestriction() { 1153 if (mSimultaneousCallingRestriction == null) { 1154 throw new IllegalStateException("This method can not be called if there is no " 1155 + "simultaneous calling restriction. See #hasSimultaneousCallingRestriction"); 1156 } 1157 return mSimultaneousCallingRestriction; 1158 } 1159 1160 /** 1161 * Whether or not this {@link PhoneAccount} contains a simultaneous calling restriction on it. 1162 * 1163 * @return {@code true} if this PhoneAccount contains a simultaneous calling restriction, 1164 * {@code false} if it does not. Use {@link #getSimultaneousCallingRestriction()} to query which 1165 * other {@link PhoneAccount}s support simultaneous calling with this one. 1166 * @see #getSimultaneousCallingRestriction() for more information on how the sinultaneous 1167 * calling restriction works. 1168 */ 1169 @FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) hasSimultaneousCallingRestriction()1170 public boolean hasSimultaneousCallingRestriction() { 1171 return mSimultaneousCallingRestriction != null; 1172 } 1173 1174 // 1175 // Parcelable implementation 1176 // 1177 1178 @Override describeContents()1179 public int describeContents() { 1180 return 0; 1181 } 1182 1183 @Override writeToParcel(Parcel out, int flags)1184 public void writeToParcel(Parcel out, int flags) { 1185 if (mAccountHandle == null) { 1186 out.writeInt(0); 1187 } else { 1188 out.writeInt(1); 1189 mAccountHandle.writeToParcel(out, flags); 1190 } 1191 if (mAddress == null) { 1192 out.writeInt(0); 1193 } else { 1194 out.writeInt(1); 1195 mAddress.writeToParcel(out, flags); 1196 } 1197 if (mSubscriptionAddress == null) { 1198 out.writeInt(0); 1199 } else { 1200 out.writeInt(1); 1201 mSubscriptionAddress.writeToParcel(out, flags); 1202 } 1203 out.writeInt(mCapabilities); 1204 out.writeInt(mHighlightColor); 1205 out.writeCharSequence(mLabel); 1206 out.writeCharSequence(mShortDescription); 1207 out.writeStringList(mSupportedUriSchemes); 1208 1209 if (mIcon == null) { 1210 out.writeInt(0); 1211 } else { 1212 out.writeInt(1); 1213 mIcon.writeToParcel(out, flags); 1214 } 1215 out.writeByte((byte) (mIsEnabled ? 1 : 0)); 1216 out.writeBundle(mExtras); 1217 out.writeString(mGroupId); 1218 out.writeInt(mSupportedAudioRoutes); 1219 if (mSimultaneousCallingRestriction == null) { 1220 out.writeBoolean(false); 1221 } else { 1222 out.writeBoolean(true); 1223 out.writeTypedList(mSimultaneousCallingRestriction.stream().toList()); 1224 } 1225 } 1226 1227 public static final @android.annotation.NonNull Creator<PhoneAccount> CREATOR 1228 = new Creator<PhoneAccount>() { 1229 @Override 1230 public PhoneAccount createFromParcel(Parcel in) { 1231 return new PhoneAccount(in); 1232 } 1233 1234 @Override 1235 public PhoneAccount[] newArray(int size) { 1236 return new PhoneAccount[size]; 1237 } 1238 }; 1239 PhoneAccount(Parcel in)1240 private PhoneAccount(Parcel in) { 1241 if (in.readInt() > 0) { 1242 mAccountHandle = PhoneAccountHandle.CREATOR.createFromParcel(in); 1243 } else { 1244 mAccountHandle = null; 1245 } 1246 if (in.readInt() > 0) { 1247 mAddress = Uri.CREATOR.createFromParcel(in); 1248 } else { 1249 mAddress = null; 1250 } 1251 if (in.readInt() > 0) { 1252 mSubscriptionAddress = Uri.CREATOR.createFromParcel(in); 1253 } else { 1254 mSubscriptionAddress = null; 1255 } 1256 mCapabilities = in.readInt(); 1257 mHighlightColor = in.readInt(); 1258 mLabel = in.readCharSequence(); 1259 mShortDescription = in.readCharSequence(); 1260 mSupportedUriSchemes = Collections.unmodifiableList(in.createStringArrayList()); 1261 if (in.readInt() > 0) { 1262 mIcon = Icon.CREATOR.createFromParcel(in); 1263 } else { 1264 mIcon = null; 1265 } 1266 mIsEnabled = in.readByte() == 1; 1267 mExtras = in.readBundle(); 1268 mGroupId = in.readString(); 1269 mSupportedAudioRoutes = in.readInt(); 1270 if (in.readBoolean()) { 1271 List<PhoneAccountHandle> list = new ArrayList<>(); 1272 in.readTypedList(list, PhoneAccountHandle.CREATOR); 1273 mSimultaneousCallingRestriction = new ArraySet<>(list); 1274 } else { 1275 mSimultaneousCallingRestriction = null; 1276 } 1277 } 1278 1279 @Override toString()1280 public String toString() { 1281 StringBuilder sb = new StringBuilder().append("[[") 1282 .append(mIsEnabled ? 'X' : ' ') 1283 .append("] PhoneAccount: ") 1284 .append(mAccountHandle) 1285 .append(" Capabilities: ") 1286 .append(capabilitiesToString()) 1287 .append(" Audio Routes: ") 1288 .append(audioRoutesToString()) 1289 .append(" Schemes: "); 1290 for (String scheme : mSupportedUriSchemes) { 1291 sb.append(scheme) 1292 .append(" "); 1293 } 1294 sb.append(" Extras: "); 1295 sb.append(mExtras); 1296 sb.append(" GroupId: "); 1297 sb.append(Log.pii(mGroupId)); 1298 sb.append(" SC Restrictions: "); 1299 if (hasSimultaneousCallingRestriction()) { 1300 sb.append("[ "); 1301 for (PhoneAccountHandle handle : mSimultaneousCallingRestriction) { 1302 sb.append(handle); 1303 sb.append(" "); 1304 } 1305 sb.append("]"); 1306 } else { 1307 sb.append("[NONE]"); 1308 } 1309 sb.append("]"); 1310 return sb.toString(); 1311 } 1312 1313 /** 1314 * Generates a string representation of a capabilities bitmask. 1315 * 1316 * @return String representation of the capabilities bitmask. 1317 * @hide 1318 */ capabilitiesToString()1319 public String capabilitiesToString() { 1320 StringBuilder sb = new StringBuilder(); 1321 if (hasCapabilities(CAPABILITY_SELF_MANAGED)) { 1322 sb.append("SelfManaged "); 1323 } 1324 if (hasCapabilities(CAPABILITY_SUPPORTS_VIDEO_CALLING)) { 1325 sb.append("SuppVideo "); 1326 } 1327 if (hasCapabilities(CAPABILITY_VIDEO_CALLING)) { 1328 sb.append("Video "); 1329 } 1330 if (hasCapabilities(CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE)) { 1331 sb.append("Presence "); 1332 } 1333 if (hasCapabilities(CAPABILITY_CALL_PROVIDER)) { 1334 sb.append("CallProvider "); 1335 } 1336 if (hasCapabilities(CAPABILITY_CALL_SUBJECT)) { 1337 sb.append("CallSubject "); 1338 } 1339 if (hasCapabilities(CAPABILITY_CONNECTION_MANAGER)) { 1340 sb.append("ConnectionMgr "); 1341 } 1342 if (hasCapabilities(CAPABILITY_EMERGENCY_CALLS_ONLY)) { 1343 sb.append("EmergOnly "); 1344 } 1345 if (hasCapabilities(CAPABILITY_MULTI_USER)) { 1346 sb.append("MultiUser "); 1347 } 1348 if (hasCapabilities(CAPABILITY_PLACE_EMERGENCY_CALLS)) { 1349 sb.append("PlaceEmerg "); 1350 } 1351 if (hasCapabilities(CAPABILITY_EMERGENCY_PREFERRED)) { 1352 sb.append("EmerPrefer "); 1353 } 1354 if (hasCapabilities(CAPABILITY_EMERGENCY_VIDEO_CALLING)) { 1355 sb.append("EmergVideo "); 1356 } 1357 if (hasCapabilities(CAPABILITY_SIM_SUBSCRIPTION)) { 1358 sb.append("SimSub "); 1359 } 1360 if (hasCapabilities(CAPABILITY_RTT)) { 1361 sb.append("Rtt "); 1362 } 1363 if (hasCapabilities(CAPABILITY_ADHOC_CONFERENCE_CALLING)) { 1364 sb.append("AdhocConf "); 1365 } 1366 if (hasCapabilities(CAPABILITY_CALL_COMPOSER)) { 1367 sb.append("CallComposer "); 1368 } 1369 if (hasCapabilities(CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS)) { 1370 sb.append("SuppVoice "); 1371 } 1372 if (hasCapabilities(CAPABILITY_VOICE_CALLING_AVAILABLE)) { 1373 sb.append("Voice "); 1374 } 1375 if (hasCapabilities(CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS)) { 1376 sb.append("TransactOps "); 1377 } 1378 if (hasCapabilities(CAPABILITY_SUPPORTS_CALL_STREAMING)) { 1379 sb.append("Stream "); 1380 } 1381 return sb.toString(); 1382 } 1383 audioRoutesToString()1384 private String audioRoutesToString() { 1385 StringBuilder sb = new StringBuilder(); 1386 1387 if (hasAudioRoutes(CallAudioState.ROUTE_BLUETOOTH)) { 1388 sb.append("B"); 1389 } 1390 if (hasAudioRoutes(CallAudioState.ROUTE_EARPIECE)) { 1391 sb.append("E"); 1392 } 1393 if (hasAudioRoutes(CallAudioState.ROUTE_SPEAKER)) { 1394 sb.append("S"); 1395 } 1396 if (hasAudioRoutes(CallAudioState.ROUTE_WIRED_HEADSET)) { 1397 sb.append("W"); 1398 } 1399 1400 return sb.toString(); 1401 } 1402 1403 /** 1404 * Determines if two {@link Bundle}s are equal. 1405 * @param extras First {@link Bundle} to check. 1406 * @param newExtras {@link Bundle} to compare against. 1407 * @return {@code true} if the {@link Bundle}s are equal, {@code false} otherwise. 1408 */ areBundlesEqual(Bundle extras, Bundle newExtras)1409 private static boolean areBundlesEqual(Bundle extras, Bundle newExtras) { 1410 if (extras == null || newExtras == null) { 1411 return extras == newExtras; 1412 } 1413 1414 if (extras.size() != newExtras.size()) { 1415 return false; 1416 } 1417 1418 for(String key : extras.keySet()) { 1419 if (key != null) { 1420 final Object value = extras.get(key); 1421 final Object newValue = newExtras.get(key); 1422 if (!Objects.equals(value, newValue)) { 1423 return false; 1424 } 1425 } 1426 } 1427 return true; 1428 } 1429 } 1430