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