1 /* 2 * Copyright (C) 2018 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.telephony.ims; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.SystemApi; 22 import android.annotation.TestApi; 23 import android.compat.annotation.UnsupportedAppUsage; 24 import android.os.Bundle; 25 import android.os.Parcel; 26 import android.os.Parcelable; 27 import android.telecom.VideoProfile; 28 import android.telephony.emergency.EmergencyNumber; 29 import android.telephony.emergency.EmergencyNumber.EmergencyCallRouting; 30 import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories; 31 import android.util.Log; 32 33 import com.android.internal.annotations.VisibleForTesting; 34 import com.android.internal.telephony.PhoneConstants; 35 import com.android.internal.telephony.util.TelephonyUtils; 36 37 import java.lang.annotation.Retention; 38 import java.lang.annotation.RetentionPolicy; 39 import java.util.ArrayList; 40 import java.util.List; 41 42 /** 43 * A Parcelable object to handle the IMS call profile, which provides the service, call type, and 44 * additional information related to the call. 45 * <p> 46 * See the following specifications for more information about this class: GSMA IR.92/IR.94, 47 * 3GPP TS 24.229/TS 26.114/TS26.111. 48 * @hide 49 */ 50 @SystemApi 51 @TestApi 52 public final class ImsCallProfile implements Parcelable { 53 private static final String TAG = "ImsCallProfile"; 54 55 /** 56 * Service types 57 */ 58 /** 59 * It is for a special case. It helps that the application can make a call 60 * without IMS connection (not registered). 61 * In the moment of the call initiation, the device try to connect to the IMS network 62 * and initiates the call. 63 */ 64 public static final int SERVICE_TYPE_NONE = 0; 65 /** 66 * It is a default type and can be selected when the device is connected to the IMS network. 67 */ 68 public static final int SERVICE_TYPE_NORMAL = 1; 69 /** 70 * It is for an emergency call. 71 */ 72 public static final int SERVICE_TYPE_EMERGENCY = 2; 73 74 /** 75 * Call types 76 */ 77 /** 78 * IMSPhone to support IR.92 & IR.94 (voice + video upgrade/downgrade) 79 */ 80 public static final int CALL_TYPE_VOICE_N_VIDEO = 1; 81 /** 82 * IR.92 (Voice only) 83 */ 84 public static final int CALL_TYPE_VOICE = 2; 85 /** 86 * VT to support IR.92 & IR.94 (voice + video upgrade/downgrade) 87 */ 88 public static final int CALL_TYPE_VIDEO_N_VOICE = 3; 89 /** 90 * Video Telephony (audio / video two way) 91 */ 92 public static final int CALL_TYPE_VT = 4; 93 /** 94 * Video Telephony (audio two way / video TX one way) 95 */ 96 public static final int CALL_TYPE_VT_TX = 5; 97 /** 98 * Video Telephony (audio two way / video RX one way) 99 */ 100 public static final int CALL_TYPE_VT_RX = 6; 101 /** 102 * Video Telephony (audio two way / video inactive) 103 */ 104 public static final int CALL_TYPE_VT_NODIR = 7; 105 /** 106 * VideoShare (video two way) 107 */ 108 public static final int CALL_TYPE_VS = 8; 109 /** 110 * VideoShare (video TX one way) 111 */ 112 public static final int CALL_TYPE_VS_TX = 9; 113 /** 114 * VideoShare (video RX one way) 115 */ 116 public static final int CALL_TYPE_VS_RX = 10; 117 118 /** 119 * Extra properties for IMS call. 120 */ 121 /** 122 * Boolean extra properties - "true" / "false" 123 * conference : Indicates if the session is for the conference call or not. 124 * e_call : Indicates if the session is for the emergency call or not. 125 * vms : Indicates if the session is connected to the voice mail system or not. 126 * call_mode_changeable : Indicates if the session is able to upgrade/downgrade 127 * the video during voice call. 128 * conference_avail : Indicates if the session can be extended to the conference. 129 */ 130 /** 131 * @hide 132 */ 133 public static final String EXTRA_CONFERENCE = "conference"; 134 135 /** 136 * Boolean extra property set on an {@link ImsCallProfile} to indicate that this call is an 137 * emergency call. The {@link ImsService} sets this on a call to indicate that the network has 138 * identified the call as an emergency call. 139 */ 140 public static final String EXTRA_EMERGENCY_CALL = "e_call"; 141 142 /** 143 * @hide 144 */ 145 public static final String EXTRA_VMS = "vms"; 146 /** 147 * @hide 148 */ 149 public static final String EXTRA_CALL_MODE_CHANGEABLE = "call_mode_changeable"; 150 /** 151 * @hide 152 */ 153 public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail"; 154 155 /** 156 * Extra key used to store a Bundle containing proprietary extras to send to the ImsService. 157 * Use {@link #getProprietaryCallExtras()} instead. 158 * @hide 159 */ 160 @TestApi 161 public static final String EXTRA_OEM_EXTRAS = "android.telephony.ims.extra.OEM_EXTRAS"; 162 163 /** 164 * Rule for originating identity (number) presentation, MO/MT. 165 * {@link ImsCallProfile#OIR_DEFAULT} 166 * {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED} 167 * {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED} 168 */ 169 public static final String EXTRA_OIR = "oir"; 170 /** 171 * Rule for calling name presentation 172 * {@link ImsCallProfile#OIR_DEFAULT} 173 * {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED} 174 * {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED} 175 */ 176 public static final String EXTRA_CNAP = "cnap"; 177 /** 178 * To identify the Ims call type, MO 179 * {@link ImsCallProfile#DIALSTRING_NORMAL} 180 * {@link ImsCallProfile#DIALSTRING_SS_CONF} 181 * {@link ImsCallProfile#DIALSTRING_USSD} 182 */ 183 public static final String EXTRA_DIALSTRING = "dialstring"; 184 /** 185 * This extra holds call fail cause because of which redial is attempted. 186 * see {@link android.telephony.ims.ImsReasonInfo} {@code CODE_*} 187 * for possible values this extra can hold. 188 * 189 * @hide 190 */ 191 public static final String EXTRA_RETRY_CALL_FAIL_REASON = 192 "android.telephony.ims.extra.RETRY_CALL_FAIL_REASON"; 193 /** 194 * This extra holds call network type on which lower layers 195 * may try attempting redial. 196 * See {@link TelephonyManager} {@code NETWORK_TYPE_*} 197 * for possible values this extra can hold. 198 * 199 * @hide 200 */ 201 public static final String EXTRA_RETRY_CALL_FAIL_NETWORKTYPE = 202 "android.telephony.ims.extra.RETRY_CALL_FAIL_NETWORKTYPE"; 203 204 /** 205 * Values for EXTRA_OIR / EXTRA_CNAP 206 */ 207 /** 208 * Default presentation for Originating Identity. 209 */ 210 public static final int OIR_DEFAULT = 0; // "user subscription default value" 211 /** 212 * Restricted presentation for Originating Identity. 213 */ 214 public static final int OIR_PRESENTATION_RESTRICTED = 1; 215 /** 216 * Not restricted presentation for Originating Identity. 217 */ 218 public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2; 219 /** 220 * Presentation unknown for Originating Identity. 221 */ 222 public static final int OIR_PRESENTATION_UNKNOWN = 3; 223 /** 224 * Payphone presentation for Originating Identity. 225 */ 226 public static final int OIR_PRESENTATION_PAYPHONE = 4; 227 228 //Values for EXTRA_DIALSTRING 229 /** 230 * A default or normal normal call. 231 */ 232 public static final int DIALSTRING_NORMAL = 0; 233 /** 234 * Call for SIP-based user configuration 235 */ 236 public static final int DIALSTRING_SS_CONF = 1; 237 /** 238 * Call for USSD message 239 */ 240 public static final int DIALSTRING_USSD = 2; 241 242 /** 243 * Call is not restricted on peer side and High Definition media is supported 244 */ 245 public static final int CALL_RESTRICT_CAUSE_NONE = 0; 246 247 /** 248 * High Definition media is not supported on the peer side due to the Radio Access Technology 249 * (RAT) it is are connected to. 250 */ 251 public static final int CALL_RESTRICT_CAUSE_RAT = 1; 252 253 /** 254 * The service has been disabled on the peer side. 255 */ 256 public static final int CALL_RESTRICT_CAUSE_DISABLED = 2; 257 258 /** 259 * High definition media is not currently supported. 260 */ 261 public static final int CALL_RESTRICT_CAUSE_HD = 3; 262 263 /**@hide*/ 264 @Retention(RetentionPolicy.SOURCE) 265 @IntDef(prefix = "CALL_RESTRICT_CAUSE_", value = { 266 CALL_RESTRICT_CAUSE_NONE, 267 CALL_RESTRICT_CAUSE_RAT, 268 CALL_RESTRICT_CAUSE_DISABLED, 269 CALL_RESTRICT_CAUSE_HD 270 }) 271 public @interface CallRestrictCause {} 272 273 /** 274 * String extra properties 275 * oi : Originating identity (number), MT only 276 * cna : Calling name 277 * ussd : For network-initiated USSD, MT only 278 * remote_uri : Connected user identity (it can be used for the conference) 279 * ChildNum: Child number info. 280 * Codec: Codec info. 281 * DisplayText: Display text for the call. 282 * AdditionalCallInfo: Additional call info. 283 * CallPull: Boolean value specifying if the call is a pulled call. 284 */ 285 public static final String EXTRA_OI = "oi"; 286 public static final String EXTRA_CNA = "cna"; 287 public static final String EXTRA_USSD = "ussd"; 288 public static final String EXTRA_REMOTE_URI = "remote_uri"; 289 public static final String EXTRA_CHILD_NUMBER = "ChildNum"; 290 public static final String EXTRA_CODEC = "Codec"; 291 public static final String EXTRA_DISPLAY_TEXT = "DisplayText"; 292 public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo"; 293 public static final String EXTRA_IS_CALL_PULL = "CallPull"; 294 295 /** 296 * String extra property 297 * Containing fields from the SIP INVITE message for an IMS call 298 */ 299 public static final String EXTRA_ADDITIONAL_SIP_INVITE_FIELDS = 300 "android.telephony.ims.extra.ADDITIONAL_SIP_INVITE_FIELDS"; 301 302 /** 303 * CallDisconnectCause: Specify call disconnect cause. This extra should be a code 304 * corresponding to ImsReasonInfo and should only be populated in the case that the 305 * call has already been missed 306 */ 307 public static final String EXTRA_CALL_DISCONNECT_CAUSE = 308 "android.telephony.ims.extra.CALL_DISCONNECT_CAUSE"; 309 310 /** 311 * Extra key which the RIL can use to indicate the radio technology used for a call. 312 * Valid values are: 313 * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}, 314 * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_IWLAN}, and the other defined 315 * {@code RIL_RADIO_TECHNOLOGY_*} constants. 316 * Note: Despite the fact the {@link android.telephony.ServiceState} values are integer 317 * constants, the values passed for the {@link #EXTRA_CALL_RAT_TYPE} should be strings (e.g. 318 * "14" vs (int) 14). 319 * Note: This is used by {@link com.android.internal.telephony.imsphone.ImsPhoneConnection# 320 * updateImsCallRatFromExtras(Bundle)} to determine whether to set the 321 * {@link android.telecom.TelecomManager#EXTRA_CALL_NETWORK_TYPE} extra value and 322 * {@link android.telecom.Connection#PROPERTY_WIFI} property on a connection. 323 * @deprecated the constants associated with this extra are hidden, instead use 324 * {@link #EXTRA_CALL_NETWORK_TYPE}. 325 */ 326 @Deprecated 327 public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech"; 328 329 /** 330 * Extra key with an {@code int} value which can be set in {@link #setCallExtraInt(String, int)} 331 * to indicate the network type used for a call. 332 * <p> 333 * Valid values are defined by {@code TelephonyManager.NETWORK_TYPE_*} constants. An example may 334 * be {@link android.telephony.TelephonyManager#NETWORK_TYPE_LTE}. 335 */ 336 public static final String EXTRA_CALL_NETWORK_TYPE = 337 "android.telephony.ims.extra.CALL_NETWORK_TYPE"; 338 339 /** 340 * Similar to {@link #EXTRA_CALL_RAT_TYPE}, except with a lowercase 'c'. Used to ensure 341 * compatibility with modems that are non-compliant with the {@link #EXTRA_CALL_RAT_TYPE} 342 * extra key. Should be removed when the non-compliant modems are fixed. 343 * @hide 344 * @deprecated Use {@link #EXTRA_CALL_NETWORK_TYPE} instead. 345 */ 346 @Deprecated 347 public static final String EXTRA_CALL_RAT_TYPE_ALT = "callRadioTech"; 348 349 /** 350 * String extra property containing forwarded numbers associated with the current connection 351 * for an IMS call. The value is string array, and it can include multiple numbers, and 352 * the array values are expected E164 (e.g. +1 (650) 253-0000) format. 353 */ 354 public static final String EXTRA_FORWARDED_NUMBER = 355 "android.telephony.ims.extra.FORWARDED_NUMBER"; 356 357 /** @hide */ 358 public int mServiceType; 359 /** @hide */ 360 @UnsupportedAppUsage 361 public int mCallType; 362 /** @hide */ 363 @UnsupportedAppUsage 364 public @CallRestrictCause int mRestrictCause = CALL_RESTRICT_CAUSE_NONE; 365 366 /** 367 * The VERSTAT for an incoming call's phone number. 368 */ 369 private @VerificationStatus int mCallerNumberVerificationStatus; 370 371 /** 372 * Indicates that the network could not perform verification. 373 */ 374 public static final int VERIFICATION_STATUS_NOT_VERIFIED = 0; 375 376 /** 377 * Indicates that verification by the network passed. This indicates there is a high likelihood 378 * that the call originated from a valid source. 379 */ 380 public static final int VERIFICATION_STATUS_PASSED = 1; 381 382 /** 383 * Indicates that verification by the network failed. This indicates there is a high likelihood 384 * that the call did not originate from a valid source. 385 */ 386 public static final int VERIFICATION_STATUS_FAILED = 2; 387 388 /**@hide*/ 389 @Retention(RetentionPolicy.SOURCE) 390 @IntDef(prefix = "VERIFICATION_STATUS_", value = { 391 VERIFICATION_STATUS_NOT_VERIFIED, 392 VERIFICATION_STATUS_PASSED, 393 VERIFICATION_STATUS_FAILED 394 }) 395 public @interface VerificationStatus {} 396 397 /** 398 * The emergency service categories, only valid if {@link #getServiceType} returns 399 * {@link #SERVICE_TYPE_EMERGENCY} 400 * 401 * If valid, the value is the bitwise-OR combination of the following constants: 402 * <ol> 403 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} </li> 404 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_POLICE} </li> 405 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AMBULANCE} </li> 406 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE} </li> 407 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD} </li> 408 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE} </li> 409 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MIEC} </li> 410 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AIEC} </li> 411 * </ol> 412 * 413 * Reference: 3gpp 23.167, Section 6 - Functional description; 414 * 3gpp 22.101, Section 10 - Emergency Calls. 415 */ 416 private @EmergencyServiceCategories int mEmergencyServiceCategories = 417 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED; 418 419 /** 420 * The emergency Uniform Resource Names (URN), only valid if {@link #getServiceType} returns 421 * {@link #SERVICE_TYPE_EMERGENCY}. 422 * 423 * Reference: 3gpp 24.503, Section 5.1.6.8.1 - General; 424 * 3gpp 22.101, Section 10 - Emergency Calls. 425 */ 426 private List<String> mEmergencyUrns = new ArrayList<>(); 427 428 /** 429 * The emergency call routing, only valid if {@link #getServiceType} returns 430 * {@link #SERVICE_TYPE_EMERGENCY} 431 * 432 * If valid, the value is any of the following constants: 433 * <ol> 434 * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_UNKNOWN} </li> 435 * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_NORMAL} </li> 436 * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_EMERGENCY} </li> 437 * </ol> 438 */ 439 private @EmergencyCallRouting int mEmergencyCallRouting = 440 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN; 441 442 /** Indicates if the call is for testing purpose */ 443 private boolean mEmergencyCallTesting = false; 444 445 /** Indicates if we have known the intent of the user for the call is emergency */ 446 private boolean mHasKnownUserIntentEmergency = false; 447 448 /** 449 * Extras associated with this {@link ImsCallProfile}. 450 * <p> 451 * Valid data types include: 452 * <ul> 453 * <li>{@link Integer} (and int)</li> 454 * <li>{@link Long} (and long)</li> 455 * <li>{@link Double} (and double)</li> 456 * <li>{@link String}</li> 457 * <li>{@code int[]}</li> 458 * <li>{@code long[]}</li> 459 * <li>{@code double[]}</li> 460 * <li>{@code String[]}</li> 461 * <li>{@link android.os.PersistableBundle}</li> 462 * <li>{@link Boolean} (and boolean)</li> 463 * <li>{@code boolean[]}</li> 464 * <li>Other {@link Parcelable} classes in the {@code android.*} namespace.</li> 465 * </ul> 466 * <p> 467 * Invalid types will be removed when the {@link ImsCallProfile} is parceled for transmit across 468 * a {@link android.os.Binder}. 469 */ 470 /** @hide */ 471 @UnsupportedAppUsage 472 public Bundle mCallExtras; 473 /** @hide */ 474 @UnsupportedAppUsage 475 public ImsStreamMediaProfile mMediaProfile; 476 477 /** @hide */ ImsCallProfile(Parcel in)478 public ImsCallProfile(Parcel in) { 479 readFromParcel(in); 480 } 481 482 /** 483 * Default Constructor that initializes the call profile with service type 484 * {@link #SERVICE_TYPE_NORMAL} and call type {@link #CALL_TYPE_VIDEO_N_VOICE} 485 */ ImsCallProfile()486 public ImsCallProfile() { 487 mServiceType = SERVICE_TYPE_NORMAL; 488 mCallType = CALL_TYPE_VOICE_N_VIDEO; 489 mCallExtras = new Bundle(); 490 mMediaProfile = new ImsStreamMediaProfile(); 491 } 492 493 /** 494 * Constructor. 495 * 496 * @param serviceType the service type for the call. Can be one of the following: 497 * {@link #SERVICE_TYPE_NONE}, 498 * {@link #SERVICE_TYPE_NORMAL}, 499 * {@link #SERVICE_TYPE_EMERGENCY} 500 * @param callType the call type. Can be one of the following: 501 * {@link #CALL_TYPE_VOICE_N_VIDEO}, 502 * {@link #CALL_TYPE_VOICE}, 503 * {@link #CALL_TYPE_VIDEO_N_VOICE}, 504 * {@link #CALL_TYPE_VT}, 505 * {@link #CALL_TYPE_VT_TX}, 506 * {@link #CALL_TYPE_VT_RX}, 507 * {@link #CALL_TYPE_VT_NODIR}, 508 * {@link #CALL_TYPE_VS}, 509 * {@link #CALL_TYPE_VS_TX}, 510 * {@link #CALL_TYPE_VS_RX} 511 */ ImsCallProfile(int serviceType, int callType)512 public ImsCallProfile(int serviceType, int callType) { 513 mServiceType = serviceType; 514 mCallType = callType; 515 mCallExtras = new Bundle(); 516 mMediaProfile = new ImsStreamMediaProfile(); 517 } 518 519 /** 520 * Constructor. 521 * 522 * @param serviceType the service type for the call. Can be one of the following: 523 * {@link #SERVICE_TYPE_NONE}, 524 * {@link #SERVICE_TYPE_NORMAL}, 525 * {@link #SERVICE_TYPE_EMERGENCY} 526 * @param callType the call type. Can be one of the following: 527 * {@link #CALL_TYPE_VOICE_N_VIDEO}, 528 * {@link #CALL_TYPE_VOICE}, 529 * {@link #CALL_TYPE_VIDEO_N_VOICE}, 530 * {@link #CALL_TYPE_VT}, 531 * {@link #CALL_TYPE_VT_TX}, 532 * {@link #CALL_TYPE_VT_RX}, 533 * {@link #CALL_TYPE_VT_NODIR}, 534 * {@link #CALL_TYPE_VS}, 535 * {@link #CALL_TYPE_VS_TX}, 536 * {@link #CALL_TYPE_VS_RX} 537 * @param callExtras A bundle with the call extras. 538 * @param mediaProfile The IMS stream media profile. 539 */ ImsCallProfile(int serviceType, int callType, Bundle callExtras, ImsStreamMediaProfile mediaProfile)540 public ImsCallProfile(int serviceType, int callType, Bundle callExtras, 541 ImsStreamMediaProfile mediaProfile) { 542 mServiceType = serviceType; 543 mCallType = callType; 544 mCallExtras = callExtras; 545 mMediaProfile = mediaProfile; 546 } 547 getCallExtra(String name)548 public String getCallExtra(String name) { 549 return getCallExtra(name, ""); 550 } 551 getCallExtra(String name, String defaultValue)552 public String getCallExtra(String name, String defaultValue) { 553 if (mCallExtras == null) { 554 return defaultValue; 555 } 556 557 return mCallExtras.getString(name, defaultValue); 558 } 559 getCallExtraBoolean(String name)560 public boolean getCallExtraBoolean(String name) { 561 return getCallExtraBoolean(name, false); 562 } 563 getCallExtraBoolean(String name, boolean defaultValue)564 public boolean getCallExtraBoolean(String name, boolean defaultValue) { 565 if (mCallExtras == null) { 566 return defaultValue; 567 } 568 569 return mCallExtras.getBoolean(name, defaultValue); 570 } 571 getCallExtraInt(String name)572 public int getCallExtraInt(String name) { 573 return getCallExtraInt(name, -1); 574 } 575 getCallExtraInt(String name, int defaultValue)576 public int getCallExtraInt(String name, int defaultValue) { 577 if (mCallExtras == null) { 578 return defaultValue; 579 } 580 581 return mCallExtras.getInt(name, defaultValue); 582 } 583 setCallExtra(String name, String value)584 public void setCallExtra(String name, String value) { 585 if (mCallExtras != null) { 586 mCallExtras.putString(name, value); 587 } 588 } 589 setCallExtraBoolean(String name, boolean value)590 public void setCallExtraBoolean(String name, boolean value) { 591 if (mCallExtras != null) { 592 mCallExtras.putBoolean(name, value); 593 } 594 } 595 setCallExtraInt(String name, int value)596 public void setCallExtraInt(String name, int value) { 597 if (mCallExtras != null) { 598 mCallExtras.putInt(name, value); 599 } 600 } 601 602 /** 603 * Set the call restrict cause, which provides the reason why a call has been restricted from 604 * using High Definition media. 605 */ setCallRestrictCause(@allRestrictCause int cause)606 public void setCallRestrictCause(@CallRestrictCause int cause) { 607 mRestrictCause = cause; 608 } 609 updateCallType(ImsCallProfile profile)610 public void updateCallType(ImsCallProfile profile) { 611 mCallType = profile.mCallType; 612 } 613 updateCallExtras(ImsCallProfile profile)614 public void updateCallExtras(ImsCallProfile profile) { 615 mCallExtras.clear(); 616 mCallExtras = (Bundle) profile.mCallExtras.clone(); 617 } 618 619 /** 620 * Updates the media profile for the call. 621 * 622 * @param profile Call profile with new media profile. 623 */ updateMediaProfile(ImsCallProfile profile)624 public void updateMediaProfile(ImsCallProfile profile) { 625 mMediaProfile = profile.mMediaProfile; 626 } 627 628 /** 629 * Sets the verification status for the phone number of an incoming call as identified in 630 * ATIS-1000082. 631 * <p> 632 * The ImsService should parse the verstat information from the SIP INVITE headers for the call 633 * to determine this information. It is typically found in the P-Asserted-Identity OR From 634 * header fields. 635 * @param callerNumberVerificationStatus the new verification status. 636 */ setCallerNumberVerificationStatus( @erificationStatus int callerNumberVerificationStatus)637 public void setCallerNumberVerificationStatus( 638 @VerificationStatus int callerNumberVerificationStatus) { 639 mCallerNumberVerificationStatus = callerNumberVerificationStatus; 640 } 641 642 /** 643 * Gets the verification status for the phone number of an incoming call as identified in 644 * ATIS-1000082. 645 * @return the verification status. 646 */ getCallerNumberVerificationStatus()647 public @VerificationStatus int getCallerNumberVerificationStatus() { 648 return mCallerNumberVerificationStatus; 649 } 650 651 @NonNull 652 @Override toString()653 public String toString() { 654 return "{ serviceType=" + mServiceType 655 + ", callType=" + mCallType 656 + ", restrictCause=" + mRestrictCause 657 + ", mediaProfile=" + (mMediaProfile != null ? mMediaProfile.toString() : "null") 658 + ", emergencyServiceCategories=" + mEmergencyServiceCategories 659 + ", emergencyUrns=" + mEmergencyUrns 660 + ", emergencyCallRouting=" + mEmergencyCallRouting 661 + ", emergencyCallTesting=" + mEmergencyCallTesting 662 + ", hasKnownUserIntentEmergency=" + mHasKnownUserIntentEmergency 663 + ", mRestrictCause=" + mRestrictCause 664 + ", mCallerNumberVerstat= " + mCallerNumberVerificationStatus + " }"; 665 } 666 667 @Override describeContents()668 public int describeContents() { 669 return 0; 670 } 671 672 @Override writeToParcel(Parcel out, int flags)673 public void writeToParcel(Parcel out, int flags) { 674 Bundle filteredExtras = maybeCleanseExtras(mCallExtras); 675 out.writeInt(mServiceType); 676 out.writeInt(mCallType); 677 out.writeBundle(filteredExtras); 678 out.writeParcelable(mMediaProfile, 0); 679 out.writeInt(mEmergencyServiceCategories); 680 out.writeStringList(mEmergencyUrns); 681 out.writeInt(mEmergencyCallRouting); 682 out.writeBoolean(mEmergencyCallTesting); 683 out.writeBoolean(mHasKnownUserIntentEmergency); 684 out.writeInt(mRestrictCause); 685 out.writeInt(mCallerNumberVerificationStatus); 686 } 687 readFromParcel(Parcel in)688 private void readFromParcel(Parcel in) { 689 mServiceType = in.readInt(); 690 mCallType = in.readInt(); 691 mCallExtras = in.readBundle(); 692 mMediaProfile = in.readParcelable(ImsStreamMediaProfile.class.getClassLoader()); 693 mEmergencyServiceCategories = in.readInt(); 694 mEmergencyUrns = in.createStringArrayList(); 695 mEmergencyCallRouting = in.readInt(); 696 mEmergencyCallTesting = in.readBoolean(); 697 mHasKnownUserIntentEmergency = in.readBoolean(); 698 mRestrictCause = in.readInt(); 699 mCallerNumberVerificationStatus = in.readInt(); 700 } 701 702 public static final @android.annotation.NonNull Creator<ImsCallProfile> CREATOR = new Creator<ImsCallProfile>() { 703 @Override 704 public ImsCallProfile createFromParcel(Parcel in) { 705 return new ImsCallProfile(in); 706 } 707 708 @Override 709 public ImsCallProfile[] newArray(int size) { 710 return new ImsCallProfile[size]; 711 } 712 }; 713 getServiceType()714 public int getServiceType() { 715 return mServiceType; 716 } 717 getCallType()718 public int getCallType() { 719 return mCallType; 720 } 721 722 /** 723 * @return The call restrict cause, which provides the reason why a call has been restricted 724 * from using High Definition media. 725 */ getRestrictCause()726 public @CallRestrictCause int getRestrictCause() { 727 return mRestrictCause; 728 } 729 getCallExtras()730 public Bundle getCallExtras() { 731 return mCallExtras; 732 } 733 734 /** 735 * Get the proprietary extras set for this ImsCallProfile. 736 * @return A {@link Bundle} containing proprietary call extras that were not set by the 737 * platform. 738 */ getProprietaryCallExtras()739 public @NonNull Bundle getProprietaryCallExtras() { 740 if (mCallExtras == null) { 741 return new Bundle(); 742 } 743 Bundle proprietaryExtras = mCallExtras.getBundle(EXTRA_OEM_EXTRAS); 744 if (proprietaryExtras == null) { 745 return new Bundle(); 746 } 747 // Make a copy so users do not accidentally change this copy of the extras. 748 return new Bundle(proprietaryExtras); 749 } 750 getMediaProfile()751 public ImsStreamMediaProfile getMediaProfile() { 752 return mMediaProfile; 753 } 754 755 /** 756 * Converts from the call types defined in {@link ImsCallProfile} to the 757 * video state values defined in {@link VideoProfile}. 758 * 759 * @param callProfile The call profile. 760 * @return The video state. 761 */ getVideoStateFromImsCallProfile(ImsCallProfile callProfile)762 public static int getVideoStateFromImsCallProfile(ImsCallProfile callProfile) { 763 int videostate = getVideoStateFromCallType(callProfile.mCallType); 764 if (callProfile.isVideoPaused() && !VideoProfile.isAudioOnly(videostate)) { 765 videostate |= VideoProfile.STATE_PAUSED; 766 } else { 767 videostate &= ~VideoProfile.STATE_PAUSED; 768 } 769 return videostate; 770 } 771 772 /** 773 * Translates a {@link ImsCallProfile} {@code CALL_TYPE_*} constant into a video state. 774 * @param callType The call type. 775 * @return The video state. 776 */ getVideoStateFromCallType(int callType)777 public static int getVideoStateFromCallType(int callType) { 778 int videostate = VideoProfile.STATE_AUDIO_ONLY; 779 switch (callType) { 780 case CALL_TYPE_VT_TX: 781 videostate = VideoProfile.STATE_TX_ENABLED; 782 break; 783 case CALL_TYPE_VT_RX: 784 videostate = VideoProfile.STATE_RX_ENABLED; 785 break; 786 case CALL_TYPE_VT: 787 videostate = VideoProfile.STATE_BIDIRECTIONAL; 788 break; 789 case CALL_TYPE_VOICE: 790 videostate = VideoProfile.STATE_AUDIO_ONLY; 791 break; 792 default: 793 videostate = VideoProfile.STATE_AUDIO_ONLY; 794 break; 795 } 796 return videostate; 797 } 798 799 /** 800 * Converts from the video state values defined in {@link VideoProfile} 801 * to the call types defined in {@link ImsCallProfile}. 802 * 803 * @param videoState The video state. 804 * @return The call type. 805 */ getCallTypeFromVideoState(int videoState)806 public static int getCallTypeFromVideoState(int videoState) { 807 boolean videoTx = isVideoStateSet(videoState, VideoProfile.STATE_TX_ENABLED); 808 boolean videoRx = isVideoStateSet(videoState, VideoProfile.STATE_RX_ENABLED); 809 boolean isPaused = isVideoStateSet(videoState, VideoProfile.STATE_PAUSED); 810 if (isPaused) { 811 return ImsCallProfile.CALL_TYPE_VT_NODIR; 812 } else if (videoTx && !videoRx) { 813 return ImsCallProfile.CALL_TYPE_VT_TX; 814 } else if (!videoTx && videoRx) { 815 return ImsCallProfile.CALL_TYPE_VT_RX; 816 } else if (videoTx && videoRx) { 817 return ImsCallProfile.CALL_TYPE_VT; 818 } 819 return ImsCallProfile.CALL_TYPE_VOICE; 820 } 821 822 /** 823 * Badly named old method, kept for compatibility. 824 * See {@link #presentationToOir(int)}. 825 * @hide 826 */ 827 @UnsupportedAppUsage presentationToOIR(int presentation)828 public static int presentationToOIR(int presentation) { 829 switch (presentation) { 830 case PhoneConstants.PRESENTATION_RESTRICTED: 831 return ImsCallProfile.OIR_PRESENTATION_RESTRICTED; 832 case PhoneConstants.PRESENTATION_ALLOWED: 833 return ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED; 834 case PhoneConstants.PRESENTATION_PAYPHONE: 835 return ImsCallProfile.OIR_PRESENTATION_PAYPHONE; 836 case PhoneConstants.PRESENTATION_UNKNOWN: 837 return ImsCallProfile.OIR_PRESENTATION_UNKNOWN; 838 default: 839 return ImsCallProfile.OIR_DEFAULT; 840 } 841 } 842 843 /** 844 * Translate presentation value to OIR value 845 * @param presentation 846 * @return OIR values 847 */ presentationToOir(int presentation)848 public static int presentationToOir(int presentation) { 849 return presentationToOIR(presentation); 850 } 851 852 /** 853 * Translate OIR value to presentation value 854 * @param oir value 855 * @return presentation value 856 * @hide 857 */ OIRToPresentation(int oir)858 public static int OIRToPresentation(int oir) { 859 switch(oir) { 860 case ImsCallProfile.OIR_PRESENTATION_RESTRICTED: 861 return PhoneConstants.PRESENTATION_RESTRICTED; 862 case ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED: 863 return PhoneConstants.PRESENTATION_ALLOWED; 864 case ImsCallProfile.OIR_PRESENTATION_PAYPHONE: 865 return PhoneConstants.PRESENTATION_PAYPHONE; 866 case ImsCallProfile.OIR_PRESENTATION_UNKNOWN: 867 return PhoneConstants.PRESENTATION_UNKNOWN; 868 default: 869 return PhoneConstants.PRESENTATION_UNKNOWN; 870 } 871 } 872 873 /** 874 * Checks if video call is paused 875 * @return true if call is video paused 876 */ isVideoPaused()877 public boolean isVideoPaused() { 878 return mMediaProfile.mVideoDirection == ImsStreamMediaProfile.DIRECTION_INACTIVE; 879 } 880 881 /** 882 * Determines if the {@link ImsCallProfile} represents a video call. 883 * 884 * @return {@code true} if the profile is for a video call, {@code false} otherwise. 885 */ isVideoCall()886 public boolean isVideoCall() { 887 return VideoProfile.isVideo(getVideoStateFromCallType(mCallType)); 888 } 889 890 /** 891 * Cleanses a {@link Bundle} to ensure that it contains only data of type: 892 * 1. Primitive data types (e.g. int, bool, and other values determined by 893 * {@link android.os.PersistableBundle#isValidType(Object)}). 894 * 2. Other Bundles. 895 * 3. {@link Parcelable} objects in the {@code android.*} namespace. 896 * @param extras the source {@link Bundle} 897 * @return where all elements are valid types the source {@link Bundle} is returned unmodified, 898 * otherwise a copy of the {@link Bundle} with the invalid elements is returned. 899 */ maybeCleanseExtras(Bundle extras)900 private Bundle maybeCleanseExtras(Bundle extras) { 901 if (extras == null) { 902 return null; 903 } 904 905 int startSize = extras.size(); 906 Bundle filtered = TelephonyUtils.filterValues(extras); 907 int endSize = filtered.size(); 908 if (startSize != endSize) { 909 Log.i(TAG, "maybeCleanseExtras: " + (startSize - endSize) + " extra values were " 910 + "removed - only primitive types and system parcelables are permitted."); 911 } 912 return filtered; 913 } 914 915 /** 916 * Determines if a video state is set in a video state bit-mask. 917 * 918 * @param videoState The video state bit mask. 919 * @param videoStateToCheck The particular video state to check. 920 * @return True if the video state is set in the bit-mask. 921 */ isVideoStateSet(int videoState, int videoStateToCheck)922 private static boolean isVideoStateSet(int videoState, int videoStateToCheck) { 923 return (videoState & videoStateToCheck) == videoStateToCheck; 924 } 925 926 /** 927 * Set the emergency number information. The set value is valid 928 * only if {@link #getServiceType} returns {@link #SERVICE_TYPE_EMERGENCY} 929 * 930 * Reference: 3gpp 23.167, Section 6 - Functional description; 931 * 3gpp 24.503, Section 5.1.6.8.1 - General; 932 * 3gpp 22.101, Section 10 - Emergency Calls. 933 * 934 * @hide 935 */ setEmergencyCallInfo(EmergencyNumber num, boolean hasKnownUserIntentEmergency)936 public void setEmergencyCallInfo(EmergencyNumber num, boolean hasKnownUserIntentEmergency) { 937 setEmergencyServiceCategories(num.getEmergencyServiceCategoryBitmaskInternalDial()); 938 setEmergencyUrns(num.getEmergencyUrns()); 939 setEmergencyCallRouting(num.getEmergencyCallRouting()); 940 setEmergencyCallTesting(num.getEmergencyNumberSourceBitmask() 941 == EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST); 942 setHasKnownUserIntentEmergency(hasKnownUserIntentEmergency); 943 } 944 945 /** 946 * Set the emergency service categories. The set value is valid only if 947 * {@link #getServiceType} returns {@link #SERVICE_TYPE_EMERGENCY} 948 * 949 * If valid, the value is the bitwise-OR combination of the following constants: 950 * <ol> 951 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} </li> 952 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_POLICE} </li> 953 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AMBULANCE} </li> 954 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE} </li> 955 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD} </li> 956 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE} </li> 957 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MIEC} </li> 958 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AIEC} </li> 959 * </ol> 960 * 961 * Reference: 3gpp 23.167, Section 6 - Functional description; 962 * 3gpp 22.101, Section 10 - Emergency Calls. 963 */ 964 @VisibleForTesting setEmergencyServiceCategories( @mergencyServiceCategories int emergencyServiceCategories)965 public void setEmergencyServiceCategories( 966 @EmergencyServiceCategories int emergencyServiceCategories) { 967 mEmergencyServiceCategories = emergencyServiceCategories; 968 } 969 970 /** 971 * Set the emergency Uniform Resource Names (URN), only valid if {@link #getServiceType} 972 * returns {@link #SERVICE_TYPE_EMERGENCY}. 973 * 974 * Reference: 3gpp 24.503, Section 5.1.6.8.1 - General; 975 * 3gpp 22.101, Section 10 - Emergency Calls. 976 */ 977 @VisibleForTesting setEmergencyUrns(@onNull List<String> emergencyUrns)978 public void setEmergencyUrns(@NonNull List<String> emergencyUrns) { 979 mEmergencyUrns = emergencyUrns; 980 } 981 982 /** 983 * Set the emergency call routing, only valid if {@link #getServiceType} returns 984 * {@link #SERVICE_TYPE_EMERGENCY} 985 * 986 * If valid, the value is any of the following constants: 987 * <ol> 988 * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_UNKNOWN} </li> 989 * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_NORMAL} </li> 990 * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_EMERGENCY} </li> 991 * </ol> 992 */ 993 @VisibleForTesting setEmergencyCallRouting(@mergencyCallRouting int emergencyCallRouting)994 public void setEmergencyCallRouting(@EmergencyCallRouting int emergencyCallRouting) { 995 mEmergencyCallRouting = emergencyCallRouting; 996 } 997 998 /** 999 * Set if this is for testing emergency call, only valid if {@link #getServiceType} returns 1000 * {@link #SERVICE_TYPE_EMERGENCY}. 1001 */ 1002 @VisibleForTesting setEmergencyCallTesting(boolean isTesting)1003 public void setEmergencyCallTesting(boolean isTesting) { 1004 mEmergencyCallTesting = isTesting; 1005 } 1006 1007 /** 1008 * Set if we have known the user intent of the call is emergency. 1009 * 1010 * This is only used to specify when the dialed number is ambiguous when it can be identified 1011 * as both emergency number and any other non-emergency number; e.g. in some situation, 611 1012 * could be both an emergency number in a country and a non-emergency number of a carrier's 1013 * customer service hotline. 1014 */ 1015 @VisibleForTesting setHasKnownUserIntentEmergency(boolean hasKnownUserIntentEmergency)1016 public void setHasKnownUserIntentEmergency(boolean hasKnownUserIntentEmergency) { 1017 mHasKnownUserIntentEmergency = hasKnownUserIntentEmergency; 1018 } 1019 1020 /** 1021 * Get the emergency service categories, only valid if {@link #getServiceType} returns 1022 * {@link #SERVICE_TYPE_EMERGENCY} 1023 * 1024 * @return the emergency service categories, 1025 * 1026 * If valid, the value is the bitwise-OR combination of the following constants: 1027 * <ol> 1028 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} </li> 1029 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_POLICE} </li> 1030 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AMBULANCE} </li> 1031 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE} </li> 1032 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD} </li> 1033 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE} </li> 1034 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MIEC} </li> 1035 * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AIEC} </li> 1036 * </ol> 1037 * 1038 * Reference: 3gpp 23.167, Section 6 - Functional description; 1039 * 3gpp 22.101, Section 10 - Emergency Calls. 1040 */ getEmergencyServiceCategories()1041 public @EmergencyServiceCategories int getEmergencyServiceCategories() { 1042 return mEmergencyServiceCategories; 1043 } 1044 1045 /** 1046 * Get the emergency Uniform Resource Names (URN), only valid if {@link #getServiceType} 1047 * returns {@link #SERVICE_TYPE_EMERGENCY}. 1048 * 1049 * Reference: 3gpp 24.503, Section 5.1.6.8.1 - General; 1050 * 3gpp 22.101, Section 10 - Emergency Calls. 1051 */ getEmergencyUrns()1052 public @NonNull List<String> getEmergencyUrns() { 1053 return mEmergencyUrns; 1054 } 1055 1056 /** 1057 * Get the emergency call routing, only valid if {@link #getServiceType} returns 1058 * {@link #SERVICE_TYPE_EMERGENCY} 1059 * 1060 * If valid, the value is any of the following constants: 1061 * <ol> 1062 * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_UNKNOWN} </li> 1063 * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_NORMAL} </li> 1064 * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_EMERGENCY} </li> 1065 * </ol> 1066 */ getEmergencyCallRouting()1067 public @EmergencyCallRouting int getEmergencyCallRouting() { 1068 return mEmergencyCallRouting; 1069 } 1070 1071 /** 1072 * Get if the emergency call is for testing purpose. 1073 */ isEmergencyCallTesting()1074 public boolean isEmergencyCallTesting() { 1075 return mEmergencyCallTesting; 1076 } 1077 1078 /** 1079 * Checks if we have known the user intent of the call is emergency. 1080 * 1081 * This is only used to specify when the dialed number is ambiguous when it can be identified 1082 * as both emergency number and any other non-emergency number; e.g. in some situation, 611 1083 * could be both an emergency number in a country and a non-emergency number of a carrier's 1084 * customer service hotline. 1085 */ hasKnownUserIntentEmergency()1086 public boolean hasKnownUserIntentEmergency() { 1087 return mHasKnownUserIntentEmergency; 1088 } 1089 } 1090