1 /* 2 * Copyright (C) 2006 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 com.android.internal.telephony; 18 19 import android.net.Uri; 20 import android.os.Bundle; 21 import android.os.SystemClock; 22 import android.telecom.ConferenceParticipant; 23 import android.telephony.DisconnectCause; 24 import android.telephony.Rlog; 25 import android.util.Log; 26 27 import java.lang.Override; 28 import java.util.ArrayList; 29 import java.util.List; 30 import java.util.Set; 31 import java.util.concurrent.CopyOnWriteArraySet; 32 33 /** 34 * {@hide} 35 */ 36 public abstract class Connection { 37 private static final String TAG = "Connection"; 38 39 public interface PostDialListener { onPostDialWait()40 void onPostDialWait(); onPostDialChar(char c)41 void onPostDialChar(char c); 42 } 43 44 /** 45 * Capabilities that will be mapped to telecom connection 46 * capabilities. 47 */ 48 public static class Capability { 49 50 /** 51 * For an IMS video call, indicates that the local side of the call supports downgrading 52 * from a video call to an audio-only call. 53 */ 54 public static final int SUPPORTS_DOWNGRADE_TO_VOICE_LOCAL = 0x00000001; 55 56 /** 57 * For an IMS video call, indicates that the peer supports downgrading to an audio-only 58 * call. 59 */ 60 public static final int SUPPORTS_DOWNGRADE_TO_VOICE_REMOTE = 0x00000002; 61 62 /** 63 * For an IMS call, indicates that the call supports video locally. 64 */ 65 public static final int SUPPORTS_VT_LOCAL_BIDIRECTIONAL = 0x00000004; 66 67 /** 68 * For an IMS call, indicates that the peer supports video. 69 */ 70 public static final int SUPPORTS_VT_REMOTE_BIDIRECTIONAL = 0x00000008; 71 72 /** 73 * Indicates that the connection is an external connection (e.g. an instance of the class 74 * {@link com.android.internal.telephony.imsphone.ImsExternalConnection}. 75 */ 76 public static final int IS_EXTERNAL_CONNECTION = 0x00000010; 77 78 /** 79 * Indicates that this external connection can be pulled from the remote device to the 80 * local device. 81 */ 82 public static final int IS_PULLABLE = 0x00000020; 83 } 84 85 /** 86 * Listener interface for events related to the connection which should be reported to the 87 * {@link android.telecom.Connection}. 88 */ 89 public interface Listener { onVideoStateChanged(int videoState)90 public void onVideoStateChanged(int videoState); onConnectionCapabilitiesChanged(int capability)91 public void onConnectionCapabilitiesChanged(int capability); onWifiChanged(boolean isWifi)92 public void onWifiChanged(boolean isWifi); onVideoProviderChanged( android.telecom.Connection.VideoProvider videoProvider)93 public void onVideoProviderChanged( 94 android.telecom.Connection.VideoProvider videoProvider); onAudioQualityChanged(int audioQuality)95 public void onAudioQualityChanged(int audioQuality); onConferenceParticipantsChanged(List<ConferenceParticipant> participants)96 public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants); onCallSubstateChanged(int callSubstate)97 public void onCallSubstateChanged(int callSubstate); onMultipartyStateChanged(boolean isMultiParty)98 public void onMultipartyStateChanged(boolean isMultiParty); onConferenceMergedFailed()99 public void onConferenceMergedFailed(); onExtrasChanged(Bundle extras)100 public void onExtrasChanged(Bundle extras); onExitedEcmMode()101 public void onExitedEcmMode(); onCallPullFailed(Connection externalConnection)102 public void onCallPullFailed(Connection externalConnection); onHandoverToWifiFailed()103 public void onHandoverToWifiFailed(); onConnectionEvent(String event, Bundle extras)104 public void onConnectionEvent(String event, Bundle extras); onRttModifyRequestReceived()105 public void onRttModifyRequestReceived(); onRttModifyResponseReceived(int status)106 public void onRttModifyResponseReceived(int status); onDisconnect(int cause)107 public void onDisconnect(int cause); onRttInitiated()108 public void onRttInitiated(); onRttTerminated()109 public void onRttTerminated(); 110 } 111 112 /** 113 * Base listener implementation. 114 */ 115 public abstract static class ListenerBase implements Listener { 116 @Override onVideoStateChanged(int videoState)117 public void onVideoStateChanged(int videoState) {} 118 @Override onConnectionCapabilitiesChanged(int capability)119 public void onConnectionCapabilitiesChanged(int capability) {} 120 @Override onWifiChanged(boolean isWifi)121 public void onWifiChanged(boolean isWifi) {} 122 @Override onVideoProviderChanged( android.telecom.Connection.VideoProvider videoProvider)123 public void onVideoProviderChanged( 124 android.telecom.Connection.VideoProvider videoProvider) {} 125 @Override onAudioQualityChanged(int audioQuality)126 public void onAudioQualityChanged(int audioQuality) {} 127 @Override onConferenceParticipantsChanged(List<ConferenceParticipant> participants)128 public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants) {} 129 @Override onCallSubstateChanged(int callSubstate)130 public void onCallSubstateChanged(int callSubstate) {} 131 @Override onMultipartyStateChanged(boolean isMultiParty)132 public void onMultipartyStateChanged(boolean isMultiParty) {} 133 @Override onConferenceMergedFailed()134 public void onConferenceMergedFailed() {} 135 @Override onExtrasChanged(Bundle extras)136 public void onExtrasChanged(Bundle extras) {} 137 @Override onExitedEcmMode()138 public void onExitedEcmMode() {} 139 @Override onCallPullFailed(Connection externalConnection)140 public void onCallPullFailed(Connection externalConnection) {} 141 @Override onHandoverToWifiFailed()142 public void onHandoverToWifiFailed() {} 143 @Override onConnectionEvent(String event, Bundle extras)144 public void onConnectionEvent(String event, Bundle extras) {} 145 @Override onRttModifyRequestReceived()146 public void onRttModifyRequestReceived() {} 147 @Override onRttModifyResponseReceived(int status)148 public void onRttModifyResponseReceived(int status) {} 149 @Override onDisconnect(int cause)150 public void onDisconnect(int cause) {} 151 @Override onRttInitiated()152 public void onRttInitiated() {} 153 @Override onRttTerminated()154 public void onRttTerminated() {} 155 } 156 157 public static final int AUDIO_QUALITY_STANDARD = 1; 158 public static final int AUDIO_QUALITY_HIGH_DEFINITION = 2; 159 160 /** 161 * The telecom internal call ID associated with this connection. Only to be used for debugging 162 * purposes. 163 */ 164 private String mTelecomCallId; 165 166 //Caller Name Display 167 protected String mCnapName; 168 protected int mCnapNamePresentation = PhoneConstants.PRESENTATION_ALLOWED; 169 protected String mAddress; // MAY BE NULL!!! 170 protected String mDialString; // outgoing calls only 171 protected int mNumberPresentation = PhoneConstants.PRESENTATION_ALLOWED; 172 protected boolean mIsIncoming; 173 /* 174 * These time/timespan values are based on System.currentTimeMillis(), 175 * i.e., "wall clock" time. 176 */ 177 protected long mCreateTime; 178 protected long mConnectTime; 179 /* 180 * These time/timespan values are based on SystemClock.elapsedRealTime(), 181 * i.e., time since boot. They are appropriate for comparison and 182 * calculating deltas. 183 */ 184 protected long mConnectTimeReal; 185 protected long mDuration; 186 protected long mHoldingStartTime; // The time when the Connection last transitioned 187 // into HOLDING 188 protected Connection mOrigConnection; 189 private List<PostDialListener> mPostDialListeners = new ArrayList<>(); 190 public Set<Listener> mListeners = new CopyOnWriteArraySet<>(); 191 192 protected boolean mNumberConverted = false; 193 protected String mConvertedNumber; 194 195 protected String mPostDialString; // outgoing calls only 196 protected int mNextPostDialChar; // index into postDialString 197 198 protected int mCause = DisconnectCause.NOT_DISCONNECTED; 199 protected PostDialState mPostDialState = PostDialState.NOT_STARTED; 200 201 private static String LOG_TAG = "Connection"; 202 203 Object mUserData; 204 private int mVideoState; 205 private int mConnectionCapabilities; 206 private boolean mIsWifi; 207 private boolean mAudioModeIsVoip; 208 private int mAudioQuality; 209 private int mCallSubstate; 210 private android.telecom.Connection.VideoProvider mVideoProvider; 211 public Call.State mPreHandoverState = Call.State.IDLE; 212 private Bundle mExtras; 213 private int mPhoneType; 214 private boolean mAnsweringDisconnectsActiveCall; 215 private boolean mAllowAddCallDuringVideoCall; 216 217 /** 218 * Used to indicate that this originated from pulling a {@link android.telecom.Connection} with 219 * {@link android.telecom.Connection#PROPERTY_IS_EXTERNAL_CALL}. 220 */ 221 private boolean mIsPulledCall = false; 222 223 /** 224 * Where {@link #mIsPulledCall} is {@code true}, contains the dialog Id of the external call 225 * which is being pulled (e.g. 226 * {@link com.android.internal.telephony.imsphone.ImsExternalConnection#getCallId()}). 227 */ 228 private int mPulledDialogId; 229 Connection(int phoneType)230 protected Connection(int phoneType) { 231 mPhoneType = phoneType; 232 } 233 234 /* Instance Methods */ 235 236 /** 237 * @return The telecom internal call ID associated with this connection. Only to be used for 238 * debugging purposes. 239 */ getTelecomCallId()240 public String getTelecomCallId() { 241 return mTelecomCallId; 242 } 243 244 /** 245 * Sets the telecom call ID associated with this connection. 246 * 247 * @param telecomCallId The telecom call ID. 248 */ setTelecomCallId(String telecomCallId)249 public void setTelecomCallId(String telecomCallId) { 250 mTelecomCallId = telecomCallId; 251 } 252 253 /** 254 * Gets address (e.g. phone number) associated with connection. 255 * TODO: distinguish reasons for unavailability 256 * 257 * @return address or null if unavailable 258 */ 259 getAddress()260 public String getAddress() { 261 return mAddress; 262 } 263 264 /** 265 * Gets CNAP name associated with connection. 266 * @return cnap name or null if unavailable 267 */ getCnapName()268 public String getCnapName() { 269 return mCnapName; 270 } 271 272 /** 273 * Get original dial string. 274 * @return original dial string or null if unavailable 275 */ getOrigDialString()276 public String getOrigDialString(){ 277 return null; 278 } 279 280 /** 281 * Gets CNAP presentation associated with connection. 282 * @return cnap name or null if unavailable 283 */ 284 getCnapNamePresentation()285 public int getCnapNamePresentation() { 286 return mCnapNamePresentation; 287 } 288 289 /** 290 * @return Call that owns this Connection, or null if none 291 */ getCall()292 public abstract Call getCall(); 293 294 /** 295 * Connection create time in currentTimeMillis() format 296 * Basically, set when object is created. 297 * Effectively, when an incoming call starts ringing or an 298 * outgoing call starts dialing 299 */ getCreateTime()300 public long getCreateTime() { 301 return mCreateTime; 302 } 303 304 /** 305 * Connection connect time in currentTimeMillis() format. 306 * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition. 307 * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition. 308 * Returns 0 before then. 309 */ getConnectTime()310 public long getConnectTime() { 311 return mConnectTime; 312 } 313 314 /** 315 * Sets the Connection connect time in currentTimeMillis() format. 316 * 317 * @param connectTime the new connect time. 318 */ setConnectTime(long connectTime)319 public void setConnectTime(long connectTime) { 320 mConnectTime = connectTime; 321 } 322 323 /** 324 * Sets the Connection connect time in {@link SystemClock#elapsedRealtime()} format. 325 * 326 * @param connectTimeReal the new connect time. 327 */ setConnectTimeReal(long connectTimeReal)328 public void setConnectTimeReal(long connectTimeReal) { 329 mConnectTimeReal = connectTimeReal; 330 } 331 332 /** 333 * Connection connect time in elapsedRealtime() format. 334 * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition. 335 * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition. 336 * Returns 0 before then. 337 */ getConnectTimeReal()338 public long getConnectTimeReal() { 339 return mConnectTimeReal; 340 } 341 342 /** 343 * Disconnect time in currentTimeMillis() format. 344 * The time when this Connection makes a transition into ENDED or FAIL. 345 * Returns 0 before then. 346 */ getDisconnectTime()347 public abstract long getDisconnectTime(); 348 349 /** 350 * Returns the number of milliseconds the call has been connected, 351 * or 0 if the call has never connected. 352 * If the call is still connected, then returns the elapsed 353 * time since connect. 354 */ getDurationMillis()355 public long getDurationMillis() { 356 if (mConnectTimeReal == 0) { 357 return 0; 358 } else if (mDuration == 0) { 359 return SystemClock.elapsedRealtime() - mConnectTimeReal; 360 } else { 361 return mDuration; 362 } 363 } 364 365 /** 366 * The time when this Connection last transitioned into HOLDING 367 * in elapsedRealtime() format. 368 * Returns 0, if it has never made a transition into HOLDING. 369 */ getHoldingStartTime()370 public long getHoldingStartTime() { 371 return mHoldingStartTime; 372 } 373 374 /** 375 * If this connection is HOLDING, return the number of milliseconds 376 * that it has been on hold for (approximately). 377 * If this connection is in any other state, return 0. 378 */ 379 getHoldDurationMillis()380 public abstract long getHoldDurationMillis(); 381 382 /** 383 * Returns call disconnect cause. Values are defined in 384 * {@link android.telephony.DisconnectCause}. If the call is not yet 385 * disconnected, NOT_DISCONNECTED is returned. 386 */ getDisconnectCause()387 public int getDisconnectCause() { 388 return mCause; 389 } 390 391 /** 392 * Returns a string disconnect cause which is from vendor. 393 * Vendors may use this string to explain the underline causes of failed calls. 394 * There is no guarantee that it is non-null nor it'll have meaningful stable values. 395 * Only use it when getDisconnectCause() returns a value that is not specific enough, like 396 * ERROR_UNSPECIFIED. 397 */ getVendorDisconnectCause()398 public abstract String getVendorDisconnectCause(); 399 400 /** 401 * Returns true of this connection originated elsewhere 402 * ("MT" or mobile terminated; another party called this terminal) 403 * or false if this call originated here (MO or mobile originated). 404 */ isIncoming()405 public boolean isIncoming() { 406 return mIsIncoming; 407 } 408 409 /** 410 * Sets whether this call is an incoming call or not. 411 * @param isIncoming {@code true} if the call is an incoming call, {@code false} if it is an 412 * outgoing call. 413 */ setIsIncoming(boolean isIncoming)414 public void setIsIncoming(boolean isIncoming) { 415 mIsIncoming = isIncoming; 416 } 417 418 /** 419 * If this Connection is connected, then it is associated with 420 * a Call. 421 * 422 * Returns getCall().getState() or Call.State.IDLE if not 423 * connected 424 */ getState()425 public Call.State getState() { 426 Call c; 427 428 c = getCall(); 429 430 if (c == null) { 431 return Call.State.IDLE; 432 } else { 433 return c.getState(); 434 } 435 } 436 437 /** 438 * If this connection went through handover return the state of the 439 * call that contained this connection before handover. 440 */ getStateBeforeHandover()441 public Call.State getStateBeforeHandover() { 442 return mPreHandoverState; 443 } 444 445 /** 446 * Get the details of conference participants. Expected to be 447 * overwritten by the Connection subclasses. 448 */ getConferenceParticipants()449 public List<ConferenceParticipant> getConferenceParticipants() { 450 Call c; 451 452 c = getCall(); 453 454 if (c == null) { 455 return null; 456 } else { 457 return c.getConferenceParticipants(); 458 } 459 } 460 461 /** 462 * isAlive() 463 * 464 * @return true if the connection isn't disconnected 465 * (could be active, holding, ringing, dialing, etc) 466 */ 467 public boolean isAlive()468 isAlive() { 469 return getState().isAlive(); 470 } 471 472 /** 473 * Returns true if Connection is connected and is INCOMING or WAITING 474 */ 475 public boolean isRinging()476 isRinging() { 477 return getState().isRinging(); 478 } 479 480 /** 481 * 482 * @return the userdata set in setUserData() 483 */ getUserData()484 public Object getUserData() { 485 return mUserData; 486 } 487 488 /** 489 * 490 * @param userdata user can store an any userdata in the Connection object. 491 */ setUserData(Object userdata)492 public void setUserData(Object userdata) { 493 mUserData = userdata; 494 } 495 496 /** 497 * Deflect individual Connection 498 */ deflect(String number)499 public abstract void deflect(String number) throws CallStateException; 500 501 /** 502 * Hangup individual Connection 503 */ hangup()504 public abstract void hangup() throws CallStateException; 505 506 /** 507 * Separate this call from its owner Call and assigns it to a new Call 508 * (eg if it is currently part of a Conference call 509 * TODO: Throw exception? Does GSM require error display on failure here? 510 */ separate()511 public abstract void separate() throws CallStateException; 512 513 public enum PostDialState { 514 NOT_STARTED, /* The post dial string playback hasn't 515 been started, or this call is not yet 516 connected, or this is an incoming call */ 517 STARTED, /* The post dial string playback has begun */ 518 WAIT, /* The post dial string playback is waiting for a 519 call to proceedAfterWaitChar() */ 520 WILD, /* The post dial string playback is waiting for a 521 call to proceedAfterWildChar() */ 522 COMPLETE, /* The post dial string playback is complete */ 523 CANCELLED, /* The post dial string playback was cancelled 524 with cancelPostDial() */ 525 PAUSE /* The post dial string playback is pausing for a 526 call to processNextPostDialChar*/ 527 } 528 clearUserData()529 public void clearUserData(){ 530 mUserData = null; 531 } 532 addPostDialListener(PostDialListener listener)533 public void addPostDialListener(PostDialListener listener) { 534 if (!mPostDialListeners.contains(listener)) { 535 mPostDialListeners.add(listener); 536 } 537 } 538 removePostDialListener(PostDialListener listener)539 public final void removePostDialListener(PostDialListener listener) { 540 mPostDialListeners.remove(listener); 541 } 542 clearPostDialListeners()543 protected final void clearPostDialListeners() { 544 if (mPostDialListeners != null) { 545 mPostDialListeners.clear(); 546 } 547 } 548 notifyPostDialListeners()549 protected final void notifyPostDialListeners() { 550 if (getPostDialState() == PostDialState.WAIT) { 551 for (PostDialListener listener : new ArrayList<>(mPostDialListeners)) { 552 listener.onPostDialWait(); 553 } 554 } 555 } 556 notifyPostDialListenersNextChar(char c)557 protected final void notifyPostDialListenersNextChar(char c) { 558 for (PostDialListener listener : new ArrayList<>(mPostDialListeners)) { 559 listener.onPostDialChar(c); 560 } 561 } 562 getPostDialState()563 public PostDialState getPostDialState() { 564 return mPostDialState; 565 } 566 567 /** 568 * Returns the portion of the post dial string that has not 569 * yet been dialed, or "" if none 570 */ getRemainingPostDialString()571 public String getRemainingPostDialString() { 572 if (mPostDialState == PostDialState.CANCELLED 573 || mPostDialState == PostDialState.COMPLETE 574 || mPostDialString == null 575 || mPostDialString.length() <= mNextPostDialChar) { 576 return ""; 577 } 578 579 return mPostDialString.substring(mNextPostDialChar); 580 } 581 582 /** 583 * See Phone.setOnPostDialWaitCharacter() 584 */ 585 proceedAfterWaitChar()586 public abstract void proceedAfterWaitChar(); 587 588 /** 589 * See Phone.setOnPostDialWildCharacter() 590 */ proceedAfterWildChar(String str)591 public abstract void proceedAfterWildChar(String str); 592 /** 593 * Cancel any post 594 */ cancelPostDial()595 public abstract void cancelPostDial(); 596 597 /** Called when the connection has been disconnected */ onDisconnect(int cause)598 public boolean onDisconnect(int cause) { 599 return false; 600 } 601 602 /** 603 * Returns the caller id presentation type for incoming and waiting calls 604 * @return one of PRESENTATION_* 605 */ getNumberPresentation()606 public abstract int getNumberPresentation(); 607 608 /** 609 * Returns the User to User Signaling (UUS) information associated with 610 * incoming and waiting calls 611 * @return UUSInfo containing the UUS userdata. 612 */ getUUSInfo()613 public abstract UUSInfo getUUSInfo(); 614 615 /** 616 * Returns the CallFail reason provided by the RIL with the result of 617 * RIL_REQUEST_LAST_CALL_FAIL_CAUSE 618 */ getPreciseDisconnectCause()619 public abstract int getPreciseDisconnectCause(); 620 621 /** 622 * Returns the original Connection instance associated with 623 * this Connection 624 */ getOrigConnection()625 public Connection getOrigConnection() { 626 return mOrigConnection; 627 } 628 629 /** 630 * Returns whether the original ImsPhoneConnection was a member 631 * of a conference call 632 * @return valid only when getOrigConnection() is not null 633 */ isMultiparty()634 public abstract boolean isMultiparty(); 635 636 /** 637 * Applicable only for IMS Call. Determines if this call is the origin of the conference call 638 * (i.e. {@code #isConferenceHost()} is {@code true}), or if it is a member of a conference 639 * hosted on another device. 640 * 641 * @return {@code true} if this call is the origin of the conference call it is a member of, 642 * {@code false} otherwise. 643 */ isConferenceHost()644 public boolean isConferenceHost() { 645 return false; 646 } 647 648 /** 649 * Applicable only for IMS Call. Determines if a connection is a member of a conference hosted 650 * on another device. 651 * 652 * @return {@code true} if the connection is a member of a conference hosted on another device. 653 */ isMemberOfPeerConference()654 public boolean isMemberOfPeerConference() { 655 return false; 656 } 657 migrateFrom(Connection c)658 public void migrateFrom(Connection c) { 659 if (c == null) return; 660 mListeners = c.mListeners; 661 mDialString = c.getOrigDialString(); 662 mCreateTime = c.getCreateTime(); 663 mConnectTime = c.getConnectTime(); 664 mConnectTimeReal = c.getConnectTimeReal(); 665 mHoldingStartTime = c.getHoldingStartTime(); 666 mOrigConnection = c.getOrigConnection(); 667 mPostDialString = c.mPostDialString; 668 mNextPostDialChar = c.mNextPostDialChar; 669 mPostDialState = c.mPostDialState; 670 } 671 672 /** 673 * Assign a listener to be notified of state changes. 674 * 675 * @param listener A listener. 676 */ addListener(Listener listener)677 public void addListener(Listener listener) { 678 mListeners.add(listener); 679 } 680 681 /** 682 * Removes a listener. 683 * 684 * @param listener A listener. 685 */ removeListener(Listener listener)686 public final void removeListener(Listener listener) { 687 mListeners.remove(listener); 688 } 689 690 /** 691 * Returns the current video state of the connection. 692 * 693 * @return The video state of the connection. 694 */ getVideoState()695 public int getVideoState() { 696 return mVideoState; 697 } 698 699 /** 700 * Called to get Connection capabilities.Returns Capabilities bitmask. 701 * @See Connection.Capability. 702 */ getConnectionCapabilities()703 public int getConnectionCapabilities() { 704 return mConnectionCapabilities; 705 } 706 707 /** 708 * @return {@code} true if the connection has the specified capabilities. 709 */ hasCapabilities(int connectionCapabilities)710 public boolean hasCapabilities(int connectionCapabilities) { 711 return (mConnectionCapabilities & connectionCapabilities) == connectionCapabilities; 712 } 713 714 /** 715 * Applies a capability to a capabilities bit-mask. 716 * 717 * @param capabilities The capabilities bit-mask. 718 * @param capability The capability to apply. 719 * @return The capabilities bit-mask with the capability applied. 720 */ addCapability(int capabilities, int capability)721 public static int addCapability(int capabilities, int capability) { 722 return capabilities | capability; 723 } 724 725 /** 726 * Removes a capability to a capabilities bit-mask. 727 * 728 * @param capabilities The capabilities bit-mask. 729 * @param capability The capability to remove. 730 * @return The capabilities bit-mask with the capability removed. 731 */ removeCapability(int capabilities, int capability)732 public static int removeCapability(int capabilities, int capability) { 733 return capabilities & ~capability; 734 } 735 736 /** 737 * Returns whether the connection is using a wifi network. 738 * 739 * @return {@code True} if the connection is using a wifi network. 740 */ isWifi()741 public boolean isWifi() { 742 return mIsWifi; 743 } 744 745 /** 746 * Returns whether the connection uses voip audio mode 747 * 748 * @return {@code True} if the connection uses voip audio mode 749 */ getAudioModeIsVoip()750 public boolean getAudioModeIsVoip() { 751 return mAudioModeIsVoip; 752 } 753 754 /** 755 * Returns the {@link android.telecom.Connection.VideoProvider} for the connection. 756 * 757 * @return The {@link android.telecom.Connection.VideoProvider}. 758 */ getVideoProvider()759 public android.telecom.Connection.VideoProvider getVideoProvider() { 760 return mVideoProvider; 761 } 762 763 /** 764 * Returns the audio-quality for the connection. 765 * 766 * @return The audio quality for the connection. 767 */ getAudioQuality()768 public int getAudioQuality() { 769 return mAudioQuality; 770 } 771 772 773 /** 774 * Returns the current call substate of the connection. 775 * 776 * @return The call substate of the connection. 777 */ getCallSubstate()778 public int getCallSubstate() { 779 return mCallSubstate; 780 } 781 782 783 /** 784 * Sets the videoState for the current connection and reports the changes to all listeners. 785 * Valid video states are defined in {@link android.telecom.VideoProfile}. 786 * 787 * @return The video state. 788 */ setVideoState(int videoState)789 public void setVideoState(int videoState) { 790 mVideoState = videoState; 791 for (Listener l : mListeners) { 792 l.onVideoStateChanged(mVideoState); 793 } 794 } 795 796 /** 797 * Called to set Connection capabilities. This will take Capabilities bitmask as input which is 798 * converted from Capabilities constants. 799 * 800 * @See Connection.Capability. 801 * @param capabilities The Capabilities bitmask. 802 */ setConnectionCapabilities(int capabilities)803 public void setConnectionCapabilities(int capabilities) { 804 if (mConnectionCapabilities != capabilities) { 805 mConnectionCapabilities = capabilities; 806 for (Listener l : mListeners) { 807 l.onConnectionCapabilitiesChanged(mConnectionCapabilities); 808 } 809 } 810 } 811 812 /** 813 * Sets whether a wifi network is used for the connection. 814 * 815 * @param isWifi {@code True} if wifi is being used. 816 */ setWifi(boolean isWifi)817 public void setWifi(boolean isWifi) { 818 mIsWifi = isWifi; 819 for (Listener l : mListeners) { 820 l.onWifiChanged(mIsWifi); 821 } 822 } 823 824 /** 825 * Set the voip audio mode for the connection 826 * 827 * @param isVoip {@code True} if voip audio mode is being used. 828 */ setAudioModeIsVoip(boolean isVoip)829 public void setAudioModeIsVoip(boolean isVoip) { 830 mAudioModeIsVoip = isVoip; 831 } 832 833 /** 834 * Set the audio quality for the connection. 835 * 836 * @param audioQuality The audio quality. 837 */ setAudioQuality(int audioQuality)838 public void setAudioQuality(int audioQuality) { 839 mAudioQuality = audioQuality; 840 for (Listener l : mListeners) { 841 l.onAudioQualityChanged(mAudioQuality); 842 } 843 } 844 845 /** 846 * Notifies listeners that connection extras has changed. 847 * @param extras New connection extras. This Bundle will be cloned to ensure that any concurrent 848 * modifications to the extras Bundle do not affect Bundle operations in the onExtrasChanged 849 * listeners. 850 */ setConnectionExtras(Bundle extras)851 public void setConnectionExtras(Bundle extras) { 852 if (extras != null) { 853 mExtras = new Bundle(extras); 854 855 int previousCount = mExtras.size(); 856 // Prevent vendors from passing in extras other than primitive types and android API 857 // parcelables. 858 mExtras = mExtras.filterValues(); 859 int filteredCount = mExtras.size(); 860 if (filteredCount != previousCount) { 861 Rlog.i(TAG, "setConnectionExtras: filtering " + (previousCount - filteredCount) 862 + " invalid extras."); 863 } 864 } else { 865 mExtras = null; 866 } 867 868 for (Listener l : mListeners) { 869 l.onExtrasChanged(mExtras); 870 } 871 } 872 873 /** 874 * Retrieves the current connection extras. 875 * @return the connection extras. 876 */ getConnectionExtras()877 public Bundle getConnectionExtras() { 878 return mExtras == null ? null : new Bundle(mExtras); 879 } 880 881 /** 882 * @return {@code true} if answering the call will cause the current active call to be 883 * disconnected, {@code false} otherwise. 884 */ isActiveCallDisconnectedOnAnswer()885 public boolean isActiveCallDisconnectedOnAnswer() { 886 return mAnsweringDisconnectsActiveCall; 887 } 888 889 /** 890 * Sets whether answering this call will cause the active call to be disconnected. 891 * <p> 892 * Should only be set {@code true} if there is an active call and this call is ringing. 893 * 894 * @param answeringDisconnectsActiveCall {@code true} if answering the call will call the active 895 * call to be disconnected. 896 */ setActiveCallDisconnectedOnAnswer(boolean answeringDisconnectsActiveCall)897 public void setActiveCallDisconnectedOnAnswer(boolean answeringDisconnectsActiveCall) { 898 mAnsweringDisconnectsActiveCall = answeringDisconnectsActiveCall; 899 } 900 shouldAllowAddCallDuringVideoCall()901 public boolean shouldAllowAddCallDuringVideoCall() { 902 return mAllowAddCallDuringVideoCall; 903 } 904 setAllowAddCallDuringVideoCall(boolean allowAddCallDuringVideoCall)905 public void setAllowAddCallDuringVideoCall(boolean allowAddCallDuringVideoCall) { 906 mAllowAddCallDuringVideoCall = allowAddCallDuringVideoCall; 907 } 908 909 /** 910 * Sets whether the connection is the result of an external call which was pulled to the local 911 * device. 912 * 913 * @param isPulledCall {@code true} if this connection is the result of pulling an external call 914 * to the local device. 915 */ setIsPulledCall(boolean isPulledCall)916 public void setIsPulledCall(boolean isPulledCall) { 917 mIsPulledCall = isPulledCall; 918 } 919 isPulledCall()920 public boolean isPulledCall() { 921 return mIsPulledCall; 922 } 923 924 /** 925 * For an external call which is being pulled (e.g. {@link #isPulledCall()} is {@code true}), 926 * sets the dialog Id for the external call. Used to handle failures to pull a call so that the 927 * pulled call can be reconciled with its original external connection. 928 * 929 * @param pulledDialogId The dialog id associated with a pulled call. 930 */ setPulledDialogId(int pulledDialogId)931 public void setPulledDialogId(int pulledDialogId) { 932 mPulledDialogId = pulledDialogId; 933 } 934 getPulledDialogId()935 public int getPulledDialogId() { 936 return mPulledDialogId; 937 } 938 939 /** 940 * Sets the call substate for the current connection and reports the changes to all listeners. 941 * Valid call substates are defined in {@link android.telecom.Connection}. 942 * 943 * @return The call substate. 944 */ setCallSubstate(int callSubstate)945 public void setCallSubstate(int callSubstate) { 946 mCallSubstate = callSubstate; 947 for (Listener l : mListeners) { 948 l.onCallSubstateChanged(mCallSubstate); 949 } 950 } 951 952 /** 953 * Sets the {@link android.telecom.Connection.VideoProvider} for the connection. 954 * 955 * @param videoProvider The video call provider. 956 */ setVideoProvider(android.telecom.Connection.VideoProvider videoProvider)957 public void setVideoProvider(android.telecom.Connection.VideoProvider videoProvider) { 958 mVideoProvider = videoProvider; 959 for (Listener l : mListeners) { 960 l.onVideoProviderChanged(mVideoProvider); 961 } 962 } 963 setConverted(String oriNumber)964 public void setConverted(String oriNumber) { 965 mNumberConverted = true; 966 mConvertedNumber = mAddress; 967 mAddress = oriNumber; 968 mDialString = oriNumber; 969 } 970 971 /** 972 * Notifies listeners of a change to conference participant(s). 973 * 974 * @param conferenceParticipants The participant(s). 975 */ updateConferenceParticipants(List<ConferenceParticipant> conferenceParticipants)976 public void updateConferenceParticipants(List<ConferenceParticipant> conferenceParticipants) { 977 for (Listener l : mListeners) { 978 l.onConferenceParticipantsChanged(conferenceParticipants); 979 } 980 } 981 982 /** 983 * Notifies listeners of a change to the multiparty state of the connection. 984 * 985 * @param isMultiparty The participant(s). 986 */ updateMultipartyState(boolean isMultiparty)987 public void updateMultipartyState(boolean isMultiparty) { 988 for (Listener l : mListeners) { 989 l.onMultipartyStateChanged(isMultiparty); 990 } 991 } 992 993 /** 994 * Notifies listeners of a failure in merging this connection with the background connection. 995 */ onConferenceMergeFailed()996 public void onConferenceMergeFailed() { 997 for (Listener l : mListeners) { 998 l.onConferenceMergedFailed(); 999 } 1000 } 1001 1002 /** 1003 * Notifies that the underlying phone has exited ECM mode. 1004 */ onExitedEcmMode()1005 public void onExitedEcmMode() { 1006 for (Listener l : mListeners) { 1007 l.onExitedEcmMode(); 1008 } 1009 } 1010 1011 /** 1012 * Notifies the connection that a call to {@link #pullExternalCall()} has failed to pull the 1013 * call to the local device. 1014 * 1015 * @param externalConnection The original 1016 * {@link com.android.internal.telephony.imsphone.ImsExternalConnection} from which the 1017 * pull was initiated. 1018 */ onCallPullFailed(Connection externalConnection)1019 public void onCallPullFailed(Connection externalConnection) { 1020 for (Listener l : mListeners) { 1021 l.onCallPullFailed(externalConnection); 1022 } 1023 } 1024 1025 /** 1026 * Notifies the connection that there was a failure while handing over to WIFI. 1027 */ onHandoverToWifiFailed()1028 public void onHandoverToWifiFailed() { 1029 for (Listener l : mListeners) { 1030 l.onHandoverToWifiFailed(); 1031 } 1032 } 1033 1034 /** 1035 * Notifies the connection of a connection event. 1036 */ onConnectionEvent(String event, Bundle extras)1037 public void onConnectionEvent(String event, Bundle extras) { 1038 for (Listener l : mListeners) { 1039 l.onConnectionEvent(event, extras); 1040 } 1041 } 1042 1043 /** 1044 * Notifies this Connection of a request to disconnect a participant of the conference managed 1045 * by the connection. 1046 * 1047 * @param endpoint the {@link Uri} of the participant to disconnect. 1048 */ onDisconnectConferenceParticipant(Uri endpoint)1049 public void onDisconnectConferenceParticipant(Uri endpoint) { 1050 } 1051 1052 /** 1053 * Called by a {@link android.telecom.Connection} to indicate that this call should be pulled 1054 * to the local device. 1055 */ pullExternalCall()1056 public void pullExternalCall() { 1057 } 1058 onRttModifyRequestReceived()1059 public void onRttModifyRequestReceived() { 1060 for (Listener l : mListeners) { 1061 l.onRttModifyRequestReceived(); 1062 } 1063 } 1064 onRttModifyResponseReceived(int status)1065 public void onRttModifyResponseReceived(int status) { 1066 for (Listener l : mListeners) { 1067 l.onRttModifyResponseReceived(status); 1068 } 1069 } 1070 onRttInitiated()1071 public void onRttInitiated() { 1072 for (Listener l : mListeners) { 1073 l.onRttInitiated(); 1074 } 1075 } 1076 onRttTerminated()1077 public void onRttTerminated() { 1078 for (Listener l : mListeners) { 1079 l.onRttTerminated(); 1080 } 1081 } 1082 /** 1083 * Notify interested parties that this connection disconnected. 1084 * {@code TelephonyConnection}, for example, uses this. 1085 * @param reason the disconnect code, per {@link DisconnectCause}. 1086 */ notifyDisconnect(int reason)1087 protected void notifyDisconnect(int reason) { 1088 Rlog.i(TAG, "notifyDisconnect: callId=" + getTelecomCallId() + ", reason=" + reason); 1089 for (Listener l : mListeners) { 1090 l.onDisconnect(reason); 1091 } 1092 } 1093 1094 /** 1095 * 1096 */ getPhoneType()1097 public int getPhoneType() { 1098 return mPhoneType; 1099 } 1100 1101 /** 1102 * Build a human representation of a connection instance, suitable for debugging. 1103 * Don't log personal stuff unless in debug mode. 1104 * @return a string representing the internal state of this connection. 1105 */ toString()1106 public String toString() { 1107 StringBuilder str = new StringBuilder(128); 1108 1109 str.append(" callId: " + getTelecomCallId()); 1110 str.append(" isExternal: " + (((mConnectionCapabilities & Capability.IS_EXTERNAL_CONNECTION) 1111 == Capability.IS_EXTERNAL_CONNECTION) ? "Y" : "N")); 1112 if (Rlog.isLoggable(LOG_TAG, Log.DEBUG)) { 1113 str.append("addr: " + getAddress()) 1114 .append(" pres.: " + getNumberPresentation()) 1115 .append(" dial: " + getOrigDialString()) 1116 .append(" postdial: " + getRemainingPostDialString()) 1117 .append(" cnap name: " + getCnapName()) 1118 .append("(" + getCnapNamePresentation() + ")"); 1119 } 1120 str.append(" incoming: " + isIncoming()) 1121 .append(" state: " + getState()) 1122 .append(" post dial state: " + getPostDialState()); 1123 return str.toString(); 1124 } 1125 } 1126