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