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 android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SystemApi; 23 import android.annotation.TestApi; 24 import android.compat.annotation.UnsupportedAppUsage; 25 import android.content.pm.ServiceInfo; 26 import android.net.Uri; 27 import android.os.Build; 28 import android.os.Bundle; 29 import android.os.Handler; 30 import android.os.ParcelFileDescriptor; 31 32 import com.android.internal.telecom.IVideoProvider; 33 34 import java.io.IOException; 35 import java.io.InputStreamReader; 36 import java.io.OutputStreamWriter; 37 import java.lang.annotation.Retention; 38 import java.lang.annotation.RetentionPolicy; 39 import java.nio.charset.StandardCharsets; 40 import java.util.ArrayList; 41 import java.util.Arrays; 42 import java.util.Collections; 43 import java.util.List; 44 import java.util.Map; 45 import java.util.Objects; 46 import java.util.concurrent.CopyOnWriteArrayList; 47 48 /** 49 * Represents an ongoing phone call that the in-call app should present to the user. 50 */ 51 public final class Call { 52 /** 53 * The state of a {@code Call} when newly created. 54 */ 55 public static final int STATE_NEW = 0; 56 57 /** 58 * The state of an outgoing {@code Call} when dialing the remote number, but not yet connected. 59 */ 60 public static final int STATE_DIALING = 1; 61 62 /** 63 * The state of an incoming {@code Call} when ringing locally, but not yet connected. 64 */ 65 public static final int STATE_RINGING = 2; 66 67 /** 68 * The state of a {@code Call} when in a holding state. 69 */ 70 public static final int STATE_HOLDING = 3; 71 72 /** 73 * The state of a {@code Call} when actively supporting conversation. 74 */ 75 public static final int STATE_ACTIVE = 4; 76 77 /** 78 * The state of a {@code Call} when no further voice or other communication is being 79 * transmitted, the remote side has been or will inevitably be informed that the {@code Call} 80 * is no longer active, and the local data transport has or inevitably will release resources 81 * associated with this {@code Call}. 82 */ 83 public static final int STATE_DISCONNECTED = 7; 84 85 /** 86 * The state of an outgoing {@code Call} when waiting on user to select a 87 * {@link PhoneAccount} through which to place the call. 88 */ 89 public static final int STATE_SELECT_PHONE_ACCOUNT = 8; 90 91 /** 92 * @hide 93 * @deprecated use STATE_SELECT_PHONE_ACCOUNT. 94 */ 95 @Deprecated 96 @SystemApi 97 public static final int STATE_PRE_DIAL_WAIT = STATE_SELECT_PHONE_ACCOUNT; 98 99 /** 100 * The initial state of an outgoing {@code Call}. 101 * Common transitions are to {@link #STATE_DIALING} state for a successful call or 102 * {@link #STATE_DISCONNECTED} if it failed. 103 */ 104 public static final int STATE_CONNECTING = 9; 105 106 /** 107 * The state of a {@code Call} when the user has initiated a disconnection of the call, but the 108 * call has not yet been disconnected by the underlying {@code ConnectionService}. The next 109 * state of the call is (potentially) {@link #STATE_DISCONNECTED}. 110 */ 111 public static final int STATE_DISCONNECTING = 10; 112 113 /** 114 * The state of an external call which is in the process of being pulled from a remote device to 115 * the local device. 116 * <p> 117 * A call can only be in this state if the {@link Details#PROPERTY_IS_EXTERNAL_CALL} property 118 * and {@link Details#CAPABILITY_CAN_PULL_CALL} capability are set on the call. 119 * <p> 120 * An {@link InCallService} will only see this state if it has the 121 * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true} in its 122 * manifest. 123 */ 124 public static final int STATE_PULLING_CALL = 11; 125 126 /** 127 * The state of a call that is active with the network, but the audio from the call is 128 * being intercepted by an app on the local device. Telecom does not hold audio focus in this 129 * state, and the call will be invisible to the user except for a persistent notification. 130 */ 131 public static final int STATE_AUDIO_PROCESSING = 12; 132 133 /** 134 * The state of a call that is being presented to the user after being in 135 * {@link #STATE_AUDIO_PROCESSING}. The call is still active with the network in this case, and 136 * Telecom will hold audio focus and play a ringtone if appropriate. 137 */ 138 public static final int STATE_SIMULATED_RINGING = 13; 139 140 /** 141 * @hide 142 */ 143 @IntDef(prefix = { "STATE_" }, 144 value = { 145 STATE_NEW, 146 STATE_DIALING, 147 STATE_RINGING, 148 STATE_HOLDING, 149 STATE_ACTIVE, 150 STATE_DISCONNECTED, 151 STATE_SELECT_PHONE_ACCOUNT, 152 STATE_CONNECTING, 153 STATE_DISCONNECTING, 154 STATE_PULLING_CALL, 155 STATE_AUDIO_PROCESSING, 156 STATE_SIMULATED_RINGING 157 }) 158 @Retention(RetentionPolicy.SOURCE) 159 public @interface CallState {}; 160 161 /** 162 * The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call 163 * extras. Used to pass the phone accounts to display on the front end to the user in order to 164 * select phone accounts to (for example) place a call. 165 * @deprecated Use the list from {@link #EXTRA_SUGGESTED_PHONE_ACCOUNTS} instead. 166 */ 167 @Deprecated 168 public static final String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts"; 169 170 /** 171 * Key for extra used to pass along a list of {@link PhoneAccountSuggestion}s to the in-call 172 * UI when a call enters the {@link #STATE_SELECT_PHONE_ACCOUNT} state. The list included here 173 * will have the same length and be in the same order as the list passed with 174 * {@link #AVAILABLE_PHONE_ACCOUNTS}. 175 */ 176 public static final String EXTRA_SUGGESTED_PHONE_ACCOUNTS = 177 "android.telecom.extra.SUGGESTED_PHONE_ACCOUNTS"; 178 179 /** 180 * Extra key used to indicate the time (in milliseconds since midnight, January 1, 1970 UTC) 181 * when the last outgoing emergency call was made. This is used to identify potential emergency 182 * callbacks. 183 */ 184 public static final String EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS = 185 "android.telecom.extra.LAST_EMERGENCY_CALLBACK_TIME_MILLIS"; 186 187 188 /** 189 * Extra key used to indicate whether a {@link CallScreeningService} has requested to silence 190 * the ringtone for a call. If the {@link InCallService} declares 191 * {@link TelecomManager#METADATA_IN_CALL_SERVICE_RINGING} in its manifest, it should not 192 * play a ringtone for an incoming call with this extra key set. 193 */ 194 public static final String EXTRA_SILENT_RINGING_REQUESTED = 195 "android.telecom.extra.SILENT_RINGING_REQUESTED"; 196 197 /** 198 * Call event sent from a {@link Call} via {@link #sendCallEvent(String, Bundle)} to inform 199 * Telecom that the user has requested that the current {@link Call} should be handed over 200 * to another {@link ConnectionService}. 201 * <p> 202 * The caller must specify the {@link #EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE} to indicate to 203 * Telecom which {@link PhoneAccountHandle} the {@link Call} should be handed over to. 204 * @hide 205 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated 206 * APIs instead. 207 */ 208 public static final String EVENT_REQUEST_HANDOVER = 209 "android.telecom.event.REQUEST_HANDOVER"; 210 211 /** 212 * Extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event. Specifies the 213 * {@link PhoneAccountHandle} to which a call should be handed over to. 214 * @hide 215 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated 216 * APIs instead. 217 */ 218 public static final String EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE = 219 "android.telecom.extra.HANDOVER_PHONE_ACCOUNT_HANDLE"; 220 221 /** 222 * Integer extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event. Specifies the 223 * video state of the call when it is handed over to the new {@link PhoneAccount}. 224 * <p> 225 * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY}, 226 * {@link VideoProfile#STATE_BIDIRECTIONAL}, {@link VideoProfile#STATE_RX_ENABLED}, and 227 * {@link VideoProfile#STATE_TX_ENABLED}. 228 * @hide 229 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated 230 * APIs instead. 231 */ 232 public static final String EXTRA_HANDOVER_VIDEO_STATE = 233 "android.telecom.extra.HANDOVER_VIDEO_STATE"; 234 235 /** 236 * Extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event. Used by the 237 * {@link InCallService} initiating a handover to provide a {@link Bundle} with extra 238 * information to the handover {@link ConnectionService} specified by 239 * {@link #EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE}. 240 * <p> 241 * This {@link Bundle} is not interpreted by Telecom, but passed as-is to the 242 * {@link ConnectionService} via the request extras when 243 * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} 244 * is called to initate the handover. 245 * @hide 246 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated 247 * APIs instead. 248 */ 249 public static final String EXTRA_HANDOVER_EXTRAS = "android.telecom.extra.HANDOVER_EXTRAS"; 250 251 /** 252 * Call event sent from Telecom to the handover {@link ConnectionService} via 253 * {@link Connection#onCallEvent(String, Bundle)} to inform a {@link Connection} that a handover 254 * to the {@link ConnectionService} has completed successfully. 255 * <p> 256 * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event. 257 * @hide 258 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated 259 * APIs instead. 260 */ 261 public static final String EVENT_HANDOVER_COMPLETE = 262 "android.telecom.event.HANDOVER_COMPLETE"; 263 264 /** 265 * Call event sent from Telecom to the handover destination {@link ConnectionService} via 266 * {@link Connection#onCallEvent(String, Bundle)} to inform the handover destination that the 267 * source connection has disconnected. The {@link Bundle} parameter for the call event will be 268 * {@code null}. 269 * <p> 270 * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event. 271 * @hide 272 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated 273 * APIs instead. 274 */ 275 public static final String EVENT_HANDOVER_SOURCE_DISCONNECTED = 276 "android.telecom.event.HANDOVER_SOURCE_DISCONNECTED"; 277 278 /** 279 * Call event sent from Telecom to the handover {@link ConnectionService} via 280 * {@link Connection#onCallEvent(String, Bundle)} to inform a {@link Connection} that a handover 281 * to the {@link ConnectionService} has failed. 282 * <p> 283 * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event. 284 * @hide 285 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated 286 * APIs instead. 287 */ 288 public static final String EVENT_HANDOVER_FAILED = 289 "android.telecom.event.HANDOVER_FAILED"; 290 291 /** 292 * Event reported from the Telecom stack to report an in-call diagnostic message which the 293 * dialer app may opt to display to the user. A diagnostic message is used to communicate 294 * scenarios the device has detected which may impact the quality of the ongoing call. 295 * <p> 296 * For example a problem with a bluetooth headset may generate a recommendation for the user to 297 * try using the speakerphone instead, or if the device detects it has entered a poor service 298 * area, the user might be warned so that they can finish their call prior to it dropping. 299 * <p> 300 * A diagnostic message is considered persistent in nature. When the user enters a poor service 301 * area, for example, the accompanying diagnostic message persists until they leave the area 302 * of poor service. Each message is accompanied with a {@link #EXTRA_DIAGNOSTIC_MESSAGE_ID} 303 * which uniquely identifies the diagnostic condition being reported. The framework raises a 304 * call event of type {@link #EVENT_CLEAR_DIAGNOSTIC_MESSAGE} when the condition reported has 305 * been cleared. The dialer app should display the diagnostic message until it is cleared. 306 * If multiple diagnostic messages are sent with different IDs (which have not yet been cleared) 307 * the dialer app should prioritize the most recently received message, but still provide the 308 * user with a means to review past messages. 309 * <p> 310 * The text of the message is found in {@link #EXTRA_DIAGNOSTIC_MESSAGE} in the form of a human 311 * readable {@link CharSequence} which is intended for display in the call UX. 312 * <p> 313 * The telecom framework audibly notifies the user of the presence of a diagnostic message, so 314 * the dialer app needs only to concern itself with visually displaying the message. 315 * <p> 316 * The dialer app receives this event via 317 * {@link Call.Callback#onConnectionEvent(Call, String, Bundle)}. 318 */ 319 public static final String EVENT_DISPLAY_DIAGNOSTIC_MESSAGE = 320 "android.telecom.event.DISPLAY_DIAGNOSTIC_MESSAGE"; 321 322 /** 323 * Event reported from the telecom framework when a diagnostic message previously raised with 324 * {@link #EVENT_DISPLAY_DIAGNOSTIC_MESSAGE} has cleared and is no longer pertinent. 325 * <p> 326 * The {@link #EXTRA_DIAGNOSTIC_MESSAGE_ID} indicates the diagnostic message which has been 327 * cleared. 328 * <p> 329 * The dialer app receives this event via 330 * {@link Call.Callback#onConnectionEvent(Call, String, Bundle)}. 331 */ 332 public static final String EVENT_CLEAR_DIAGNOSTIC_MESSAGE = 333 "android.telecom.event.CLEAR_DIAGNOSTIC_MESSAGE"; 334 335 /** 336 * Integer extra representing a message ID for a message posted via 337 * {@link #EVENT_DISPLAY_DIAGNOSTIC_MESSAGE}. Used to ensure that the dialer app knows when 338 * the message in question has cleared via {@link #EVENT_CLEAR_DIAGNOSTIC_MESSAGE}. 339 */ 340 public static final String EXTRA_DIAGNOSTIC_MESSAGE_ID = 341 "android.telecom.extra.DIAGNOSTIC_MESSAGE_ID"; 342 343 /** 344 * {@link CharSequence} extra used with {@link #EVENT_DISPLAY_DIAGNOSTIC_MESSAGE}. This is the 345 * diagnostic message the dialer app should display. 346 */ 347 public static final String EXTRA_DIAGNOSTIC_MESSAGE = 348 "android.telecom.extra.DIAGNOSTIC_MESSAGE"; 349 350 /** 351 * Reject reason used with {@link #reject(int)} to indicate that the user is rejecting this 352 * call because they have declined to answer it. This typically means that they are unable 353 * to answer the call at this time and would prefer it be sent to voicemail. 354 */ 355 public static final int REJECT_REASON_DECLINED = 1; 356 357 /** 358 * Reject reason used with {@link #reject(int)} to indicate that the user is rejecting this 359 * call because it is an unwanted call. This allows the user to indicate that they are 360 * rejecting a call because it is likely a nuisance call. 361 */ 362 public static final int REJECT_REASON_UNWANTED = 2; 363 364 /** 365 * @hide 366 */ 367 @IntDef(prefix = { "REJECT_REASON_" }, 368 value = {REJECT_REASON_DECLINED, REJECT_REASON_UNWANTED}) 369 @Retention(RetentionPolicy.SOURCE) 370 public @interface RejectReason {}; 371 372 public static class Details { 373 /** @hide */ 374 @Retention(RetentionPolicy.SOURCE) 375 @IntDef( 376 prefix = { "DIRECTION_" }, 377 value = {DIRECTION_UNKNOWN, DIRECTION_INCOMING, DIRECTION_OUTGOING}) 378 public @interface CallDirection {} 379 380 /** 381 * Indicates that the call is neither and incoming nor an outgoing call. This can be the 382 * case for calls reported directly by a {@link ConnectionService} in special cases such as 383 * call handovers. 384 */ 385 public static final int DIRECTION_UNKNOWN = -1; 386 387 /** 388 * Indicates that the call is an incoming call. 389 */ 390 public static final int DIRECTION_INCOMING = 0; 391 392 /** 393 * Indicates that the call is an outgoing call. 394 */ 395 public static final int DIRECTION_OUTGOING = 1; 396 397 /** Call can currently be put on hold or unheld. */ 398 public static final int CAPABILITY_HOLD = 0x00000001; 399 400 /** Call supports the hold feature. */ 401 public static final int CAPABILITY_SUPPORT_HOLD = 0x00000002; 402 403 /** 404 * Calls within a conference can be merged. A {@link ConnectionService} has the option to 405 * add a {@link Conference} call before the child {@link Connection}s are merged. This is how 406 * CDMA-based {@link Connection}s are implemented. For these unmerged {@link Conference}s, this 407 * capability allows a merge button to be shown while the conference call is in the foreground 408 * of the in-call UI. 409 * <p> 410 * This is only intended for use by a {@link Conference}. 411 */ 412 public static final int CAPABILITY_MERGE_CONFERENCE = 0x00000004; 413 414 /** 415 * Calls within a conference can be swapped between foreground and background. 416 * See {@link #CAPABILITY_MERGE_CONFERENCE} for additional information. 417 * <p> 418 * This is only intended for use by a {@link Conference}. 419 */ 420 public static final int CAPABILITY_SWAP_CONFERENCE = 0x00000008; 421 422 /** 423 * @hide 424 */ 425 public static final int CAPABILITY_UNUSED_1 = 0x00000010; 426 427 /** Call supports responding via text option. */ 428 public static final int CAPABILITY_RESPOND_VIA_TEXT = 0x00000020; 429 430 /** Call can be muted. */ 431 public static final int CAPABILITY_MUTE = 0x00000040; 432 433 /** 434 * Call supports conference call management. This capability only applies to {@link Conference} 435 * calls which can have {@link Connection}s as children. 436 */ 437 public static final int CAPABILITY_MANAGE_CONFERENCE = 0x00000080; 438 439 /** 440 * Local device supports receiving video. 441 */ 442 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_RX = 0x00000100; 443 444 /** 445 * Local device supports transmitting video. 446 */ 447 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_TX = 0x00000200; 448 449 /** 450 * Local device supports bidirectional video calling. 451 */ 452 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL = 453 CAPABILITY_SUPPORTS_VT_LOCAL_RX | CAPABILITY_SUPPORTS_VT_LOCAL_TX; 454 455 /** 456 * Remote device supports receiving video. 457 */ 458 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_RX = 0x00000400; 459 460 /** 461 * Remote device supports transmitting video. 462 */ 463 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 0x00000800; 464 465 /** 466 * Remote device supports bidirectional video calling. 467 */ 468 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL = 469 CAPABILITY_SUPPORTS_VT_REMOTE_RX | CAPABILITY_SUPPORTS_VT_REMOTE_TX; 470 471 /** 472 * Call is able to be separated from its parent {@code Conference}, if any. 473 */ 474 public static final int CAPABILITY_SEPARATE_FROM_CONFERENCE = 0x00001000; 475 476 /** 477 * Call is able to be individually disconnected when in a {@code Conference}. 478 */ 479 public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 0x00002000; 480 481 /** 482 * Speed up audio setup for MT call. 483 * @hide 484 */ 485 public static final int CAPABILITY_SPEED_UP_MT_AUDIO = 0x00040000; 486 487 /** 488 * Call can be upgraded to a video call. 489 * @hide 490 * @deprecated Use {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and 491 * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL} to indicate for a call 492 * whether or not video calling is supported. 493 */ 494 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590) 495 public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000; 496 497 /** 498 * For video calls, indicates whether the outgoing video for the call can be paused using 499 * the {@link android.telecom.VideoProfile#STATE_PAUSED} VideoState. 500 */ 501 public static final int CAPABILITY_CAN_PAUSE_VIDEO = 0x00100000; 502 503 /** 504 * Call sends responses through connection. 505 * @hide 506 */ 507 public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 0x00200000; 508 509 /** 510 * When set, prevents a video {@code Call} from being downgraded to an audio-only call. 511 * <p> 512 * Should be set when the VideoState has the {@link VideoProfile#STATE_TX_ENABLED} or 513 * {@link VideoProfile#STATE_RX_ENABLED} bits set to indicate that the connection cannot be 514 * downgraded from a video call back to a VideoState of 515 * {@link VideoProfile#STATE_AUDIO_ONLY}. 516 * <p> 517 * Intuitively, a call which can be downgraded to audio should also have local and remote 518 * video 519 * capabilities (see {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and 520 * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL}). 521 */ 522 public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 0x00400000; 523 524 /** 525 * When set for an external call, indicates that this {@code Call} can be pulled from a 526 * remote device to the current device. 527 * <p> 528 * Should only be set on a {@code Call} where {@link #PROPERTY_IS_EXTERNAL_CALL} is set. 529 * <p> 530 * An {@link InCallService} will only see calls with this capability if it has the 531 * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true} 532 * in its manifest. 533 * <p> 534 * See {@link Connection#CAPABILITY_CAN_PULL_CALL} and 535 * {@link Connection#PROPERTY_IS_EXTERNAL_CALL}. 536 */ 537 public static final int CAPABILITY_CAN_PULL_CALL = 0x00800000; 538 539 /** Call supports the deflect feature. */ 540 public static final int CAPABILITY_SUPPORT_DEFLECT = 0x01000000; 541 542 /** 543 * Call supports adding participants to the call via 544 * {@link #addConferenceParticipants(List)}. Once participants are added, the call becomes 545 * an adhoc conference call ({@link #PROPERTY_IS_ADHOC_CONFERENCE}). 546 */ 547 public static final int CAPABILITY_ADD_PARTICIPANT = 0x02000000; 548 549 /** 550 * When set for a call, indicates that this {@code Call} can be transferred to another 551 * number. 552 * Call supports the confirmed and unconfirmed call transfer feature. 553 * 554 * @hide 555 */ 556 public static final int CAPABILITY_TRANSFER = 0x04000000; 557 558 /** 559 * When set for a call, indicates that this {@code Call} can be transferred to another 560 * ongoing call. 561 * Call supports the consultative call transfer feature. 562 * 563 * @hide 564 */ 565 public static final int CAPABILITY_TRANSFER_CONSULTATIVE = 0x08000000; 566 567 //****************************************************************************************** 568 // Next CAPABILITY value: 0x10000000 569 //****************************************************************************************** 570 571 /** 572 * Whether the call is currently a conference. 573 */ 574 public static final int PROPERTY_CONFERENCE = 0x00000001; 575 576 /** 577 * Whether the call is a generic conference, where we do not know the precise state of 578 * participants in the conference (eg. on CDMA). 579 */ 580 public static final int PROPERTY_GENERIC_CONFERENCE = 0x00000002; 581 582 /** 583 * Whether the call is made while the device is in emergency callback mode. 584 */ 585 public static final int PROPERTY_EMERGENCY_CALLBACK_MODE = 0x00000004; 586 587 /** 588 * Connection is using WIFI. 589 */ 590 public static final int PROPERTY_WIFI = 0x00000008; 591 592 /** 593 * When set, the UI should indicate to the user that a call is using high definition 594 * audio. 595 * <p> 596 * The underlying {@link ConnectionService} is responsible for reporting this 597 * property. It is important to note that this property is not intended to report the 598 * actual audio codec being used for a Call, but whether the call should be indicated 599 * to the user as high definition. 600 * <p> 601 * The Android Telephony stack reports this property for calls based on a number 602 * of factors, including which audio codec is used and whether a call is using an HD 603 * codec end-to-end. Some mobile operators choose to suppress display of an HD indication, 604 * and in these cases this property will not be set for a call even if the underlying audio 605 * codec is in fact "high definition". 606 */ 607 public static final int PROPERTY_HIGH_DEF_AUDIO = 0x00000010; 608 609 /** 610 * Whether the call is associated with the work profile. 611 */ 612 public static final int PROPERTY_ENTERPRISE_CALL = 0x00000020; 613 614 /** 615 * When set, indicates that this {@code Call} does not actually exist locally for the 616 * {@link ConnectionService}. 617 * <p> 618 * Consider, for example, a scenario where a user has two phones with the same phone number. 619 * When a user places a call on one device, the telephony stack can represent that call on 620 * the other device by adding it to the {@link ConnectionService} with the 621 * {@link Connection#PROPERTY_IS_EXTERNAL_CALL} property set. 622 * <p> 623 * An {@link InCallService} will only see calls with this property if it has the 624 * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true} 625 * in its manifest. 626 * <p> 627 * See {@link Connection#PROPERTY_IS_EXTERNAL_CALL}. 628 */ 629 public static final int PROPERTY_IS_EXTERNAL_CALL = 0x00000040; 630 631 /** 632 * Indicates that the call has CDMA Enhanced Voice Privacy enabled. 633 */ 634 public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 0x00000080; 635 636 /** 637 * Indicates that the call is from a self-managed {@link ConnectionService}. 638 * <p> 639 * See also {@link Connection#PROPERTY_SELF_MANAGED} 640 */ 641 public static final int PROPERTY_SELF_MANAGED = 0x00000100; 642 643 /** 644 * Indicates the call used Assisted Dialing. 645 * 646 * @see TelecomManager#EXTRA_USE_ASSISTED_DIALING 647 */ 648 public static final int PROPERTY_ASSISTED_DIALING = 0x00000200; 649 650 /** 651 * Indicates that the call is an RTT call. Use {@link #getRttCall()} to get the 652 * {@link RttCall} object that is used to send and receive text. 653 */ 654 public static final int PROPERTY_RTT = 0x00000400; 655 656 /** 657 * Indicates that the call has been identified as the network as an emergency call. This 658 * property may be set for both incoming and outgoing calls which the network identifies as 659 * emergency calls. 660 */ 661 public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 0x00000800; 662 663 /** 664 * Indicates that the call is using VoIP audio mode. 665 * <p> 666 * When this property is set, the {@link android.media.AudioManager} audio mode for this 667 * call will be {@link android.media.AudioManager#MODE_IN_COMMUNICATION}. When this 668 * property is not set, the audio mode for this call will be 669 * {@link android.media.AudioManager#MODE_IN_CALL}. 670 * <p> 671 * This property reflects changes made using {@link Connection#setAudioModeIsVoip(boolean)}. 672 * <p> 673 * You can use this property to determine whether an un-answered incoming call or a held 674 * call will use VoIP audio mode (if the call does not currently have focus, the system 675 * audio mode may not reflect the mode the call will use). 676 */ 677 public static final int PROPERTY_VOIP_AUDIO_MODE = 0x00001000; 678 679 /** 680 * Indicates that the call is an adhoc conference call. This property can be set for both 681 * incoming and outgoing calls. An adhoc conference call is formed using 682 * {@link #addConferenceParticipants(List)}, 683 * {@link TelecomManager#addNewIncomingConference(PhoneAccountHandle, Bundle)}, or 684 * {@link TelecomManager#startConference(List, Bundle)}, rather than by merging existing 685 * call using {@link #conference(Call)}. 686 */ 687 public static final int PROPERTY_IS_ADHOC_CONFERENCE = 0x00002000; 688 689 /** 690 * Connection is using cross sim technology. 691 * <p> 692 * Indicates that the {@link Connection} is using a cross sim technology which would 693 * register IMS over internet APN of default data subscription. 694 * <p> 695 */ 696 public static final int PROPERTY_CROSS_SIM = 0x00004000; 697 698 //****************************************************************************************** 699 // Next PROPERTY value: 0x00004000 700 //****************************************************************************************** 701 702 private final @CallState int mState; 703 private final String mTelecomCallId; 704 private final Uri mHandle; 705 private final int mHandlePresentation; 706 private final String mCallerDisplayName; 707 private final int mCallerDisplayNamePresentation; 708 private final PhoneAccountHandle mAccountHandle; 709 private final int mCallCapabilities; 710 private final int mCallProperties; 711 private final int mSupportedAudioRoutes = CallAudioState.ROUTE_ALL; 712 private final DisconnectCause mDisconnectCause; 713 private final long mConnectTimeMillis; 714 private final GatewayInfo mGatewayInfo; 715 private final int mVideoState; 716 private final StatusHints mStatusHints; 717 private final Bundle mExtras; 718 private final Bundle mIntentExtras; 719 private final long mCreationTimeMillis; 720 private final String mContactDisplayName; 721 private final @CallDirection int mCallDirection; 722 private final @Connection.VerificationStatus int mCallerNumberVerificationStatus; 723 724 /** 725 * Whether the supplied capabilities supports the specified capability. 726 * 727 * @param capabilities A bit field of capabilities. 728 * @param capability The capability to check capabilities for. 729 * @return Whether the specified capability is supported. 730 */ can(int capabilities, int capability)731 public static boolean can(int capabilities, int capability) { 732 return (capabilities & capability) == capability; 733 } 734 735 /** 736 * Whether the capabilities of this {@code Details} supports the specified capability. 737 * 738 * @param capability The capability to check capabilities for. 739 * @return Whether the specified capability is supported. 740 */ can(int capability)741 public boolean can(int capability) { 742 return can(mCallCapabilities, capability); 743 } 744 745 /** 746 * Render a set of capability bits ({@code CAPABILITY_*}) as a human readable string. 747 * 748 * @param capabilities A capability bit field. 749 * @return A human readable string representation. 750 */ capabilitiesToString(int capabilities)751 public static String capabilitiesToString(int capabilities) { 752 StringBuilder builder = new StringBuilder(); 753 builder.append("[Capabilities:"); 754 if (can(capabilities, CAPABILITY_HOLD)) { 755 builder.append(" CAPABILITY_HOLD"); 756 } 757 if (can(capabilities, CAPABILITY_SUPPORT_HOLD)) { 758 builder.append(" CAPABILITY_SUPPORT_HOLD"); 759 } 760 if (can(capabilities, CAPABILITY_MERGE_CONFERENCE)) { 761 builder.append(" CAPABILITY_MERGE_CONFERENCE"); 762 } 763 if (can(capabilities, CAPABILITY_SWAP_CONFERENCE)) { 764 builder.append(" CAPABILITY_SWAP_CONFERENCE"); 765 } 766 if (can(capabilities, CAPABILITY_RESPOND_VIA_TEXT)) { 767 builder.append(" CAPABILITY_RESPOND_VIA_TEXT"); 768 } 769 if (can(capabilities, CAPABILITY_MUTE)) { 770 builder.append(" CAPABILITY_MUTE"); 771 } 772 if (can(capabilities, CAPABILITY_MANAGE_CONFERENCE)) { 773 builder.append(" CAPABILITY_MANAGE_CONFERENCE"); 774 } 775 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_RX)) { 776 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_RX"); 777 } 778 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_TX)) { 779 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_TX"); 780 } 781 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL)) { 782 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL"); 783 } 784 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_RX)) { 785 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_RX"); 786 } 787 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_TX)) { 788 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_TX"); 789 } 790 if (can(capabilities, CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO)) { 791 builder.append(" CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO"); 792 } 793 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL)) { 794 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL"); 795 } 796 if (can(capabilities, CAPABILITY_SPEED_UP_MT_AUDIO)) { 797 builder.append(" CAPABILITY_SPEED_UP_MT_AUDIO"); 798 } 799 if (can(capabilities, CAPABILITY_CAN_UPGRADE_TO_VIDEO)) { 800 builder.append(" CAPABILITY_CAN_UPGRADE_TO_VIDEO"); 801 } 802 if (can(capabilities, CAPABILITY_CAN_PAUSE_VIDEO)) { 803 builder.append(" CAPABILITY_CAN_PAUSE_VIDEO"); 804 } 805 if (can(capabilities, CAPABILITY_CAN_PULL_CALL)) { 806 builder.append(" CAPABILITY_CAN_PULL_CALL"); 807 } 808 if (can(capabilities, CAPABILITY_SUPPORT_DEFLECT)) { 809 builder.append(" CAPABILITY_SUPPORT_DEFLECT"); 810 } 811 if (can(capabilities, CAPABILITY_ADD_PARTICIPANT)) { 812 builder.append(" CAPABILITY_ADD_PARTICIPANT"); 813 } 814 if (can(capabilities, CAPABILITY_TRANSFER)) { 815 builder.append(" CAPABILITY_TRANSFER"); 816 } 817 if (can(capabilities, CAPABILITY_TRANSFER_CONSULTATIVE)) { 818 builder.append(" CAPABILITY_TRANSFER_CONSULTATIVE"); 819 } 820 builder.append("]"); 821 return builder.toString(); 822 } 823 824 /** 825 * Whether the supplied properties includes the specified property. 826 * 827 * @param properties A bit field of properties. 828 * @param property The property to check properties for. 829 * @return Whether the specified property is supported. 830 */ hasProperty(int properties, int property)831 public static boolean hasProperty(int properties, int property) { 832 return (properties & property) == property; 833 } 834 835 /** 836 * Whether the properties of this {@code Details} includes the specified property. 837 * 838 * @param property The property to check properties for. 839 * @return Whether the specified property is supported. 840 */ hasProperty(int property)841 public boolean hasProperty(int property) { 842 return hasProperty(mCallProperties, property); 843 } 844 845 /** 846 * Render a set of property bits ({@code PROPERTY_*}) as a human readable string. 847 * 848 * @param properties A property bit field. 849 * @return A human readable string representation. 850 */ propertiesToString(int properties)851 public static String propertiesToString(int properties) { 852 StringBuilder builder = new StringBuilder(); 853 builder.append("[Properties:"); 854 if (hasProperty(properties, PROPERTY_CONFERENCE)) { 855 builder.append(" PROPERTY_CONFERENCE"); 856 } 857 if (hasProperty(properties, PROPERTY_GENERIC_CONFERENCE)) { 858 builder.append(" PROPERTY_GENERIC_CONFERENCE"); 859 } 860 if (hasProperty(properties, PROPERTY_WIFI)) { 861 builder.append(" PROPERTY_WIFI"); 862 } 863 if (hasProperty(properties, PROPERTY_HIGH_DEF_AUDIO)) { 864 builder.append(" PROPERTY_HIGH_DEF_AUDIO"); 865 } 866 if (hasProperty(properties, PROPERTY_EMERGENCY_CALLBACK_MODE)) { 867 builder.append(" PROPERTY_EMERGENCY_CALLBACK_MODE"); 868 } 869 if (hasProperty(properties, PROPERTY_IS_EXTERNAL_CALL)) { 870 builder.append(" PROPERTY_IS_EXTERNAL_CALL"); 871 } 872 if (hasProperty(properties, PROPERTY_HAS_CDMA_VOICE_PRIVACY)) { 873 builder.append(" PROPERTY_HAS_CDMA_VOICE_PRIVACY"); 874 } 875 if (hasProperty(properties, PROPERTY_ASSISTED_DIALING)) { 876 builder.append(" PROPERTY_ASSISTED_DIALING_USED"); 877 } 878 if (hasProperty(properties, PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL)) { 879 builder.append(" PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL"); 880 } 881 if (hasProperty(properties, PROPERTY_RTT)) { 882 builder.append(" PROPERTY_RTT"); 883 } 884 if (hasProperty(properties, PROPERTY_VOIP_AUDIO_MODE)) { 885 builder.append(" PROPERTY_VOIP_AUDIO_MODE"); 886 } 887 if (hasProperty(properties, PROPERTY_IS_ADHOC_CONFERENCE)) { 888 builder.append(" PROPERTY_IS_ADHOC_CONFERENCE"); 889 } 890 if (hasProperty(properties, PROPERTY_CROSS_SIM)) { 891 builder.append(" PROPERTY_CROSS_SIM"); 892 } 893 builder.append("]"); 894 return builder.toString(); 895 } 896 897 /** 898 * @return the state of the {@link Call} represented by this {@link Call.Details}. 899 */ getState()900 public final @CallState int getState() { 901 return mState; 902 } 903 904 /** {@hide} */ 905 @TestApi getTelecomCallId()906 public String getTelecomCallId() { 907 return mTelecomCallId; 908 } 909 910 /** 911 * @return The handle (e.g., phone number) to which the {@code Call} is currently 912 * connected. 913 */ getHandle()914 public Uri getHandle() { 915 return mHandle; 916 } 917 918 /** 919 * @return The presentation requirements for the handle. See 920 * {@link TelecomManager} for valid values. 921 */ getHandlePresentation()922 public int getHandlePresentation() { 923 return mHandlePresentation; 924 } 925 926 /** 927 * The display name for the caller. 928 * <p> 929 * This is the name as reported by the {@link ConnectionService} associated with this call. 930 * 931 * @return The display name for the caller. 932 */ getCallerDisplayName()933 public String getCallerDisplayName() { 934 return mCallerDisplayName; 935 } 936 937 /** 938 * @return The presentation requirements for the caller display name. See 939 * {@link TelecomManager} for valid values. 940 */ getCallerDisplayNamePresentation()941 public int getCallerDisplayNamePresentation() { 942 return mCallerDisplayNamePresentation; 943 } 944 945 /** 946 * @return The {@code PhoneAccountHandle} whereby the {@code Call} is currently being 947 * routed. 948 */ getAccountHandle()949 public PhoneAccountHandle getAccountHandle() { 950 return mAccountHandle; 951 } 952 953 /** 954 * @return A bitmask of the capabilities of the {@code Call}, as defined by the various 955 * {@code CAPABILITY_*} constants in this class. 956 */ getCallCapabilities()957 public int getCallCapabilities() { 958 return mCallCapabilities; 959 } 960 961 /** 962 * @return A bitmask of the properties of the {@code Call}, as defined by the various 963 * {@code PROPERTY_*} constants in this class. 964 */ getCallProperties()965 public int getCallProperties() { 966 return mCallProperties; 967 } 968 969 /** 970 * @return a bitmask of the audio routes available for the call. 971 * 972 * @hide 973 */ getSupportedAudioRoutes()974 public int getSupportedAudioRoutes() { 975 return mSupportedAudioRoutes; 976 } 977 978 /** 979 * @return For a {@link #STATE_DISCONNECTED} {@code Call}, the disconnect cause expressed 980 * by {@link android.telecom.DisconnectCause}. 981 */ getDisconnectCause()982 public DisconnectCause getDisconnectCause() { 983 return mDisconnectCause; 984 } 985 986 /** 987 * Returns the time the {@link Call} connected (i.e. became active). This information is 988 * updated periodically, but user interfaces should not rely on this to display the "call 989 * time clock". For the time when the call was first added to Telecom, see 990 * {@link #getCreationTimeMillis()}. 991 * 992 * @return The time the {@link Call} connected in milliseconds since the epoch. 993 */ getConnectTimeMillis()994 public final long getConnectTimeMillis() { 995 return mConnectTimeMillis; 996 } 997 998 /** 999 * @return Information about any calling gateway the {@code Call} may be using. 1000 */ getGatewayInfo()1001 public GatewayInfo getGatewayInfo() { 1002 return mGatewayInfo; 1003 } 1004 1005 /** 1006 * @return The video state of the {@code Call}. 1007 */ getVideoState()1008 public int getVideoState() { 1009 return mVideoState; 1010 } 1011 1012 /** 1013 * @return The current {@link android.telecom.StatusHints}, or {@code null} if none 1014 * have been set. 1015 */ getStatusHints()1016 public StatusHints getStatusHints() { 1017 return mStatusHints; 1018 } 1019 1020 /** 1021 * @return The extras associated with this call. 1022 */ getExtras()1023 public Bundle getExtras() { 1024 return mExtras; 1025 } 1026 1027 /** 1028 * @return The extras used with the original intent to place this call. 1029 */ getIntentExtras()1030 public Bundle getIntentExtras() { 1031 return mIntentExtras; 1032 } 1033 1034 /** 1035 * Returns the time when the call was first created and added to Telecom. This is the same 1036 * time that is logged as the start time in the Call Log (see 1037 * {@link android.provider.CallLog.Calls#DATE}). To determine when the call was connected 1038 * (became active), see {@link #getConnectTimeMillis()}. 1039 * 1040 * @return The creation time of the call, in millis since the epoch. 1041 */ getCreationTimeMillis()1042 public long getCreationTimeMillis() { 1043 return mCreationTimeMillis; 1044 } 1045 1046 /** 1047 * Returns the name of the caller on the remote end, as derived from a 1048 * {@link android.provider.ContactsContract} lookup of the call's handle. 1049 * @return The name of the caller, or {@code null} if the lookup is not yet complete, if 1050 * there's no contacts entry for the caller, or if the {@link InCallService} does 1051 * not hold the {@link android.Manifest.permission#READ_CONTACTS} permission. 1052 */ getContactDisplayName()1053 public @Nullable String getContactDisplayName() { 1054 return mContactDisplayName; 1055 } 1056 1057 /** 1058 * Indicates whether the call is an incoming or outgoing call. 1059 * @return The call's direction. 1060 */ getCallDirection()1061 public @CallDirection int getCallDirection() { 1062 return mCallDirection; 1063 } 1064 1065 /** 1066 * Gets the verification status for the phone number of an incoming call as identified in 1067 * ATIS-1000082. 1068 * <p> 1069 * For incoming calls, the number verification status indicates whether the device was 1070 * able to verify the authenticity of the calling number using the STIR process outlined 1071 * in ATIS-1000082. {@link Connection#VERIFICATION_STATUS_NOT_VERIFIED} indicates that 1072 * the network was not able to use STIR to verify the caller's number (i.e. nothing is 1073 * known regarding the authenticity of the number. 1074 * {@link Connection#VERIFICATION_STATUS_PASSED} indicates that the network was able to 1075 * use STIR to verify the caller's number. This indicates that the network has a high 1076 * degree of confidence that the incoming call actually originated from the indicated 1077 * number. {@link Connection#VERIFICATION_STATUS_FAILED} indicates that the network's 1078 * STIR verification did not pass. This indicates that the incoming call may not 1079 * actually be from the indicated number. This could occur if, for example, the caller 1080 * is using an impersonated phone number. 1081 * <p> 1082 * A {@link CallScreeningService} can use this information to help determine if an 1083 * incoming call is potentially an unwanted call. A verification status of 1084 * {@link Connection#VERIFICATION_STATUS_FAILED} indicates that an incoming call may not 1085 * actually be from the number indicated on the call (i.e. impersonated number) and that it 1086 * should potentially be blocked. Likewise, 1087 * {@link Connection#VERIFICATION_STATUS_PASSED} can be used as a positive signal to 1088 * help clarify that the incoming call is originating from the indicated number and it 1089 * is less likely to be an undesirable call. 1090 * <p> 1091 * An {@link InCallService} can use this information to provide a visual indicator to the 1092 * user regarding the verification status of a call and to help identify calls from 1093 * potentially impersonated numbers. 1094 * @return the verification status. 1095 */ getCallerNumberVerificationStatus()1096 public @Connection.VerificationStatus int getCallerNumberVerificationStatus() { 1097 return mCallerNumberVerificationStatus; 1098 } 1099 1100 @Override equals(Object o)1101 public boolean equals(Object o) { 1102 if (o instanceof Details) { 1103 Details d = (Details) o; 1104 return 1105 Objects.equals(mState, d.mState) && 1106 Objects.equals(mHandle, d.mHandle) && 1107 Objects.equals(mHandlePresentation, d.mHandlePresentation) && 1108 Objects.equals(mCallerDisplayName, d.mCallerDisplayName) && 1109 Objects.equals(mCallerDisplayNamePresentation, 1110 d.mCallerDisplayNamePresentation) && 1111 Objects.equals(mAccountHandle, d.mAccountHandle) && 1112 Objects.equals(mCallCapabilities, d.mCallCapabilities) && 1113 Objects.equals(mCallProperties, d.mCallProperties) && 1114 Objects.equals(mDisconnectCause, d.mDisconnectCause) && 1115 Objects.equals(mConnectTimeMillis, d.mConnectTimeMillis) && 1116 Objects.equals(mGatewayInfo, d.mGatewayInfo) && 1117 Objects.equals(mVideoState, d.mVideoState) && 1118 Objects.equals(mStatusHints, d.mStatusHints) && 1119 areBundlesEqual(mExtras, d.mExtras) && 1120 areBundlesEqual(mIntentExtras, d.mIntentExtras) && 1121 Objects.equals(mCreationTimeMillis, d.mCreationTimeMillis) && 1122 Objects.equals(mContactDisplayName, d.mContactDisplayName) && 1123 Objects.equals(mCallDirection, d.mCallDirection) && 1124 Objects.equals(mCallerNumberVerificationStatus, 1125 d.mCallerNumberVerificationStatus); 1126 } 1127 return false; 1128 } 1129 1130 @Override hashCode()1131 public int hashCode() { 1132 return Objects.hash(mState, 1133 mHandle, 1134 mHandlePresentation, 1135 mCallerDisplayName, 1136 mCallerDisplayNamePresentation, 1137 mAccountHandle, 1138 mCallCapabilities, 1139 mCallProperties, 1140 mDisconnectCause, 1141 mConnectTimeMillis, 1142 mGatewayInfo, 1143 mVideoState, 1144 mStatusHints, 1145 mExtras, 1146 mIntentExtras, 1147 mCreationTimeMillis, 1148 mContactDisplayName, 1149 mCallDirection, 1150 mCallerNumberVerificationStatus); 1151 } 1152 1153 /** {@hide} */ Details( @allState int state, String telecomCallId, Uri handle, int handlePresentation, String callerDisplayName, int callerDisplayNamePresentation, PhoneAccountHandle accountHandle, int capabilities, int properties, DisconnectCause disconnectCause, long connectTimeMillis, GatewayInfo gatewayInfo, int videoState, StatusHints statusHints, Bundle extras, Bundle intentExtras, long creationTimeMillis, String contactDisplayName, int callDirection, int callerNumberVerificationStatus)1154 public Details( 1155 @CallState int state, 1156 String telecomCallId, 1157 Uri handle, 1158 int handlePresentation, 1159 String callerDisplayName, 1160 int callerDisplayNamePresentation, 1161 PhoneAccountHandle accountHandle, 1162 int capabilities, 1163 int properties, 1164 DisconnectCause disconnectCause, 1165 long connectTimeMillis, 1166 GatewayInfo gatewayInfo, 1167 int videoState, 1168 StatusHints statusHints, 1169 Bundle extras, 1170 Bundle intentExtras, 1171 long creationTimeMillis, 1172 String contactDisplayName, 1173 int callDirection, 1174 int callerNumberVerificationStatus) { 1175 mState = state; 1176 mTelecomCallId = telecomCallId; 1177 mHandle = handle; 1178 mHandlePresentation = handlePresentation; 1179 mCallerDisplayName = callerDisplayName; 1180 mCallerDisplayNamePresentation = callerDisplayNamePresentation; 1181 mAccountHandle = accountHandle; 1182 mCallCapabilities = capabilities; 1183 mCallProperties = properties; 1184 mDisconnectCause = disconnectCause; 1185 mConnectTimeMillis = connectTimeMillis; 1186 mGatewayInfo = gatewayInfo; 1187 mVideoState = videoState; 1188 mStatusHints = statusHints; 1189 mExtras = extras; 1190 mIntentExtras = intentExtras; 1191 mCreationTimeMillis = creationTimeMillis; 1192 mContactDisplayName = contactDisplayName; 1193 mCallDirection = callDirection; 1194 mCallerNumberVerificationStatus = callerNumberVerificationStatus; 1195 } 1196 1197 /** {@hide} */ createFromParcelableCall(ParcelableCall parcelableCall)1198 public static Details createFromParcelableCall(ParcelableCall parcelableCall) { 1199 return new Details( 1200 parcelableCall.getState(), 1201 parcelableCall.getId(), 1202 parcelableCall.getHandle(), 1203 parcelableCall.getHandlePresentation(), 1204 parcelableCall.getCallerDisplayName(), 1205 parcelableCall.getCallerDisplayNamePresentation(), 1206 parcelableCall.getAccountHandle(), 1207 parcelableCall.getCapabilities(), 1208 parcelableCall.getProperties(), 1209 parcelableCall.getDisconnectCause(), 1210 parcelableCall.getConnectTimeMillis(), 1211 parcelableCall.getGatewayInfo(), 1212 parcelableCall.getVideoState(), 1213 parcelableCall.getStatusHints(), 1214 parcelableCall.getExtras(), 1215 parcelableCall.getIntentExtras(), 1216 parcelableCall.getCreationTimeMillis(), 1217 parcelableCall.getContactDisplayName(), 1218 parcelableCall.getCallDirection(), 1219 parcelableCall.getCallerNumberVerificationStatus()); 1220 } 1221 1222 @Override toString()1223 public String toString() { 1224 StringBuilder sb = new StringBuilder(); 1225 sb.append("[id: "); 1226 sb.append(mTelecomCallId); 1227 sb.append(", state: "); 1228 sb.append(Call.stateToString(mState)); 1229 sb.append(", pa: "); 1230 sb.append(mAccountHandle); 1231 sb.append(", hdl: "); 1232 sb.append(Log.piiHandle(mHandle)); 1233 sb.append(", hdlPres: "); 1234 sb.append(mHandlePresentation); 1235 sb.append(", videoState: "); 1236 sb.append(VideoProfile.videoStateToString(mVideoState)); 1237 sb.append(", caps: "); 1238 sb.append(capabilitiesToString(mCallCapabilities)); 1239 sb.append(", props: "); 1240 sb.append(propertiesToString(mCallProperties)); 1241 sb.append("]"); 1242 return sb.toString(); 1243 } 1244 } 1245 1246 /** 1247 * Defines callbacks which inform the {@link InCallService} of changes to a {@link Call}. 1248 * These callbacks can originate from the Telecom framework, or a {@link ConnectionService} 1249 * implementation. 1250 * <p> 1251 * You can handle these callbacks by extending the {@link Callback} class and overriding the 1252 * callbacks that your {@link InCallService} is interested in. The callback methods include the 1253 * {@link Call} for which the callback applies, allowing reuse of a single instance of your 1254 * {@link Callback} implementation, if desired. 1255 * <p> 1256 * Use {@link Call#registerCallback(Callback)} to register your callback(s). Ensure 1257 * {@link Call#unregisterCallback(Callback)} is called when you no longer require callbacks 1258 * (typically in {@link InCallService#onCallRemoved(Call)}). 1259 * Note: Callbacks which occur before you call {@link Call#registerCallback(Callback)} will not 1260 * reach your implementation of {@link Callback}, so it is important to register your callback 1261 * as soon as your {@link InCallService} is notified of a new call via 1262 * {@link InCallService#onCallAdded(Call)}. 1263 */ 1264 public static abstract class Callback { 1265 /** 1266 * @hide 1267 */ 1268 @IntDef(prefix = { "HANDOVER_" }, 1269 value = {HANDOVER_FAILURE_DEST_APP_REJECTED, HANDOVER_FAILURE_NOT_SUPPORTED, 1270 HANDOVER_FAILURE_USER_REJECTED, HANDOVER_FAILURE_ONGOING_EMERGENCY_CALL, 1271 HANDOVER_FAILURE_UNKNOWN}) 1272 @Retention(RetentionPolicy.SOURCE) 1273 public @interface HandoverFailureErrors {} 1274 1275 /** 1276 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when the app 1277 * to handover the call to rejects the handover request. 1278 * <p> 1279 * Will be returned when {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} is called 1280 * and the destination {@link PhoneAccountHandle}'s {@link ConnectionService} returns a 1281 * {@code null} {@link Connection} from 1282 * {@link ConnectionService#onCreateOutgoingHandoverConnection(PhoneAccountHandle, 1283 * ConnectionRequest)}. 1284 * <p> 1285 * For more information on call handovers, see 1286 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}. 1287 */ 1288 public static final int HANDOVER_FAILURE_DEST_APP_REJECTED = 1; 1289 1290 /** 1291 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when a handover 1292 * is initiated but the source or destination app does not support handover. 1293 * <p> 1294 * Will be returned when a handover is requested via 1295 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)} and the destination 1296 * {@link PhoneAccountHandle} does not declare 1297 * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_TO}. May also be returned when a handover is 1298 * requested at the {@link PhoneAccountHandle} for the current call (i.e. the source call's 1299 * {@link Details#getAccountHandle()}) does not declare 1300 * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}. 1301 * <p> 1302 * For more information on call handovers, see 1303 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}. 1304 */ 1305 public static final int HANDOVER_FAILURE_NOT_SUPPORTED = 2; 1306 1307 /** 1308 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when the remote 1309 * user rejects the handover request. 1310 * <p> 1311 * For more information on call handovers, see 1312 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}. 1313 */ 1314 public static final int HANDOVER_FAILURE_USER_REJECTED = 3; 1315 1316 /** 1317 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when there 1318 * is ongoing emergency call. 1319 * <p> 1320 * This error code is returned when {@link #handoverTo(PhoneAccountHandle, int, Bundle)} is 1321 * called on an emergency call, or if any other call is an emergency call. 1322 * <p> 1323 * Handovers are not permitted while there are ongoing emergency calls. 1324 * <p> 1325 * For more information on call handovers, see 1326 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}. 1327 */ 1328 public static final int HANDOVER_FAILURE_ONGOING_EMERGENCY_CALL = 4; 1329 1330 /** 1331 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when a handover 1332 * fails for an unknown reason. 1333 * <p> 1334 * For more information on call handovers, see 1335 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}. 1336 */ 1337 public static final int HANDOVER_FAILURE_UNKNOWN = 5; 1338 1339 /** 1340 * Invoked when the state of this {@code Call} has changed. See {@link #getState()}. 1341 * 1342 * @param call The {@code Call} invoking this method. 1343 * @param state The new state of the {@code Call}. 1344 */ onStateChanged(Call call, @CallState int state)1345 public void onStateChanged(Call call, @CallState int state) {} 1346 1347 /** 1348 * Invoked when the parent of this {@code Call} has changed. See {@link #getParent()}. 1349 * 1350 * @param call The {@code Call} invoking this method. 1351 * @param parent The new parent of the {@code Call}. 1352 */ onParentChanged(Call call, Call parent)1353 public void onParentChanged(Call call, Call parent) {} 1354 1355 /** 1356 * Invoked when the children of this {@code Call} have changed. See {@link #getChildren()}. 1357 * 1358 * @param call The {@code Call} invoking this method. 1359 * @param children The new children of the {@code Call}. 1360 */ onChildrenChanged(Call call, List<Call> children)1361 public void onChildrenChanged(Call call, List<Call> children) {} 1362 1363 /** 1364 * Invoked when the details of this {@code Call} have changed. See {@link #getDetails()}. 1365 * 1366 * @param call The {@code Call} invoking this method. 1367 * @param details A {@code Details} object describing the {@code Call}. 1368 */ onDetailsChanged(Call call, Details details)1369 public void onDetailsChanged(Call call, Details details) {} 1370 1371 /** 1372 * Invoked when the text messages that can be used as responses to the incoming 1373 * {@code Call} are loaded from the relevant database. 1374 * See {@link #getCannedTextResponses()}. 1375 * 1376 * @param call The {@code Call} invoking this method. 1377 * @param cannedTextResponses The text messages useable as responses. 1378 */ onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses)1379 public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {} 1380 1381 /** 1382 * Invoked when the post-dial sequence in the outgoing {@code Call} has reached a pause 1383 * character. This causes the post-dial signals to stop pending user confirmation. An 1384 * implementation should present this choice to the user and invoke 1385 * {@link #postDialContinue(boolean)} when the user makes the choice. 1386 * 1387 * @param call The {@code Call} invoking this method. 1388 * @param remainingPostDialSequence The post-dial characters that remain to be sent. 1389 */ onPostDialWait(Call call, String remainingPostDialSequence)1390 public void onPostDialWait(Call call, String remainingPostDialSequence) {} 1391 1392 /** 1393 * Invoked when the {@code Call.VideoCall} of the {@code Call} has changed. 1394 * 1395 * @param call The {@code Call} invoking this method. 1396 * @param videoCall The {@code Call.VideoCall} associated with the {@code Call}. 1397 */ onVideoCallChanged(Call call, InCallService.VideoCall videoCall)1398 public void onVideoCallChanged(Call call, InCallService.VideoCall videoCall) {} 1399 1400 /** 1401 * Invoked when the {@code Call} is destroyed. Clients should refrain from cleaning 1402 * up their UI for the {@code Call} in response to state transitions. Specifically, 1403 * clients should not assume that a {@link #onStateChanged(Call, int)} with a state of 1404 * {@link #STATE_DISCONNECTED} is the final notification the {@code Call} will send. Rather, 1405 * clients should wait for this method to be invoked. 1406 * 1407 * @param call The {@code Call} being destroyed. 1408 */ onCallDestroyed(Call call)1409 public void onCallDestroyed(Call call) {} 1410 1411 /** 1412 * Invoked upon changes to the set of {@code Call}s with which this {@code Call} can be 1413 * conferenced. 1414 * 1415 * @param call The {@code Call} being updated. 1416 * @param conferenceableCalls The {@code Call}s with which this {@code Call} can be 1417 * conferenced. 1418 */ onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls)1419 public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {} 1420 1421 /** 1422 * Invoked when a {@link Call} receives an event from its associated {@link Connection} or 1423 * {@link Conference}. 1424 * <p> 1425 * Where possible, the Call should make an attempt to handle {@link Connection} events which 1426 * are part of the {@code android.telecom.*} namespace. The Call should ignore any events 1427 * it does not wish to handle. Unexpected events should be handled gracefully, as it is 1428 * possible that a {@link ConnectionService} has defined its own Connection events which a 1429 * Call is not aware of. 1430 * <p> 1431 * See {@link Connection#sendConnectionEvent(String, Bundle)}, 1432 * {@link Conference#sendConferenceEvent(String, Bundle)}. 1433 * 1434 * @param call The {@code Call} receiving the event. 1435 * @param event The event. 1436 * @param extras Extras associated with the connection event. 1437 */ onConnectionEvent(Call call, String event, Bundle extras)1438 public void onConnectionEvent(Call call, String event, Bundle extras) {} 1439 1440 /** 1441 * Invoked when the RTT mode changes for this call. 1442 * @param call The call whose RTT mode has changed. 1443 * @param mode the new RTT mode, one of 1444 * {@link RttCall#RTT_MODE_FULL}, {@link RttCall#RTT_MODE_HCO}, 1445 * or {@link RttCall#RTT_MODE_VCO} 1446 */ onRttModeChanged(Call call, int mode)1447 public void onRttModeChanged(Call call, int mode) {} 1448 1449 /** 1450 * Invoked when the call's RTT status changes, either from off to on or from on to off. 1451 * @param call The call whose RTT status has changed. 1452 * @param enabled whether RTT is now enabled or disabled 1453 * @param rttCall the {@link RttCall} object to use for reading and writing if RTT is now 1454 * on, null otherwise. 1455 */ onRttStatusChanged(Call call, boolean enabled, RttCall rttCall)1456 public void onRttStatusChanged(Call call, boolean enabled, RttCall rttCall) {} 1457 1458 /** 1459 * Invoked when the remote end of the connection has requested that an RTT communication 1460 * channel be opened. A response to this should be sent via {@link #respondToRttRequest} 1461 * with the same ID that this method is invoked with. 1462 * @param call The call which the RTT request was placed on 1463 * @param id The ID of the request. 1464 */ onRttRequest(Call call, int id)1465 public void onRttRequest(Call call, int id) {} 1466 1467 /** 1468 * Invoked when the RTT session failed to initiate for some reason, including rejection 1469 * by the remote party. 1470 * @param call The call which the RTT initiation failure occurred on. 1471 * @param reason One of the status codes defined in 1472 * {@link android.telecom.Connection.RttModifyStatus}, with the exception of 1473 * {@link android.telecom.Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}. 1474 */ onRttInitiationFailure(Call call, int reason)1475 public void onRttInitiationFailure(Call call, int reason) {} 1476 1477 /** 1478 * Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount} 1479 * has completed successfully. 1480 * <p> 1481 * For a full discussion of the handover process and the APIs involved, see 1482 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}. 1483 * 1484 * @param call The call which had initiated handover. 1485 */ onHandoverComplete(Call call)1486 public void onHandoverComplete(Call call) {} 1487 1488 /** 1489 * Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount} 1490 * has failed. 1491 * <p> 1492 * For a full discussion of the handover process and the APIs involved, see 1493 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}. 1494 * 1495 * @param call The call which had initiated handover. 1496 * @param failureReason Error reason for failure. 1497 */ onHandoverFailed(Call call, @HandoverFailureErrors int failureReason)1498 public void onHandoverFailed(Call call, @HandoverFailureErrors int failureReason) {} 1499 } 1500 1501 /** 1502 * A class that holds the state that describes the state of the RTT channel to the remote 1503 * party, if it is active. 1504 */ 1505 public static final class RttCall { 1506 /** @hide */ 1507 @Retention(RetentionPolicy.SOURCE) 1508 @IntDef({RTT_MODE_INVALID, RTT_MODE_FULL, RTT_MODE_HCO, RTT_MODE_VCO}) 1509 public @interface RttAudioMode {} 1510 1511 /** 1512 * For metrics use. Default value in the proto. 1513 * @hide 1514 */ 1515 public static final int RTT_MODE_INVALID = 0; 1516 1517 /** 1518 * Indicates that there should be a bidirectional audio stream between the two parties 1519 * on the call. 1520 */ 1521 public static final int RTT_MODE_FULL = 1; 1522 1523 /** 1524 * Indicates that the local user should be able to hear the audio stream from the remote 1525 * user, but not vice versa. Equivalent to muting the microphone. 1526 */ 1527 public static final int RTT_MODE_HCO = 2; 1528 1529 /** 1530 * Indicates that the remote user should be able to hear the audio stream from the local 1531 * user, but not vice versa. Equivalent to setting the volume to zero. 1532 */ 1533 public static final int RTT_MODE_VCO = 3; 1534 1535 private static final int READ_BUFFER_SIZE = 1000; 1536 1537 private InputStreamReader mReceiveStream; 1538 private OutputStreamWriter mTransmitStream; 1539 private int mRttMode; 1540 private final InCallAdapter mInCallAdapter; 1541 private final String mTelecomCallId; 1542 private char[] mReadBuffer = new char[READ_BUFFER_SIZE]; 1543 1544 /** 1545 * @hide 1546 */ RttCall(String telecomCallId, InputStreamReader receiveStream, OutputStreamWriter transmitStream, int mode, InCallAdapter inCallAdapter)1547 public RttCall(String telecomCallId, InputStreamReader receiveStream, 1548 OutputStreamWriter transmitStream, int mode, InCallAdapter inCallAdapter) { 1549 mTelecomCallId = telecomCallId; 1550 mReceiveStream = receiveStream; 1551 mTransmitStream = transmitStream; 1552 mRttMode = mode; 1553 mInCallAdapter = inCallAdapter; 1554 } 1555 1556 /** 1557 * Returns the current RTT audio mode. 1558 * @return Current RTT audio mode. One of {@link #RTT_MODE_FULL}, {@link #RTT_MODE_VCO}, or 1559 * {@link #RTT_MODE_HCO}. 1560 */ getRttAudioMode()1561 public int getRttAudioMode() { 1562 return mRttMode; 1563 } 1564 1565 /** 1566 * Sets the RTT audio mode. The requested mode change will be communicated through 1567 * {@link Callback#onRttModeChanged(Call, int)}. 1568 * @param mode The desired RTT audio mode, one of {@link #RTT_MODE_FULL}, 1569 * {@link #RTT_MODE_VCO}, or {@link #RTT_MODE_HCO}. 1570 */ setRttMode(@ttAudioMode int mode)1571 public void setRttMode(@RttAudioMode int mode) { 1572 mInCallAdapter.setRttMode(mTelecomCallId, mode); 1573 } 1574 1575 /** 1576 * Writes the string {@param input} into the outgoing text stream for this RTT call. Since 1577 * RTT transmits text in real-time, this method should be called once for each user action. 1578 * For example, when the user enters text as discrete characters using the keyboard, this 1579 * method should be called once for each character. However, if the user enters text by 1580 * pasting or autocomplete, the entire contents of the pasted or autocompleted text should 1581 * be sent in one call to this method. 1582 * 1583 * This method is not thread-safe -- calling it from multiple threads simultaneously may 1584 * lead to interleaved text. 1585 * @param input The message to send to the remote user. 1586 */ write(String input)1587 public void write(String input) throws IOException { 1588 mTransmitStream.write(input); 1589 mTransmitStream.flush(); 1590 } 1591 1592 /** 1593 * Reads a string from the remote user, blocking if there is no data available. Returns 1594 * {@code null} if the RTT conversation has been terminated and there is no further data 1595 * to read. 1596 * 1597 * This method is not thread-safe -- calling it from multiple threads simultaneously may 1598 * lead to interleaved text. 1599 * @return A string containing text sent by the remote user, or {@code null} if the 1600 * conversation has been terminated or if there was an error while reading. 1601 */ read()1602 public String read() { 1603 try { 1604 int numRead = mReceiveStream.read(mReadBuffer, 0, READ_BUFFER_SIZE); 1605 if (numRead < 0) { 1606 return null; 1607 } 1608 return new String(mReadBuffer, 0, numRead); 1609 } catch (IOException e) { 1610 Log.w(this, "Exception encountered when reading from InputStreamReader: %s", e); 1611 return null; 1612 } 1613 } 1614 1615 /** 1616 * Non-blocking version of {@link #read()}. Returns {@code null} if there is nothing to 1617 * be read. 1618 * @return A string containing text entered by the user, or {@code null} if the user has 1619 * not entered any new text yet. 1620 */ readImmediately()1621 public String readImmediately() throws IOException { 1622 if (mReceiveStream.ready()) { 1623 int numRead = mReceiveStream.read(mReadBuffer, 0, READ_BUFFER_SIZE); 1624 if (numRead < 0) { 1625 return null; 1626 } 1627 return new String(mReadBuffer, 0, numRead); 1628 } else { 1629 return null; 1630 } 1631 } 1632 1633 /** 1634 * Closes the underlying file descriptors 1635 * @hide 1636 */ close()1637 public void close() { 1638 try { 1639 mReceiveStream.close(); 1640 } catch (IOException e) { 1641 // ignore 1642 } 1643 try { 1644 mTransmitStream.close(); 1645 } catch (IOException e) { 1646 // ignore 1647 } 1648 } 1649 } 1650 1651 /** 1652 * @deprecated Use {@code Call.Callback} instead. 1653 * @hide 1654 */ 1655 @Deprecated 1656 @SystemApi 1657 public static abstract class Listener extends Callback { } 1658 1659 private final Phone mPhone; 1660 private final String mTelecomCallId; 1661 private final InCallAdapter mInCallAdapter; 1662 private final List<String> mChildrenIds = new ArrayList<>(); 1663 private final List<Call> mChildren = new ArrayList<>(); 1664 private final List<Call> mUnmodifiableChildren = Collections.unmodifiableList(mChildren); 1665 private final List<CallbackRecord<Callback>> mCallbackRecords = new CopyOnWriteArrayList<>(); 1666 private final List<Call> mConferenceableCalls = new ArrayList<>(); 1667 private final List<Call> mUnmodifiableConferenceableCalls = 1668 Collections.unmodifiableList(mConferenceableCalls); 1669 1670 private boolean mChildrenCached; 1671 private String mParentId = null; 1672 private String mActiveGenericConferenceChild = null; 1673 private int mState; 1674 private List<String> mCannedTextResponses = null; 1675 private String mCallingPackage; 1676 private int mTargetSdkVersion; 1677 private String mRemainingPostDialSequence; 1678 private VideoCallImpl mVideoCallImpl; 1679 private RttCall mRttCall; 1680 private Details mDetails; 1681 private Bundle mExtras; 1682 1683 /** 1684 * Obtains the post-dial sequence remaining to be emitted by this {@code Call}, if any. 1685 * 1686 * @return The remaining post-dial sequence, or {@code null} if there is no post-dial sequence 1687 * remaining or this {@code Call} is not in a post-dial state. 1688 */ getRemainingPostDialSequence()1689 public String getRemainingPostDialSequence() { 1690 return mRemainingPostDialSequence; 1691 } 1692 1693 /** 1694 * Instructs this {@link #STATE_RINGING} {@code Call} to answer. 1695 * @param videoState The video state in which to answer the call. 1696 */ answer(@ideoProfile.VideoState int videoState)1697 public void answer(@VideoProfile.VideoState int videoState) { 1698 mInCallAdapter.answerCall(mTelecomCallId, videoState); 1699 } 1700 1701 /** 1702 * Instructs this {@link #STATE_RINGING} {@code Call} to deflect. 1703 * 1704 * @param address The address to which the call will be deflected. 1705 */ deflect(Uri address)1706 public void deflect(Uri address) { 1707 mInCallAdapter.deflectCall(mTelecomCallId, address); 1708 } 1709 1710 /** 1711 * Instructs this {@link #STATE_RINGING} {@code Call} to reject. 1712 * 1713 * @param rejectWithMessage Whether to reject with a text message. 1714 * @param textMessage An optional text message with which to respond. 1715 */ reject(boolean rejectWithMessage, String textMessage)1716 public void reject(boolean rejectWithMessage, String textMessage) { 1717 mInCallAdapter.rejectCall(mTelecomCallId, rejectWithMessage, textMessage); 1718 } 1719 1720 /** 1721 * Instructs the {@link ConnectionService} providing this {@link #STATE_RINGING} call that the 1722 * user has chosen to reject the call and has indicated a reason why the call is being rejected. 1723 * 1724 * @param rejectReason the reason the call is being rejected. 1725 */ reject(@ejectReason int rejectReason)1726 public void reject(@RejectReason int rejectReason) { 1727 mInCallAdapter.rejectCall(mTelecomCallId, rejectReason); 1728 } 1729 1730 /** 1731 * Instructs this {@code Call} to be transferred to another number. 1732 * 1733 * @param targetNumber The address to which the call will be transferred. 1734 * @param isConfirmationRequired if {@code true} it will initiate a confirmed transfer, 1735 * if {@code false}, it will initiate an unconfirmed transfer. 1736 * 1737 * @hide 1738 */ transfer(@onNull Uri targetNumber, boolean isConfirmationRequired)1739 public void transfer(@NonNull Uri targetNumber, boolean isConfirmationRequired) { 1740 mInCallAdapter.transferCall(mTelecomCallId, targetNumber, isConfirmationRequired); 1741 } 1742 1743 /** 1744 * Instructs this {@code Call} to be transferred to another ongoing call. 1745 * This will initiate CONSULTATIVE transfer. 1746 * @param toCall The other ongoing {@code Call} to which this call will be transferred. 1747 * 1748 * @hide 1749 */ transfer(@onNull android.telecom.Call toCall)1750 public void transfer(@NonNull android.telecom.Call toCall) { 1751 mInCallAdapter.transferCall(mTelecomCallId, toCall.mTelecomCallId); 1752 } 1753 1754 /** 1755 * Instructs this {@code Call} to disconnect. 1756 */ disconnect()1757 public void disconnect() { 1758 mInCallAdapter.disconnectCall(mTelecomCallId); 1759 } 1760 1761 /** 1762 * Instructs this {@code Call} to go on hold. 1763 */ hold()1764 public void hold() { 1765 mInCallAdapter.holdCall(mTelecomCallId); 1766 } 1767 1768 /** 1769 * Instructs this {@link #STATE_HOLDING} call to release from hold. 1770 */ unhold()1771 public void unhold() { 1772 mInCallAdapter.unholdCall(mTelecomCallId); 1773 } 1774 1775 /** 1776 * Instructs Telecom to put the call into the background audio processing state. 1777 * <p> 1778 * This method can be called either when the call is in {@link #STATE_RINGING} or 1779 * {@link #STATE_ACTIVE}. After Telecom acknowledges the request by setting the call's state to 1780 * {@link #STATE_AUDIO_PROCESSING}, your app may setup the audio paths with the audio stack in 1781 * order to capture and play audio on the call stream. 1782 * <p> 1783 * This method can only be called by the default dialer app. 1784 * <p> 1785 * Apps built with SDK version {@link android.os.Build.VERSION_CODES#R} or later which are using 1786 * the microphone as part of audio processing should specify the foreground service type using 1787 * the attribute {@link android.R.attr#foregroundServiceType} in the {@link InCallService} 1788 * service element of the app's manifest file. 1789 * The {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MICROPHONE} attribute should be specified. 1790 * @see <a href="https://developer.android.com/preview/privacy/foreground-service-types"> 1791 * the Android Developer Site</a> for more information. 1792 * @hide 1793 */ 1794 @SystemApi enterBackgroundAudioProcessing()1795 public void enterBackgroundAudioProcessing() { 1796 if (mState != STATE_ACTIVE && mState != STATE_RINGING) { 1797 throw new IllegalStateException("Call must be active or ringing"); 1798 } 1799 mInCallAdapter.enterBackgroundAudioProcessing(mTelecomCallId); 1800 } 1801 1802 /** 1803 * Instructs Telecom to come out of the background audio processing state requested by 1804 * {@link #enterBackgroundAudioProcessing()} or from the call screening service. 1805 * 1806 * This method can only be called when the call is in {@link #STATE_AUDIO_PROCESSING}. 1807 * 1808 * @param shouldRing If true, Telecom will put the call into the 1809 * {@link #STATE_SIMULATED_RINGING} state and notify other apps that there is 1810 * a ringing call. Otherwise, the call will go into {@link #STATE_ACTIVE} 1811 * immediately. 1812 * @hide 1813 */ 1814 @SystemApi exitBackgroundAudioProcessing(boolean shouldRing)1815 public void exitBackgroundAudioProcessing(boolean shouldRing) { 1816 if (mState != STATE_AUDIO_PROCESSING) { 1817 throw new IllegalStateException("Call must in the audio processing state"); 1818 } 1819 mInCallAdapter.exitBackgroundAudioProcessing(mTelecomCallId, shouldRing); 1820 } 1821 1822 /** 1823 * Instructs this {@code Call} to play a dual-tone multi-frequency signaling (DTMF) tone. 1824 * 1825 * Any other currently playing DTMF tone in the specified call is immediately stopped. 1826 * 1827 * @param digit A character representing the DTMF digit for which to play the tone. This 1828 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}. 1829 */ playDtmfTone(char digit)1830 public void playDtmfTone(char digit) { 1831 mInCallAdapter.playDtmfTone(mTelecomCallId, digit); 1832 } 1833 1834 /** 1835 * Instructs this {@code Call} to stop any dual-tone multi-frequency signaling (DTMF) tone 1836 * currently playing. 1837 * 1838 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is 1839 * currently playing, this method will do nothing. 1840 */ stopDtmfTone()1841 public void stopDtmfTone() { 1842 mInCallAdapter.stopDtmfTone(mTelecomCallId); 1843 } 1844 1845 /** 1846 * Instructs this {@code Call} to continue playing a post-dial DTMF string. 1847 * 1848 * A post-dial DTMF string is a string of digits entered after a phone number, when dialed, 1849 * that are immediately sent as DTMF tones to the recipient as soon as the connection is made. 1850 * 1851 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this 1852 * {@code Call} will temporarily pause playing the tones for a pre-defined period of time. 1853 * 1854 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this 1855 * {@code Call} will pause playing the tones and notify callbacks via 1856 * {@link Callback#onPostDialWait(Call, String)}. At this point, the in-call app 1857 * should display to the user an indication of this state and an affordance to continue 1858 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call 1859 * app should invoke the {@link #postDialContinue(boolean)} method. 1860 * 1861 * @param proceed Whether or not to continue with the post-dial sequence. 1862 */ postDialContinue(boolean proceed)1863 public void postDialContinue(boolean proceed) { 1864 mInCallAdapter.postDialContinue(mTelecomCallId, proceed); 1865 } 1866 1867 /** 1868 * Notifies this {@code Call} that an account has been selected and to proceed with placing 1869 * an outgoing call. Optionally sets this account as the default account. 1870 */ phoneAccountSelected(PhoneAccountHandle accountHandle, boolean setDefault)1871 public void phoneAccountSelected(PhoneAccountHandle accountHandle, boolean setDefault) { 1872 mInCallAdapter.phoneAccountSelected(mTelecomCallId, accountHandle, setDefault); 1873 1874 } 1875 1876 /** 1877 * Instructs this {@code Call} to enter a conference. 1878 * 1879 * @param callToConferenceWith The other call with which to conference. 1880 */ conference(Call callToConferenceWith)1881 public void conference(Call callToConferenceWith) { 1882 if (callToConferenceWith != null) { 1883 mInCallAdapter.conference(mTelecomCallId, callToConferenceWith.mTelecomCallId); 1884 } 1885 } 1886 1887 /** 1888 * Instructs this {@code Call} to split from any conference call with which it may be 1889 * connected. 1890 */ splitFromConference()1891 public void splitFromConference() { 1892 mInCallAdapter.splitFromConference(mTelecomCallId); 1893 } 1894 1895 /** 1896 * Merges the calls within this conference. See {@link Details#CAPABILITY_MERGE_CONFERENCE}. 1897 */ mergeConference()1898 public void mergeConference() { 1899 mInCallAdapter.mergeConference(mTelecomCallId); 1900 } 1901 1902 /** 1903 * Swaps the calls within this conference. See {@link Details#CAPABILITY_SWAP_CONFERENCE}. 1904 */ swapConference()1905 public void swapConference() { 1906 mInCallAdapter.swapConference(mTelecomCallId); 1907 } 1908 1909 /** 1910 * Pulls participants to existing call by forming a conference call. 1911 * See {@link Details#CAPABILITY_ADD_PARTICIPANT}. 1912 * 1913 * @param participants participants to be pulled to existing call. 1914 */ addConferenceParticipants(@onNull List<Uri> participants)1915 public void addConferenceParticipants(@NonNull List<Uri> participants) { 1916 mInCallAdapter.addConferenceParticipants(mTelecomCallId, participants); 1917 } 1918 1919 /** 1920 * Initiates a request to the {@link ConnectionService} to pull an external call to the local 1921 * device. 1922 * <p> 1923 * Calls to this method are ignored if the call does not have the 1924 * {@link Call.Details#PROPERTY_IS_EXTERNAL_CALL} property set. 1925 * <p> 1926 * An {@link InCallService} will only see calls which support this method if it has the 1927 * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true} 1928 * in its manifest. 1929 */ pullExternalCall()1930 public void pullExternalCall() { 1931 // If this isn't an external call, ignore the request. 1932 if (!mDetails.hasProperty(Details.PROPERTY_IS_EXTERNAL_CALL)) { 1933 return; 1934 } 1935 1936 mInCallAdapter.pullExternalCall(mTelecomCallId); 1937 } 1938 1939 /** 1940 * Sends a {@code Call} event from this {@code Call} to the associated {@link Connection} in 1941 * the {@link ConnectionService}. 1942 * <p> 1943 * Call events are used to communicate point in time information from an {@link InCallService} 1944 * to a {@link ConnectionService}. A {@link ConnectionService} implementation could define 1945 * events which enable the {@link InCallService}, for example, toggle a unique feature of the 1946 * {@link ConnectionService}. 1947 * <p> 1948 * A {@link ConnectionService} can communicate to the {@link InCallService} using 1949 * {@link Connection#sendConnectionEvent(String, Bundle)}. 1950 * <p> 1951 * Events are exposed to {@link ConnectionService} implementations via 1952 * {@link android.telecom.Connection#onCallEvent(String, Bundle)}. 1953 * <p> 1954 * No assumptions should be made as to how a {@link ConnectionService} will handle these events. 1955 * The {@link InCallService} must assume that the {@link ConnectionService} could chose to 1956 * ignore some events altogether. 1957 * <p> 1958 * Events should be fully qualified (e.g., {@code com.example.event.MY_EVENT}) to avoid 1959 * conflicts between {@link InCallService} implementations. Further, {@link InCallService} 1960 * implementations shall not re-purpose events in the {@code android.*} namespace, nor shall 1961 * they define their own event types in this namespace. When defining a custom event type, 1962 * ensure the contents of the extras {@link Bundle} is clearly defined. Extra keys for this 1963 * bundle should be named similar to the event type (e.g. {@code com.example.extra.MY_EXTRA}). 1964 * <p> 1965 * When defining events and the associated extras, it is important to keep their behavior 1966 * consistent when the associated {@link InCallService} is updated. Support for deprecated 1967 * events/extras should me maintained to ensure backwards compatibility with older 1968 * {@link ConnectionService} implementations which were built to support the older behavior. 1969 * 1970 * @param event The connection event. 1971 * @param extras Bundle containing extra information associated with the event. 1972 */ sendCallEvent(String event, Bundle extras)1973 public void sendCallEvent(String event, Bundle extras) { 1974 mInCallAdapter.sendCallEvent(mTelecomCallId, event, mTargetSdkVersion, extras); 1975 } 1976 1977 /** 1978 * Sends an RTT upgrade request to the remote end of the connection. Success is not 1979 * guaranteed, and notification of success will be via the 1980 * {@link Callback#onRttStatusChanged(Call, boolean, RttCall)} callback. 1981 */ sendRttRequest()1982 public void sendRttRequest() { 1983 mInCallAdapter.sendRttRequest(mTelecomCallId); 1984 } 1985 1986 /** 1987 * Responds to an RTT request received via the {@link Callback#onRttRequest(Call, int)} )} 1988 * callback. 1989 * The ID used here should be the same as the ID that was received via the callback. 1990 * @param id The request ID received via {@link Callback#onRttRequest(Call, int)} 1991 * @param accept {@code true} if the RTT request should be accepted, {@code false} otherwise. 1992 */ respondToRttRequest(int id, boolean accept)1993 public void respondToRttRequest(int id, boolean accept) { 1994 mInCallAdapter.respondToRttRequest(mTelecomCallId, id, accept); 1995 } 1996 1997 /** 1998 * Initiates a handover of this {@link Call} to the {@link ConnectionService} identified 1999 * by {@code toHandle}. The videoState specified indicates the desired video state after the 2000 * handover. 2001 * <p> 2002 * A call handover is the process where an ongoing call is transferred from one app (i.e. 2003 * {@link ConnectionService} to another app. The user could, for example, choose to continue a 2004 * mobile network call in a video calling app. The mobile network call via the Telephony stack 2005 * is referred to as the source of the handover, and the video calling app is referred to as the 2006 * destination. 2007 * <p> 2008 * When considering a handover scenario the device this method is called on is considered the 2009 * <em>initiating</em> device (since the user initiates the handover from this device), and the 2010 * other device is considered the <em>receiving</em> device. 2011 * <p> 2012 * When this method is called on the <em>initiating</em> device, the Telecom framework will bind 2013 * to the {@link ConnectionService} defined by the {@code toHandle} {@link PhoneAccountHandle} 2014 * and invoke 2015 * {@link ConnectionService#onCreateOutgoingHandoverConnection(PhoneAccountHandle, 2016 * ConnectionRequest)} to inform the destination app that a request has been made to handover a 2017 * call to it. The app returns an instance of {@link Connection} to represent the handover call 2018 * At this point the app should display UI to indicate to the user that a call 2019 * handover is in process. 2020 * <p> 2021 * The destination app is responsible for communicating the handover request from the 2022 * <em>initiating</em> device to the <em>receiving</em> device. 2023 * <p> 2024 * When the app on the <em>receiving</em> device receives the handover request, it calls 2025 * {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)} to continue the handover 2026 * process from the <em>initiating</em> device to the <em>receiving</em> device. At this point 2027 * the destination app on the <em>receiving</em> device should show UI to allow the user to 2028 * choose whether they want to continue their call in the destination app. 2029 * <p> 2030 * When the destination app on the <em>receiving</em> device calls 2031 * {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)}, Telecom will bind to its 2032 * {@link ConnectionService} and call 2033 * {@link ConnectionService#onCreateIncomingHandoverConnection(PhoneAccountHandle, 2034 * ConnectionRequest)} to inform it of the handover request. The app returns an instance of 2035 * {@link Connection} to represent the handover call. 2036 * <p> 2037 * If the user of the <em>receiving</em> device accepts the handover, the app calls 2038 * {@link Connection#setActive()} to complete the handover process; Telecom will disconnect the 2039 * original call. If the user rejects the handover, the app calls 2040 * {@link Connection#setDisconnected(DisconnectCause)} and specifies a {@link DisconnectCause} 2041 * of {@link DisconnectCause#CANCELED} to indicate that the handover has been cancelled. 2042 * <p> 2043 * Telecom will only allow handovers from {@link PhoneAccount}s which declare 2044 * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}. Similarly, the {@link PhoneAccount} 2045 * specified by {@code toHandle} must declare {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_TO}. 2046 * <p> 2047 * Errors in the handover process are reported to the {@link InCallService} via 2048 * {@link Callback#onHandoverFailed(Call, int)}. Errors in the handover process are reported to 2049 * the involved {@link ConnectionService}s via 2050 * {@link ConnectionService#onHandoverFailed(ConnectionRequest, int)}. 2051 * 2052 * @param toHandle {@link PhoneAccountHandle} of the {@link ConnectionService} to handover 2053 * this call to. 2054 * @param videoState Indicates the video state desired after the handover (see the 2055 * {@code STATE_*} constants defined in {@link VideoProfile}). 2056 * @param extras Bundle containing extra information to be passed to the 2057 * {@link ConnectionService} 2058 */ handoverTo(PhoneAccountHandle toHandle, @VideoProfile.VideoState int videoState, Bundle extras)2059 public void handoverTo(PhoneAccountHandle toHandle, @VideoProfile.VideoState int videoState, 2060 Bundle extras) { 2061 mInCallAdapter.handoverTo(mTelecomCallId, toHandle, videoState, extras); 2062 } 2063 2064 /** 2065 * Terminate the RTT session on this call. The resulting state change will be notified via 2066 * the {@link Callback#onRttStatusChanged(Call, boolean, RttCall)} callback. 2067 */ stopRtt()2068 public void stopRtt() { 2069 mInCallAdapter.stopRtt(mTelecomCallId); 2070 } 2071 2072 /** 2073 * Adds some extras to this {@link Call}. Existing keys are replaced and new ones are 2074 * added. 2075 * <p> 2076 * No assumptions should be made as to how an In-Call UI or service will handle these 2077 * extras. Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts. 2078 * 2079 * @param extras The extras to add. 2080 */ putExtras(Bundle extras)2081 public final void putExtras(Bundle extras) { 2082 if (extras == null) { 2083 return; 2084 } 2085 2086 if (mExtras == null) { 2087 mExtras = new Bundle(); 2088 } 2089 mExtras.putAll(extras); 2090 mInCallAdapter.putExtras(mTelecomCallId, extras); 2091 } 2092 2093 /** 2094 * Adds a boolean extra to this {@link Call}. 2095 * 2096 * @param key The extra key. 2097 * @param value The value. 2098 * @hide 2099 */ putExtra(String key, boolean value)2100 public final void putExtra(String key, boolean value) { 2101 if (mExtras == null) { 2102 mExtras = new Bundle(); 2103 } 2104 mExtras.putBoolean(key, value); 2105 mInCallAdapter.putExtra(mTelecomCallId, key, value); 2106 } 2107 2108 /** 2109 * Adds an integer extra to this {@link Call}. 2110 * 2111 * @param key The extra key. 2112 * @param value The value. 2113 * @hide 2114 */ putExtra(String key, int value)2115 public final void putExtra(String key, int value) { 2116 if (mExtras == null) { 2117 mExtras = new Bundle(); 2118 } 2119 mExtras.putInt(key, value); 2120 mInCallAdapter.putExtra(mTelecomCallId, key, value); 2121 } 2122 2123 /** 2124 * Adds a string extra to this {@link Call}. 2125 * 2126 * @param key The extra key. 2127 * @param value The value. 2128 * @hide 2129 */ putExtra(String key, String value)2130 public final void putExtra(String key, String value) { 2131 if (mExtras == null) { 2132 mExtras = new Bundle(); 2133 } 2134 mExtras.putString(key, value); 2135 mInCallAdapter.putExtra(mTelecomCallId, key, value); 2136 } 2137 2138 /** 2139 * Removes extras from this {@link Call}. 2140 * 2141 * @param keys The keys of the extras to remove. 2142 */ removeExtras(List<String> keys)2143 public final void removeExtras(List<String> keys) { 2144 if (mExtras != null) { 2145 for (String key : keys) { 2146 mExtras.remove(key); 2147 } 2148 if (mExtras.size() == 0) { 2149 mExtras = null; 2150 } 2151 } 2152 mInCallAdapter.removeExtras(mTelecomCallId, keys); 2153 } 2154 2155 /** 2156 * Removes extras from this {@link Call}. 2157 * 2158 * @param keys The keys of the extras to remove. 2159 */ removeExtras(String .... keys)2160 public final void removeExtras(String ... keys) { 2161 removeExtras(Arrays.asList(keys)); 2162 } 2163 2164 /** 2165 * Obtains the parent of this {@code Call} in a conference, if any. 2166 * 2167 * @return The parent {@code Call}, or {@code null} if this {@code Call} is not a 2168 * child of any conference {@code Call}s. 2169 */ getParent()2170 public Call getParent() { 2171 if (mParentId != null) { 2172 return mPhone.internalGetCallByTelecomId(mParentId); 2173 } 2174 return null; 2175 } 2176 2177 /** 2178 * Obtains the children of this conference {@code Call}, if any. 2179 * 2180 * @return The children of this {@code Call} if this {@code Call} is a conference, or an empty 2181 * {@code List} otherwise. 2182 */ getChildren()2183 public List<Call> getChildren() { 2184 if (!mChildrenCached) { 2185 mChildrenCached = true; 2186 mChildren.clear(); 2187 2188 for(String id : mChildrenIds) { 2189 Call call = mPhone.internalGetCallByTelecomId(id); 2190 if (call == null) { 2191 // At least one child was still not found, so do not save true for "cached" 2192 mChildrenCached = false; 2193 } else { 2194 mChildren.add(call); 2195 } 2196 } 2197 } 2198 2199 return mUnmodifiableChildren; 2200 } 2201 2202 /** 2203 * Returns the list of {@code Call}s with which this {@code Call} is allowed to conference. 2204 * 2205 * @return The list of conferenceable {@code Call}s. 2206 */ getConferenceableCalls()2207 public List<Call> getConferenceableCalls() { 2208 return mUnmodifiableConferenceableCalls; 2209 } 2210 2211 /** 2212 * Obtains the state of this {@code Call}. 2213 * 2214 * @return The call state. 2215 * @deprecated The call state is available via {@link Call.Details#getState()}. 2216 */ 2217 @Deprecated getState()2218 public @CallState int getState() { 2219 return mState; 2220 } 2221 2222 /** 2223 * Returns the child {@link Call} in a generic conference that is currently active. 2224 * 2225 * A "generic conference" is the mechanism used to support two simultaneous calls on a device 2226 * in CDMA networks. It is effectively equivalent to having one call active and one call on hold 2227 * in GSM or IMS calls. This method returns the currently active call. 2228 * 2229 * In a generic conference, the network exposes the conference to us as a single call, and we 2230 * switch between talking to the two participants using a CDMA flash command. Since the network 2231 * exposes no additional information about the call, the only way we know which caller we're 2232 * currently talking to is by keeping track of the flash commands that we've sent to the 2233 * network. 2234 * 2235 * For calls that are not generic conferences, or when the generic conference has more than 2236 * 2 children, returns {@code null}. 2237 * @see Details#PROPERTY_GENERIC_CONFERENCE 2238 * @return The active child call. 2239 */ getGenericConferenceActiveChildCall()2240 public @Nullable Call getGenericConferenceActiveChildCall() { 2241 if (mActiveGenericConferenceChild != null) { 2242 return mPhone.internalGetCallByTelecomId(mActiveGenericConferenceChild); 2243 } 2244 return null; 2245 } 2246 2247 /** 2248 * Obtains a list of canned, pre-configured message responses to present to the user as 2249 * ways of rejecting an incoming {@code Call} using via a text message. 2250 * <p> 2251 * <em>Note:</em> Since canned responses may be loaded from the file system, they are not 2252 * guaranteed to be present when this {@link Call} is first added to the {@link InCallService} 2253 * via {@link InCallService#onCallAdded(Call)}. The callback 2254 * {@link Call.Callback#onCannedTextResponsesLoaded(Call, List)} will be called when/if canned 2255 * responses for the call become available. 2256 * 2257 * @see #reject(boolean, String) 2258 * 2259 * @return A list of canned text message responses. 2260 */ getCannedTextResponses()2261 public List<String> getCannedTextResponses() { 2262 return mCannedTextResponses; 2263 } 2264 2265 /** 2266 * Obtains an object that can be used to display video from this {@code Call}. 2267 * 2268 * @return An {@code Call.VideoCall}. 2269 */ getVideoCall()2270 public InCallService.VideoCall getVideoCall() { 2271 return mVideoCallImpl; 2272 } 2273 2274 /** 2275 * Obtains an object containing call details. 2276 * 2277 * @return A {@link Details} object. Depending on the state of the {@code Call}, the 2278 * result may be {@code null}. 2279 */ getDetails()2280 public Details getDetails() { 2281 return mDetails; 2282 } 2283 2284 /** 2285 * Returns this call's RttCall object. The {@link RttCall} instance is used to send and 2286 * receive RTT text data, as well as to change the RTT mode. 2287 * @return A {@link Call.RttCall}. {@code null} if there is no active RTT connection. 2288 */ getRttCall()2289 public @Nullable RttCall getRttCall() { 2290 return mRttCall; 2291 } 2292 2293 /** 2294 * Returns whether this call has an active RTT connection. 2295 * @return true if there is a connection, false otherwise. 2296 */ isRttActive()2297 public boolean isRttActive() { 2298 return mRttCall != null && mDetails.hasProperty(Details.PROPERTY_RTT); 2299 } 2300 2301 /** 2302 * Registers a callback to this {@code Call}. 2303 * 2304 * @param callback A {@code Callback}. 2305 */ registerCallback(Callback callback)2306 public void registerCallback(Callback callback) { 2307 registerCallback(callback, new Handler()); 2308 } 2309 2310 /** 2311 * Registers a callback to this {@code Call}. 2312 * 2313 * @param callback A {@code Callback}. 2314 * @param handler A handler which command and status changes will be delivered to. 2315 */ registerCallback(Callback callback, Handler handler)2316 public void registerCallback(Callback callback, Handler handler) { 2317 unregisterCallback(callback); 2318 // Don't allow new callback registration if the call is already being destroyed. 2319 if (callback != null && handler != null && mState != STATE_DISCONNECTED) { 2320 mCallbackRecords.add(new CallbackRecord<Callback>(callback, handler)); 2321 } 2322 } 2323 2324 /** 2325 * Unregisters a callback from this {@code Call}. 2326 * 2327 * @param callback A {@code Callback}. 2328 */ unregisterCallback(Callback callback)2329 public void unregisterCallback(Callback callback) { 2330 // Don't allow callback deregistration if the call is already being destroyed. 2331 if (callback != null && mState != STATE_DISCONNECTED) { 2332 for (CallbackRecord<Callback> record : mCallbackRecords) { 2333 if (record.getCallback() == callback) { 2334 mCallbackRecords.remove(record); 2335 break; 2336 } 2337 } 2338 } 2339 } 2340 2341 @Override toString()2342 public String toString() { 2343 return new StringBuilder(). 2344 append("Call [id: "). 2345 append(mTelecomCallId). 2346 append(", state: "). 2347 append(stateToString(mState)). 2348 append(", details: "). 2349 append(mDetails). 2350 append("]").toString(); 2351 } 2352 2353 /** 2354 * @param state An integer value of a {@code STATE_*} constant. 2355 * @return A string representation of the value. 2356 */ stateToString(int state)2357 private static String stateToString(int state) { 2358 switch (state) { 2359 case STATE_NEW: 2360 return "NEW"; 2361 case STATE_RINGING: 2362 return "RINGING"; 2363 case STATE_DIALING: 2364 return "DIALING"; 2365 case STATE_ACTIVE: 2366 return "ACTIVE"; 2367 case STATE_HOLDING: 2368 return "HOLDING"; 2369 case STATE_DISCONNECTED: 2370 return "DISCONNECTED"; 2371 case STATE_CONNECTING: 2372 return "CONNECTING"; 2373 case STATE_DISCONNECTING: 2374 return "DISCONNECTING"; 2375 case STATE_SELECT_PHONE_ACCOUNT: 2376 return "SELECT_PHONE_ACCOUNT"; 2377 case STATE_SIMULATED_RINGING: 2378 return "SIMULATED_RINGING"; 2379 case STATE_AUDIO_PROCESSING: 2380 return "AUDIO_PROCESSING"; 2381 default: 2382 Log.w(Call.class, "Unknown state %d", state); 2383 return "UNKNOWN"; 2384 } 2385 } 2386 2387 /** 2388 * Adds a listener to this {@code Call}. 2389 * 2390 * @param listener A {@code Listener}. 2391 * @deprecated Use {@link #registerCallback} instead. 2392 * @hide 2393 */ 2394 @Deprecated 2395 @SystemApi addListener(Listener listener)2396 public void addListener(Listener listener) { 2397 registerCallback(listener); 2398 } 2399 2400 /** 2401 * Removes a listener from this {@code Call}. 2402 * 2403 * @param listener A {@code Listener}. 2404 * @deprecated Use {@link #unregisterCallback} instead. 2405 * @hide 2406 */ 2407 @Deprecated 2408 @SystemApi removeListener(Listener listener)2409 public void removeListener(Listener listener) { 2410 unregisterCallback(listener); 2411 } 2412 2413 /** {@hide} */ Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter, String callingPackage, int targetSdkVersion)2414 Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter, String callingPackage, 2415 int targetSdkVersion) { 2416 mPhone = phone; 2417 mTelecomCallId = telecomCallId; 2418 mInCallAdapter = inCallAdapter; 2419 mState = STATE_NEW; 2420 mCallingPackage = callingPackage; 2421 mTargetSdkVersion = targetSdkVersion; 2422 } 2423 2424 /** {@hide} */ Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter, int state, String callingPackage, int targetSdkVersion)2425 Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter, int state, 2426 String callingPackage, int targetSdkVersion) { 2427 mPhone = phone; 2428 mTelecomCallId = telecomCallId; 2429 mInCallAdapter = inCallAdapter; 2430 mState = state; 2431 mCallingPackage = callingPackage; 2432 mTargetSdkVersion = targetSdkVersion; 2433 } 2434 2435 /** {@hide} */ internalGetCallId()2436 final String internalGetCallId() { 2437 return mTelecomCallId; 2438 } 2439 2440 /** {@hide} */ internalUpdate(ParcelableCall parcelableCall, Map<String, Call> callIdMap)2441 final void internalUpdate(ParcelableCall parcelableCall, Map<String, Call> callIdMap) { 2442 2443 // First, we update the internal state as far as possible before firing any updates. 2444 Details details = Details.createFromParcelableCall(parcelableCall); 2445 boolean detailsChanged = !Objects.equals(mDetails, details); 2446 if (detailsChanged) { 2447 mDetails = details; 2448 } 2449 2450 boolean cannedTextResponsesChanged = false; 2451 if (mCannedTextResponses == null && parcelableCall.getCannedSmsResponses() != null 2452 && !parcelableCall.getCannedSmsResponses().isEmpty()) { 2453 mCannedTextResponses = 2454 Collections.unmodifiableList(parcelableCall.getCannedSmsResponses()); 2455 cannedTextResponsesChanged = true; 2456 } 2457 2458 IVideoProvider previousVideoProvider = mVideoCallImpl == null ? null : 2459 mVideoCallImpl.getVideoProvider(); 2460 IVideoProvider newVideoProvider = parcelableCall.getVideoProvider(); 2461 2462 // parcelableCall.isVideoCallProviderChanged is only true when we have a video provider 2463 // specified; so we should check if the actual IVideoProvider changes as well. 2464 boolean videoCallChanged = parcelableCall.isVideoCallProviderChanged() 2465 && !Objects.equals(previousVideoProvider, newVideoProvider); 2466 if (videoCallChanged) { 2467 if (mVideoCallImpl != null) { 2468 mVideoCallImpl.destroy(); 2469 } 2470 mVideoCallImpl = parcelableCall.isVideoCallProviderChanged() ? 2471 parcelableCall.getVideoCallImpl(mCallingPackage, mTargetSdkVersion) : null; 2472 } 2473 2474 if (mVideoCallImpl != null) { 2475 mVideoCallImpl.setVideoState(getDetails().getVideoState()); 2476 } 2477 2478 int state = parcelableCall.getState(); 2479 if (mTargetSdkVersion < Phone.SDK_VERSION_R && state == Call.STATE_SIMULATED_RINGING) { 2480 state = Call.STATE_RINGING; 2481 } 2482 boolean stateChanged = mState != state; 2483 if (stateChanged) { 2484 mState = state; 2485 } 2486 2487 String parentId = parcelableCall.getParentCallId(); 2488 boolean parentChanged = !Objects.equals(mParentId, parentId); 2489 if (parentChanged) { 2490 mParentId = parentId; 2491 } 2492 2493 List<String> childCallIds = parcelableCall.getChildCallIds(); 2494 boolean childrenChanged = !Objects.equals(childCallIds, mChildrenIds); 2495 if (childrenChanged) { 2496 mChildrenIds.clear(); 2497 mChildrenIds.addAll(parcelableCall.getChildCallIds()); 2498 mChildrenCached = false; 2499 } 2500 2501 String activeChildCallId = parcelableCall.getActiveChildCallId(); 2502 boolean activeChildChanged = !Objects.equals(activeChildCallId, 2503 mActiveGenericConferenceChild); 2504 if (activeChildChanged) { 2505 mActiveGenericConferenceChild = activeChildCallId; 2506 } 2507 2508 List<String> conferenceableCallIds = parcelableCall.getConferenceableCallIds(); 2509 List<Call> conferenceableCalls = new ArrayList<Call>(conferenceableCallIds.size()); 2510 for (String otherId : conferenceableCallIds) { 2511 if (callIdMap.containsKey(otherId)) { 2512 conferenceableCalls.add(callIdMap.get(otherId)); 2513 } 2514 } 2515 2516 if (!Objects.equals(mConferenceableCalls, conferenceableCalls)) { 2517 mConferenceableCalls.clear(); 2518 mConferenceableCalls.addAll(conferenceableCalls); 2519 fireConferenceableCallsChanged(); 2520 } 2521 2522 boolean isRttChanged = false; 2523 boolean rttModeChanged = false; 2524 if (parcelableCall.getIsRttCallChanged() 2525 && mDetails.hasProperty(Details.PROPERTY_RTT)) { 2526 ParcelableRttCall parcelableRttCall = parcelableCall.getParcelableRttCall(); 2527 InputStreamReader receiveStream = new InputStreamReader( 2528 new ParcelFileDescriptor.AutoCloseInputStream( 2529 parcelableRttCall.getReceiveStream()), 2530 StandardCharsets.UTF_8); 2531 OutputStreamWriter transmitStream = new OutputStreamWriter( 2532 new ParcelFileDescriptor.AutoCloseOutputStream( 2533 parcelableRttCall.getTransmitStream()), 2534 StandardCharsets.UTF_8); 2535 RttCall newRttCall = new Call.RttCall(mTelecomCallId, 2536 receiveStream, transmitStream, parcelableRttCall.getRttMode(), mInCallAdapter); 2537 if (mRttCall == null) { 2538 isRttChanged = true; 2539 } else if (mRttCall.getRttAudioMode() != newRttCall.getRttAudioMode()) { 2540 rttModeChanged = true; 2541 } 2542 mRttCall = newRttCall; 2543 } else if (mRttCall != null && parcelableCall.getParcelableRttCall() == null 2544 && parcelableCall.getIsRttCallChanged()) { 2545 isRttChanged = true; 2546 mRttCall.close(); 2547 mRttCall = null; 2548 } 2549 2550 // Now we fire updates, ensuring that any client who listens to any of these notifications 2551 // gets the most up-to-date state. 2552 2553 if (stateChanged) { 2554 fireStateChanged(mState); 2555 } 2556 if (detailsChanged) { 2557 fireDetailsChanged(mDetails); 2558 } 2559 if (cannedTextResponsesChanged) { 2560 fireCannedTextResponsesLoaded(mCannedTextResponses); 2561 } 2562 if (videoCallChanged) { 2563 fireVideoCallChanged(mVideoCallImpl); 2564 } 2565 if (parentChanged) { 2566 fireParentChanged(getParent()); 2567 } 2568 if (childrenChanged || activeChildChanged) { 2569 fireChildrenChanged(getChildren()); 2570 } 2571 if (isRttChanged) { 2572 fireOnIsRttChanged(mRttCall != null, mRttCall); 2573 } 2574 if (rttModeChanged) { 2575 fireOnRttModeChanged(mRttCall.getRttAudioMode()); 2576 } 2577 2578 // If we have transitioned to DISCONNECTED, that means we need to notify clients and 2579 // remove ourselves from the Phone. Note that we do this after completing all state updates 2580 // so a client can cleanly transition all their UI to the state appropriate for a 2581 // DISCONNECTED Call while still relying on the existence of that Call in the Phone's list. 2582 if (mState == STATE_DISCONNECTED) { 2583 fireCallDestroyed(); 2584 } 2585 } 2586 2587 /** {@hide} */ internalSetPostDialWait(String remaining)2588 final void internalSetPostDialWait(String remaining) { 2589 mRemainingPostDialSequence = remaining; 2590 firePostDialWait(mRemainingPostDialSequence); 2591 } 2592 2593 /** {@hide} */ internalSetDisconnected()2594 final void internalSetDisconnected() { 2595 if (mState != Call.STATE_DISCONNECTED) { 2596 mState = Call.STATE_DISCONNECTED; 2597 if (mDetails != null) { 2598 mDetails = new Details(mState, 2599 mDetails.getTelecomCallId(), 2600 mDetails.getHandle(), 2601 mDetails.getHandlePresentation(), 2602 mDetails.getCallerDisplayName(), 2603 mDetails.getCallerDisplayNamePresentation(), 2604 mDetails.getAccountHandle(), 2605 mDetails.getCallCapabilities(), 2606 mDetails.getCallProperties(), 2607 mDetails.getDisconnectCause(), 2608 mDetails.getConnectTimeMillis(), 2609 mDetails.getGatewayInfo(), 2610 mDetails.getVideoState(), 2611 mDetails.getStatusHints(), 2612 mDetails.getExtras(), 2613 mDetails.getIntentExtras(), 2614 mDetails.getCreationTimeMillis(), 2615 mDetails.getContactDisplayName(), 2616 mDetails.getCallDirection(), 2617 mDetails.getCallerNumberVerificationStatus() 2618 ); 2619 fireDetailsChanged(mDetails); 2620 } 2621 fireStateChanged(mState); 2622 fireCallDestroyed(); 2623 } 2624 } 2625 2626 /** {@hide} */ internalOnConnectionEvent(String event, Bundle extras)2627 final void internalOnConnectionEvent(String event, Bundle extras) { 2628 fireOnConnectionEvent(event, extras); 2629 } 2630 2631 /** {@hide} */ internalOnRttUpgradeRequest(final int requestId)2632 final void internalOnRttUpgradeRequest(final int requestId) { 2633 for (CallbackRecord<Callback> record : mCallbackRecords) { 2634 final Call call = this; 2635 final Callback callback = record.getCallback(); 2636 record.getHandler().post(() -> callback.onRttRequest(call, requestId)); 2637 } 2638 } 2639 2640 /** @hide */ internalOnRttInitiationFailure(int reason)2641 final void internalOnRttInitiationFailure(int reason) { 2642 for (CallbackRecord<Callback> record : mCallbackRecords) { 2643 final Call call = this; 2644 final Callback callback = record.getCallback(); 2645 record.getHandler().post(() -> callback.onRttInitiationFailure(call, reason)); 2646 } 2647 } 2648 2649 /** {@hide} */ internalOnHandoverFailed(int error)2650 final void internalOnHandoverFailed(int error) { 2651 for (CallbackRecord<Callback> record : mCallbackRecords) { 2652 final Call call = this; 2653 final Callback callback = record.getCallback(); 2654 record.getHandler().post(() -> callback.onHandoverFailed(call, error)); 2655 } 2656 } 2657 2658 /** {@hide} */ internalOnHandoverComplete()2659 final void internalOnHandoverComplete() { 2660 for (CallbackRecord<Callback> record : mCallbackRecords) { 2661 final Call call = this; 2662 final Callback callback = record.getCallback(); 2663 record.getHandler().post(() -> callback.onHandoverComplete(call)); 2664 } 2665 } 2666 fireStateChanged(final int newState)2667 private void fireStateChanged(final int newState) { 2668 for (CallbackRecord<Callback> record : mCallbackRecords) { 2669 final Call call = this; 2670 final Callback callback = record.getCallback(); 2671 record.getHandler().post(new Runnable() { 2672 @Override 2673 public void run() { 2674 callback.onStateChanged(call, newState); 2675 } 2676 }); 2677 } 2678 } 2679 fireParentChanged(final Call newParent)2680 private void fireParentChanged(final Call newParent) { 2681 for (CallbackRecord<Callback> record : mCallbackRecords) { 2682 final Call call = this; 2683 final Callback callback = record.getCallback(); 2684 record.getHandler().post(new Runnable() { 2685 @Override 2686 public void run() { 2687 callback.onParentChanged(call, newParent); 2688 } 2689 }); 2690 } 2691 } 2692 fireChildrenChanged(final List<Call> children)2693 private void fireChildrenChanged(final List<Call> children) { 2694 for (CallbackRecord<Callback> record : mCallbackRecords) { 2695 final Call call = this; 2696 final Callback callback = record.getCallback(); 2697 record.getHandler().post(new Runnable() { 2698 @Override 2699 public void run() { 2700 callback.onChildrenChanged(call, children); 2701 } 2702 }); 2703 } 2704 } 2705 fireDetailsChanged(final Details details)2706 private void fireDetailsChanged(final Details details) { 2707 for (CallbackRecord<Callback> record : mCallbackRecords) { 2708 final Call call = this; 2709 final Callback callback = record.getCallback(); 2710 record.getHandler().post(new Runnable() { 2711 @Override 2712 public void run() { 2713 callback.onDetailsChanged(call, details); 2714 } 2715 }); 2716 } 2717 } 2718 fireCannedTextResponsesLoaded(final List<String> cannedTextResponses)2719 private void fireCannedTextResponsesLoaded(final List<String> cannedTextResponses) { 2720 for (CallbackRecord<Callback> record : mCallbackRecords) { 2721 final Call call = this; 2722 final Callback callback = record.getCallback(); 2723 record.getHandler().post(new Runnable() { 2724 @Override 2725 public void run() { 2726 callback.onCannedTextResponsesLoaded(call, cannedTextResponses); 2727 } 2728 }); 2729 } 2730 } 2731 fireVideoCallChanged(final InCallService.VideoCall videoCall)2732 private void fireVideoCallChanged(final InCallService.VideoCall videoCall) { 2733 for (CallbackRecord<Callback> record : mCallbackRecords) { 2734 final Call call = this; 2735 final Callback callback = record.getCallback(); 2736 record.getHandler().post(new Runnable() { 2737 @Override 2738 public void run() { 2739 callback.onVideoCallChanged(call, videoCall); 2740 } 2741 }); 2742 } 2743 } 2744 firePostDialWait(final String remainingPostDialSequence)2745 private void firePostDialWait(final String remainingPostDialSequence) { 2746 for (CallbackRecord<Callback> record : mCallbackRecords) { 2747 final Call call = this; 2748 final Callback callback = record.getCallback(); 2749 record.getHandler().post(new Runnable() { 2750 @Override 2751 public void run() { 2752 callback.onPostDialWait(call, remainingPostDialSequence); 2753 } 2754 }); 2755 } 2756 } 2757 fireCallDestroyed()2758 private void fireCallDestroyed() { 2759 /** 2760 * To preserve the ordering of the Call's onCallDestroyed callback and Phone's 2761 * onCallRemoved callback, we remove this call from the Phone's record 2762 * only once all of the registered onCallDestroyed callbacks are executed. 2763 * All the callbacks get removed from our records as a part of this operation 2764 * since onCallDestroyed is the final callback. 2765 */ 2766 final Call call = this; 2767 if (mCallbackRecords.isEmpty()) { 2768 // No callbacks registered, remove the call from Phone's record. 2769 mPhone.internalRemoveCall(call); 2770 } 2771 for (final CallbackRecord<Callback> record : mCallbackRecords) { 2772 final Callback callback = record.getCallback(); 2773 record.getHandler().post(new Runnable() { 2774 @Override 2775 public void run() { 2776 boolean isFinalRemoval = false; 2777 RuntimeException toThrow = null; 2778 try { 2779 callback.onCallDestroyed(call); 2780 } catch (RuntimeException e) { 2781 toThrow = e; 2782 } 2783 synchronized(Call.this) { 2784 mCallbackRecords.remove(record); 2785 if (mCallbackRecords.isEmpty()) { 2786 isFinalRemoval = true; 2787 } 2788 } 2789 if (isFinalRemoval) { 2790 mPhone.internalRemoveCall(call); 2791 } 2792 if (toThrow != null) { 2793 throw toThrow; 2794 } 2795 } 2796 }); 2797 } 2798 } 2799 fireConferenceableCallsChanged()2800 private void fireConferenceableCallsChanged() { 2801 for (CallbackRecord<Callback> record : mCallbackRecords) { 2802 final Call call = this; 2803 final Callback callback = record.getCallback(); 2804 record.getHandler().post(new Runnable() { 2805 @Override 2806 public void run() { 2807 callback.onConferenceableCallsChanged(call, mUnmodifiableConferenceableCalls); 2808 } 2809 }); 2810 } 2811 } 2812 2813 /** 2814 * Notifies listeners of an incoming connection event. 2815 * <p> 2816 * Connection events are issued via {@link Connection#sendConnectionEvent(String, Bundle)}. 2817 * 2818 * @param event 2819 * @param extras 2820 */ fireOnConnectionEvent(final String event, final Bundle extras)2821 private void fireOnConnectionEvent(final String event, final Bundle extras) { 2822 for (CallbackRecord<Callback> record : mCallbackRecords) { 2823 final Call call = this; 2824 final Callback callback = record.getCallback(); 2825 record.getHandler().post(new Runnable() { 2826 @Override 2827 public void run() { 2828 callback.onConnectionEvent(call, event, extras); 2829 } 2830 }); 2831 } 2832 } 2833 2834 /** 2835 * Notifies listeners of an RTT on/off change 2836 * 2837 * @param enabled True if RTT is now enabled, false otherwise 2838 */ fireOnIsRttChanged(final boolean enabled, final RttCall rttCall)2839 private void fireOnIsRttChanged(final boolean enabled, final RttCall rttCall) { 2840 for (CallbackRecord<Callback> record : mCallbackRecords) { 2841 final Call call = this; 2842 final Callback callback = record.getCallback(); 2843 record.getHandler().post(() -> callback.onRttStatusChanged(call, enabled, rttCall)); 2844 } 2845 } 2846 2847 /** 2848 * Notifies listeners of a RTT mode change 2849 * 2850 * @param mode The new RTT mode 2851 */ fireOnRttModeChanged(final int mode)2852 private void fireOnRttModeChanged(final int mode) { 2853 for (CallbackRecord<Callback> record : mCallbackRecords) { 2854 final Call call = this; 2855 final Callback callback = record.getCallback(); 2856 record.getHandler().post(() -> callback.onRttModeChanged(call, mode)); 2857 } 2858 } 2859 2860 /** 2861 * Determines if two bundles are equal. 2862 * 2863 * @param bundle The original bundle. 2864 * @param newBundle The bundle to compare with. 2865 * @retrun {@code true} if the bundles are equal, {@code false} otherwise. 2866 */ areBundlesEqual(Bundle bundle, Bundle newBundle)2867 private static boolean areBundlesEqual(Bundle bundle, Bundle newBundle) { 2868 if (bundle == null || newBundle == null) { 2869 return bundle == newBundle; 2870 } 2871 2872 if (bundle.size() != newBundle.size()) { 2873 return false; 2874 } 2875 2876 for(String key : bundle.keySet()) { 2877 if (key != null) { 2878 final Object value = bundle.get(key); 2879 final Object newValue = newBundle.get(key); 2880 if (!Objects.equals(value, newValue)) { 2881 return false; 2882 } 2883 } 2884 } 2885 return true; 2886 } 2887 } 2888