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.SystemApi; 20 import android.os.Bundle; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.os.PersistableBundle; 24 import android.telecom.VideoProfile; 25 import android.util.Log; 26 27 import com.android.internal.telephony.PhoneConstants; 28 29 /** 30 * Parcelable object to handle IMS call profile. 31 * It is created from GSMA IR.92/IR.94, 3GPP TS 24.229/TS 26.114/TS26.111. 32 * It provides the service and call type, the additional information related to the call. 33 * 34 * @hide 35 */ 36 @SystemApi 37 public final class ImsCallProfile implements Parcelable { 38 private static final String TAG = "ImsCallProfile"; 39 40 /** 41 * Service types 42 */ 43 /** 44 * It is for a special case. It helps that the application can make a call 45 * without IMS connection (not registered). 46 * In the moment of the call initiation, the device try to connect to the IMS network 47 * and initiates the call. 48 */ 49 public static final int SERVICE_TYPE_NONE = 0; 50 /** 51 * It is a default type and can be selected when the device is connected to the IMS network. 52 */ 53 public static final int SERVICE_TYPE_NORMAL = 1; 54 /** 55 * It is for an emergency call. 56 */ 57 public static final int SERVICE_TYPE_EMERGENCY = 2; 58 59 /** 60 * Call types 61 */ 62 /** 63 * IMSPhone to support IR.92 & IR.94 (voice + video upgrade/downgrade) 64 */ 65 public static final int CALL_TYPE_VOICE_N_VIDEO = 1; 66 /** 67 * IR.92 (Voice only) 68 */ 69 public static final int CALL_TYPE_VOICE = 2; 70 /** 71 * VT to support IR.92 & IR.94 (voice + video upgrade/downgrade) 72 */ 73 public static final int CALL_TYPE_VIDEO_N_VOICE = 3; 74 /** 75 * Video Telephony (audio / video two way) 76 */ 77 public static final int CALL_TYPE_VT = 4; 78 /** 79 * Video Telephony (audio two way / video TX one way) 80 */ 81 public static final int CALL_TYPE_VT_TX = 5; 82 /** 83 * Video Telephony (audio two way / video RX one way) 84 */ 85 public static final int CALL_TYPE_VT_RX = 6; 86 /** 87 * Video Telephony (audio two way / video inactive) 88 */ 89 public static final int CALL_TYPE_VT_NODIR = 7; 90 /** 91 * VideoShare (video two way) 92 */ 93 public static final int CALL_TYPE_VS = 8; 94 /** 95 * VideoShare (video TX one way) 96 */ 97 public static final int CALL_TYPE_VS_TX = 9; 98 /** 99 * VideoShare (video RX one way) 100 */ 101 public static final int CALL_TYPE_VS_RX = 10; 102 103 /** 104 * Extra properties for IMS call. 105 */ 106 /** 107 * Boolean extra properties - "true" / "false" 108 * conference : Indicates if the session is for the conference call or not. 109 * e_call : Indicates if the session is for the emergency call or not. 110 * vms : Indicates if the session is connected to the voice mail system or not. 111 * call_mode_changeable : Indicates if the session is able to upgrade/downgrade 112 * the video during voice call. 113 * conference_avail : Indicates if the session can be extended to the conference. 114 */ 115 /** 116 * @hide 117 */ 118 public static final String EXTRA_CONFERENCE = "conference"; 119 /** 120 * @hide 121 */ 122 public static final String EXTRA_E_CALL = "e_call"; 123 /** 124 * @hide 125 */ 126 public static final String EXTRA_VMS = "vms"; 127 /** 128 * @hide 129 */ 130 public static final String EXTRA_CALL_MODE_CHANGEABLE = "call_mode_changeable"; 131 /** 132 * @hide 133 */ 134 public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail"; 135 136 // Extra string for internal use only. OEMs should not use 137 // this for packing extras. 138 /** 139 * @hide 140 */ 141 public static final String EXTRA_OEM_EXTRAS = "OemCallExtras"; 142 143 /** 144 * Rule for originating identity (number) presentation, MO/MT. 145 * {@link ImsCallProfile#OIR_DEFAULT} 146 * {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED} 147 * {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED} 148 */ 149 public static final String EXTRA_OIR = "oir"; 150 /** 151 * Rule for calling name presentation 152 * {@link ImsCallProfile#OIR_DEFAULT} 153 * {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED} 154 * {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED} 155 */ 156 public static final String EXTRA_CNAP = "cnap"; 157 /** 158 * To identify the Ims call type, MO 159 * {@link ImsCallProfile#DIALSTRING_NORMAL} 160 * {@link ImsCallProfile#DIALSTRING_SS_CONF} 161 * {@link ImsCallProfile#DIALSTRING_USSD} 162 */ 163 public static final String EXTRA_DIALSTRING = "dialstring"; 164 165 /** 166 * Values for EXTRA_OIR / EXTRA_CNAP 167 */ 168 /** 169 * Default presentation for Originating Identity. 170 */ 171 public static final int OIR_DEFAULT = 0; // "user subscription default value" 172 /** 173 * Restricted presentation for Originating Identity. 174 */ 175 public static final int OIR_PRESENTATION_RESTRICTED = 1; 176 /** 177 * Not restricted presentation for Originating Identity. 178 */ 179 public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2; 180 /** 181 * Presentation unknown for Originating Identity. 182 */ 183 public static final int OIR_PRESENTATION_UNKNOWN = 3; 184 /** 185 * Payphone presentation for Originating Identity. 186 */ 187 public static final int OIR_PRESENTATION_PAYPHONE = 4; 188 189 //Values for EXTRA_DIALSTRING 190 /** 191 * A default or normal normal call. 192 */ 193 public static final int DIALSTRING_NORMAL = 0; 194 /** 195 * Call for SIP-based user configuration 196 */ 197 public static final int DIALSTRING_SS_CONF = 1; 198 /** 199 * Call for USSD message 200 */ 201 public static final int DIALSTRING_USSD = 2; 202 203 /** 204 * Values for causes that restrict call types 205 */ 206 // Default cause not restricted at peer and HD is supported 207 public static final int CALL_RESTRICT_CAUSE_NONE = 0; 208 // Service not supported by RAT at peer 209 public static final int CALL_RESTRICT_CAUSE_RAT = 1; 210 // Service Disabled at peer 211 public static final int CALL_RESTRICT_CAUSE_DISABLED = 2; 212 // HD is not supported 213 public static final int CALL_RESTRICT_CAUSE_HD = 3; 214 215 /** 216 * String extra properties 217 * oi : Originating identity (number), MT only 218 * cna : Calling name 219 * ussd : For network-initiated USSD, MT only 220 * remote_uri : Connected user identity (it can be used for the conference) 221 * ChildNum: Child number info. 222 * Codec: Codec info. 223 * DisplayText: Display text for the call. 224 * AdditionalCallInfo: Additional call info. 225 * CallPull: Boolean value specifying if the call is a pulled call. 226 */ 227 public static final String EXTRA_OI = "oi"; 228 public static final String EXTRA_CNA = "cna"; 229 public static final String EXTRA_USSD = "ussd"; 230 public static final String EXTRA_REMOTE_URI = "remote_uri"; 231 public static final String EXTRA_CHILD_NUMBER = "ChildNum"; 232 public static final String EXTRA_CODEC = "Codec"; 233 public static final String EXTRA_DISPLAY_TEXT = "DisplayText"; 234 public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo"; 235 public static final String EXTRA_IS_CALL_PULL = "CallPull"; 236 237 /** 238 * Extra key which the RIL can use to indicate the radio technology used for a call. 239 * Valid values are: 240 * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}, 241 * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_IWLAN}, and the other defined 242 * {@code RIL_RADIO_TECHNOLOGY_*} constants. 243 * Note: Despite the fact the {@link android.telephony.ServiceState} values are integer 244 * constants, the values passed for the {@link #EXTRA_CALL_RAT_TYPE} should be strings (e.g. 245 * "14" vs (int) 14). 246 * Note: This is used by {@link com.android.internal.telephony.imsphone.ImsPhoneConnection# 247 * updateWifiStateFromExtras(Bundle)} to determine whether to set the 248 * {@link android.telecom.Connection#PROPERTY_WIFI} property on a connection. 249 */ 250 public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech"; 251 252 /** 253 * Similar to {@link #EXTRA_CALL_RAT_TYPE}, except with a lowercase 'c'. Used to ensure 254 * compatibility with modems that are non-compliant with the {@link #EXTRA_CALL_RAT_TYPE} 255 * extra key. Should be removed when the non-compliant modems are fixed. 256 * @hide 257 */ 258 public static final String EXTRA_CALL_RAT_TYPE_ALT = "callRadioTech"; 259 260 /** @hide */ 261 public int mServiceType; 262 /** @hide */ 263 public int mCallType; 264 /** @hide */ 265 public int mRestrictCause = CALL_RESTRICT_CAUSE_NONE; 266 267 /** 268 * Extras associated with this {@link ImsCallProfile}. 269 * <p> 270 * Valid data types include: 271 * <ul> 272 * <li>{@link Integer} (and int)</li> 273 * <li>{@link Long} (and long)</li> 274 * <li>{@link Double} (and double)</li> 275 * <li>{@link String}</li> 276 * <li>{@code int[]}</li> 277 * <li>{@code long[]}</li> 278 * <li>{@code double[]}</li> 279 * <li>{@code String[]}</li> 280 * <li>{@link PersistableBundle}</li> 281 * <li>{@link Boolean} (and boolean)</li> 282 * <li>{@code boolean[]}</li> 283 * <li>Other {@link Parcelable} classes in the {@code android.*} namespace.</li> 284 * </ul> 285 * <p> 286 * Invalid types will be removed when the {@link ImsCallProfile} is parceled for transmit across 287 * a {@link android.os.Binder}. 288 */ 289 /** @hide */ 290 public Bundle mCallExtras; 291 /** @hide */ 292 public ImsStreamMediaProfile mMediaProfile; 293 294 /** @hide */ ImsCallProfile(Parcel in)295 public ImsCallProfile(Parcel in) { 296 readFromParcel(in); 297 } 298 299 /** 300 * Default Constructor that initializes the call profile with service type 301 * {@link #SERVICE_TYPE_NORMAL} and call type {@link #CALL_TYPE_VIDEO_N_VOICE} 302 */ ImsCallProfile()303 public ImsCallProfile() { 304 mServiceType = SERVICE_TYPE_NORMAL; 305 mCallType = CALL_TYPE_VOICE_N_VIDEO; 306 mCallExtras = new Bundle(); 307 mMediaProfile = new ImsStreamMediaProfile(); 308 } 309 310 /** 311 * Constructor. 312 * 313 * @param serviceType the service type for the call. Can be one of the following: 314 * {@link #SERVICE_TYPE_NONE}, 315 * {@link #SERVICE_TYPE_NORMAL}, 316 * {@link #SERVICE_TYPE_EMERGENCY} 317 * @param callType the call type. Can be one of the following: 318 * {@link #CALL_TYPE_VOICE_N_VIDEO}, 319 * {@link #CALL_TYPE_VOICE}, 320 * {@link #CALL_TYPE_VIDEO_N_VOICE}, 321 * {@link #CALL_TYPE_VT}, 322 * {@link #CALL_TYPE_VT_TX}, 323 * {@link #CALL_TYPE_VT_RX}, 324 * {@link #CALL_TYPE_VT_NODIR}, 325 * {@link #CALL_TYPE_VS}, 326 * {@link #CALL_TYPE_VS_TX}, 327 * {@link #CALL_TYPE_VS_RX} 328 */ ImsCallProfile(int serviceType, int callType)329 public ImsCallProfile(int serviceType, int callType) { 330 mServiceType = serviceType; 331 mCallType = callType; 332 mCallExtras = new Bundle(); 333 mMediaProfile = new ImsStreamMediaProfile(); 334 } 335 336 /** 337 * Constructor. 338 * 339 * @param serviceType the service type for the call. Can be one of the following: 340 * {@link #SERVICE_TYPE_NONE}, 341 * {@link #SERVICE_TYPE_NORMAL}, 342 * {@link #SERVICE_TYPE_EMERGENCY} 343 * @param callType the call type. Can be one of the following: 344 * {@link #CALL_TYPE_VOICE_N_VIDEO}, 345 * {@link #CALL_TYPE_VOICE}, 346 * {@link #CALL_TYPE_VIDEO_N_VOICE}, 347 * {@link #CALL_TYPE_VT}, 348 * {@link #CALL_TYPE_VT_TX}, 349 * {@link #CALL_TYPE_VT_RX}, 350 * {@link #CALL_TYPE_VT_NODIR}, 351 * {@link #CALL_TYPE_VS}, 352 * {@link #CALL_TYPE_VS_TX}, 353 * {@link #CALL_TYPE_VS_RX} 354 * @param callExtras A bundle with the call extras. 355 * @param mediaProfile The IMS stream media profile. 356 */ ImsCallProfile(int serviceType, int callType, Bundle callExtras, ImsStreamMediaProfile mediaProfile)357 public ImsCallProfile(int serviceType, int callType, Bundle callExtras, 358 ImsStreamMediaProfile mediaProfile) { 359 mServiceType = serviceType; 360 mCallType = callType; 361 mCallExtras = callExtras; 362 mMediaProfile = mediaProfile; 363 } 364 getCallExtra(String name)365 public String getCallExtra(String name) { 366 return getCallExtra(name, ""); 367 } 368 getCallExtra(String name, String defaultValue)369 public String getCallExtra(String name, String defaultValue) { 370 if (mCallExtras == null) { 371 return defaultValue; 372 } 373 374 return mCallExtras.getString(name, defaultValue); 375 } 376 getCallExtraBoolean(String name)377 public boolean getCallExtraBoolean(String name) { 378 return getCallExtraBoolean(name, false); 379 } 380 getCallExtraBoolean(String name, boolean defaultValue)381 public boolean getCallExtraBoolean(String name, boolean defaultValue) { 382 if (mCallExtras == null) { 383 return defaultValue; 384 } 385 386 return mCallExtras.getBoolean(name, defaultValue); 387 } 388 getCallExtraInt(String name)389 public int getCallExtraInt(String name) { 390 return getCallExtraInt(name, -1); 391 } 392 getCallExtraInt(String name, int defaultValue)393 public int getCallExtraInt(String name, int defaultValue) { 394 if (mCallExtras == null) { 395 return defaultValue; 396 } 397 398 return mCallExtras.getInt(name, defaultValue); 399 } 400 setCallExtra(String name, String value)401 public void setCallExtra(String name, String value) { 402 if (mCallExtras != null) { 403 mCallExtras.putString(name, value); 404 } 405 } 406 setCallExtraBoolean(String name, boolean value)407 public void setCallExtraBoolean(String name, boolean value) { 408 if (mCallExtras != null) { 409 mCallExtras.putBoolean(name, value); 410 } 411 } 412 setCallExtraInt(String name, int value)413 public void setCallExtraInt(String name, int value) { 414 if (mCallExtras != null) { 415 mCallExtras.putInt(name, value); 416 } 417 } 418 updateCallType(ImsCallProfile profile)419 public void updateCallType(ImsCallProfile profile) { 420 mCallType = profile.mCallType; 421 } 422 updateCallExtras(ImsCallProfile profile)423 public void updateCallExtras(ImsCallProfile profile) { 424 mCallExtras.clear(); 425 mCallExtras = (Bundle) profile.mCallExtras.clone(); 426 } 427 428 /** 429 * Updates the media profile for the call. 430 * 431 * @param profile Call profile with new media profile. 432 */ updateMediaProfile(ImsCallProfile profile)433 public void updateMediaProfile(ImsCallProfile profile) { 434 mMediaProfile = profile.mMediaProfile; 435 } 436 437 438 @Override toString()439 public String toString() { 440 return "{ serviceType=" + mServiceType + 441 ", callType=" + mCallType + 442 ", restrictCause=" + mRestrictCause + 443 ", mediaProfile=" + mMediaProfile.toString() + " }"; 444 } 445 446 @Override describeContents()447 public int describeContents() { 448 return 0; 449 } 450 451 @Override writeToParcel(Parcel out, int flags)452 public void writeToParcel(Parcel out, int flags) { 453 Bundle filteredExtras = maybeCleanseExtras(mCallExtras); 454 out.writeInt(mServiceType); 455 out.writeInt(mCallType); 456 out.writeBundle(filteredExtras); 457 out.writeParcelable(mMediaProfile, 0); 458 } 459 readFromParcel(Parcel in)460 private void readFromParcel(Parcel in) { 461 mServiceType = in.readInt(); 462 mCallType = in.readInt(); 463 mCallExtras = in.readBundle(); 464 mMediaProfile = in.readParcelable(ImsStreamMediaProfile.class.getClassLoader()); 465 } 466 467 public static final Creator<ImsCallProfile> CREATOR = new Creator<ImsCallProfile>() { 468 @Override 469 public ImsCallProfile createFromParcel(Parcel in) { 470 return new ImsCallProfile(in); 471 } 472 473 @Override 474 public ImsCallProfile[] newArray(int size) { 475 return new ImsCallProfile[size]; 476 } 477 }; 478 getServiceType()479 public int getServiceType() { 480 return mServiceType; 481 } 482 getCallType()483 public int getCallType() { 484 return mCallType; 485 } 486 getRestrictCause()487 public int getRestrictCause() { 488 return mRestrictCause; 489 } 490 getCallExtras()491 public Bundle getCallExtras() { 492 return mCallExtras; 493 } 494 getMediaProfile()495 public ImsStreamMediaProfile getMediaProfile() { 496 return mMediaProfile; 497 } 498 499 /** 500 * Converts from the call types defined in {@link ImsCallProfile} to the 501 * video state values defined in {@link VideoProfile}. 502 * 503 * @param callProfile The call profile. 504 * @return The video state. 505 */ getVideoStateFromImsCallProfile(ImsCallProfile callProfile)506 public static int getVideoStateFromImsCallProfile(ImsCallProfile callProfile) { 507 int videostate = getVideoStateFromCallType(callProfile.mCallType); 508 if (callProfile.isVideoPaused() && !VideoProfile.isAudioOnly(videostate)) { 509 videostate |= VideoProfile.STATE_PAUSED; 510 } else { 511 videostate &= ~VideoProfile.STATE_PAUSED; 512 } 513 return videostate; 514 } 515 516 /** 517 * Translates a {@link ImsCallProfile} {@code CALL_TYPE_*} constant into a video state. 518 * @param callType The call type. 519 * @return The video state. 520 */ getVideoStateFromCallType(int callType)521 public static int getVideoStateFromCallType(int callType) { 522 int videostate = VideoProfile.STATE_AUDIO_ONLY; 523 switch (callType) { 524 case CALL_TYPE_VT_TX: 525 videostate = VideoProfile.STATE_TX_ENABLED; 526 break; 527 case CALL_TYPE_VT_RX: 528 videostate = VideoProfile.STATE_RX_ENABLED; 529 break; 530 case CALL_TYPE_VT: 531 videostate = VideoProfile.STATE_BIDIRECTIONAL; 532 break; 533 case CALL_TYPE_VOICE: 534 videostate = VideoProfile.STATE_AUDIO_ONLY; 535 break; 536 default: 537 videostate = VideoProfile.STATE_AUDIO_ONLY; 538 break; 539 } 540 return videostate; 541 } 542 543 /** 544 * Converts from the video state values defined in {@link VideoProfile} 545 * to the call types defined in {@link ImsCallProfile}. 546 * 547 * @param videoState The video state. 548 * @return The call type. 549 */ getCallTypeFromVideoState(int videoState)550 public static int getCallTypeFromVideoState(int videoState) { 551 boolean videoTx = isVideoStateSet(videoState, VideoProfile.STATE_TX_ENABLED); 552 boolean videoRx = isVideoStateSet(videoState, VideoProfile.STATE_RX_ENABLED); 553 boolean isPaused = isVideoStateSet(videoState, VideoProfile.STATE_PAUSED); 554 if (isPaused) { 555 return ImsCallProfile.CALL_TYPE_VT_NODIR; 556 } else if (videoTx && !videoRx) { 557 return ImsCallProfile.CALL_TYPE_VT_TX; 558 } else if (!videoTx && videoRx) { 559 return ImsCallProfile.CALL_TYPE_VT_RX; 560 } else if (videoTx && videoRx) { 561 return ImsCallProfile.CALL_TYPE_VT; 562 } 563 return ImsCallProfile.CALL_TYPE_VOICE; 564 } 565 566 /** 567 * Badly named old method, kept for compatibility. 568 * See {@link #presentationToOir(int)}. 569 * @hide 570 */ presentationToOIR(int presentation)571 public static int presentationToOIR(int presentation) { 572 switch (presentation) { 573 case PhoneConstants.PRESENTATION_RESTRICTED: 574 return ImsCallProfile.OIR_PRESENTATION_RESTRICTED; 575 case PhoneConstants.PRESENTATION_ALLOWED: 576 return ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED; 577 case PhoneConstants.PRESENTATION_PAYPHONE: 578 return ImsCallProfile.OIR_PRESENTATION_PAYPHONE; 579 case PhoneConstants.PRESENTATION_UNKNOWN: 580 return ImsCallProfile.OIR_PRESENTATION_UNKNOWN; 581 default: 582 return ImsCallProfile.OIR_DEFAULT; 583 } 584 } 585 586 /** 587 * Translate presentation value to OIR value 588 * @param presentation 589 * @return OIR values 590 */ presentationToOir(int presentation)591 public static int presentationToOir(int presentation) { 592 return presentationToOIR(presentation); 593 } 594 595 /** 596 * Translate OIR value to presentation value 597 * @param oir value 598 * @return presentation value 599 * @hide 600 */ OIRToPresentation(int oir)601 public static int OIRToPresentation(int oir) { 602 switch(oir) { 603 case ImsCallProfile.OIR_PRESENTATION_RESTRICTED: 604 return PhoneConstants.PRESENTATION_RESTRICTED; 605 case ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED: 606 return PhoneConstants.PRESENTATION_ALLOWED; 607 case ImsCallProfile.OIR_PRESENTATION_PAYPHONE: 608 return PhoneConstants.PRESENTATION_PAYPHONE; 609 case ImsCallProfile.OIR_PRESENTATION_UNKNOWN: 610 return PhoneConstants.PRESENTATION_UNKNOWN; 611 default: 612 return PhoneConstants.PRESENTATION_UNKNOWN; 613 } 614 } 615 616 /** 617 * Checks if video call is paused 618 * @return true if call is video paused 619 */ isVideoPaused()620 public boolean isVideoPaused() { 621 return mMediaProfile.mVideoDirection == ImsStreamMediaProfile.DIRECTION_INACTIVE; 622 } 623 624 /** 625 * Determines if the {@link ImsCallProfile} represents a video call. 626 * 627 * @return {@code true} if the profile is for a video call, {@code false} otherwise. 628 */ isVideoCall()629 public boolean isVideoCall() { 630 return VideoProfile.isVideo(getVideoStateFromCallType(mCallType)); 631 } 632 633 /** 634 * Cleanses a {@link Bundle} to ensure that it contains only data of type: 635 * 1. Primitive data types (e.g. int, bool, and other values determined by 636 * {@link android.os.PersistableBundle#isValidType(Object)}). 637 * 2. Other Bundles. 638 * 3. {@link Parcelable} objects in the {@code android.*} namespace. 639 * @param extras the source {@link Bundle} 640 * @return where all elements are valid types the source {@link Bundle} is returned unmodified, 641 * otherwise a copy of the {@link Bundle} with the invalid elements is returned. 642 */ maybeCleanseExtras(Bundle extras)643 private Bundle maybeCleanseExtras(Bundle extras) { 644 if (extras == null) { 645 return null; 646 } 647 648 int startSize = extras.size(); 649 Bundle filtered = extras.filterValues(); 650 int endSize = filtered.size(); 651 if (startSize != endSize) { 652 Log.i(TAG, "maybeCleanseExtras: " + (startSize - endSize) + " extra values were " 653 + "removed - only primitive types and system parcelables are permitted."); 654 } 655 return filtered; 656 } 657 658 /** 659 * Determines if a video state is set in a video state bit-mask. 660 * 661 * @param videoState The video state bit mask. 662 * @param videoStateToCheck The particular video state to check. 663 * @return True if the video state is set in the bit-mask. 664 */ isVideoStateSet(int videoState, int videoStateToCheck)665 private static boolean isVideoStateSet(int videoState, int videoStateToCheck) { 666 return (videoState & videoStateToCheck) == videoStateToCheck; 667 } 668 } 669