@@ -594,12 +594,10 @@ public void endCall() throws SipException {
594594 */
595595 public void holdCall (int timeout ) throws SipException {
596596 synchronized (this ) {
597- if (mHold ) return ;
597+ if (mHold ) return ;
598598 mSipSession .changeCall (createHoldOffer ().encode (), timeout );
599599 mHold = true ;
600-
601- AudioGroup audioGroup = getAudioGroup ();
602- if (audioGroup != null ) audioGroup .setMode (AudioGroup .MODE_ON_HOLD );
600+ setAudioGroupMode ();
603601 }
604602 }
605603
@@ -643,8 +641,7 @@ public void continueCall(int timeout) throws SipException {
643641 if (!mHold ) return ;
644642 mSipSession .changeCall (createContinueOffer ().encode (), timeout );
645643 mHold = false ;
646- AudioGroup audioGroup = getAudioGroup ();
647- if (audioGroup != null ) audioGroup .setMode (AudioGroup .MODE_NORMAL );
644+ setAudioGroupMode ();
648645 }
649646 }
650647
@@ -765,13 +762,8 @@ private boolean isWifiOn() {
765762 /** Toggles mute. */
766763 public void toggleMute () {
767764 synchronized (this ) {
768- AudioGroup audioGroup = getAudioGroup ();
769- if (audioGroup != null ) {
770- audioGroup .setMode (mMuted
771- ? AudioGroup .MODE_NORMAL
772- : AudioGroup .MODE_MUTED );
773- mMuted = !mMuted ;
774- }
765+ mMuted = !mMuted ;
766+ setAudioGroupMode ();
775767 }
776768 }
777769
@@ -790,14 +782,22 @@ public boolean isMuted() {
790782 * Puts the device to speaker mode.
791783 * <p class="note"><strong>Note:</strong> Requires the
792784 * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS} permission.</p>
785+ *
786+ * @param speakerMode set true to enable speaker mode; false to disable
793787 */
794788 public void setSpeakerMode (boolean speakerMode ) {
795789 synchronized (this ) {
796790 ((AudioManager ) mContext .getSystemService (Context .AUDIO_SERVICE ))
797791 .setSpeakerphoneOn (speakerMode );
792+ setAudioGroupMode ();
798793 }
799794 }
800795
796+ private boolean isSpeakerOn () {
797+ return ((AudioManager ) mContext .getSystemService (Context .AUDIO_SERVICE ))
798+ .isSpeakerphoneOn ();
799+ }
800+
801801 /**
802802 * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2883</a>,
803803 * event 0--9 maps to decimal
@@ -874,7 +874,11 @@ public AudioGroup getAudioGroup() {
874874 /**
875875 * Sets the {@link AudioGroup} object which the {@link AudioStream} object
876876 * joins. If {@code audioGroup} is null, then the {@code AudioGroup} object
877- * will be dynamically created when needed.
877+ * will be dynamically created when needed. Note that the mode of the
878+ * {@code AudioGroup} is not changed according to the audio settings (i.e.,
879+ * hold, mute, speaker phone) of this object. This is mainly used to merge
880+ * multiple {@code SipAudioCall} objects to form a conference call. The
881+ * settings of the first object (that merges others) override others'.
878882 *
879883 * @see #getAudioStream
880884 * @hide
@@ -990,16 +994,25 @@ private synchronized void startAudioInternal() throws UnknownHostException {
990994 // AudioGroup logic:
991995 AudioGroup audioGroup = getAudioGroup ();
992996 if (mHold ) {
993- if (audioGroup != null ) {
994- audioGroup .setMode (AudioGroup .MODE_ON_HOLD );
995- }
996997 // don't create an AudioGroup here; doing so will fail if
997998 // there's another AudioGroup out there that's active
998999 } else {
9991000 if (audioGroup == null ) audioGroup = new AudioGroup ();
10001001 stream .join (audioGroup );
1001- if (mMuted ) {
1002+ }
1003+ setAudioGroupMode ();
1004+ }
1005+
1006+ // set audio group mode based on current audio configuration
1007+ private void setAudioGroupMode () {
1008+ AudioGroup audioGroup = getAudioGroup ();
1009+ if (audioGroup != null ) {
1010+ if (mHold ) {
1011+ audioGroup .setMode (AudioGroup .MODE_ON_HOLD );
1012+ } else if (mMuted ) {
10021013 audioGroup .setMode (AudioGroup .MODE_MUTED );
1014+ } else if (isSpeakerOn ()) {
1015+ audioGroup .setMode (AudioGroup .MODE_ECHO_SUPPRESSION );
10031016 } else {
10041017 audioGroup .setMode (AudioGroup .MODE_NORMAL );
10051018 }
0 commit comments