make mute and speaker button work
| 
						 | 
				
			
			@ -16,6 +16,7 @@ import android.view.View;
 | 
			
		|||
import android.view.WindowManager;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Preconditions;
 | 
			
		||||
import com.google.common.collect.ImmutableList;
 | 
			
		||||
 | 
			
		||||
import java.lang.ref.WeakReference;
 | 
			
		||||
| 
						 | 
				
			
			@ -344,18 +345,91 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
 | 
			
		|||
            this.binding.endCall.setVisibility(View.VISIBLE);
 | 
			
		||||
            this.binding.acceptCall.setVisibility(View.INVISIBLE);
 | 
			
		||||
        }
 | 
			
		||||
        updateInCallButtonConfiguration(state);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void updateInCallButtonConfiguration() {
 | 
			
		||||
        updateInCallButtonConfiguration(requireRtpConnection().getEndUserState());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("RestrictedApi")
 | 
			
		||||
    private void updateInCallButtonConfiguration(final RtpEndUserState state) {
 | 
			
		||||
        if (state == RtpEndUserState.CONNECTED) {
 | 
			
		||||
            this.binding.inCallActionLeft.setImageResource(R.drawable.ic_volume_off_black_24dp);
 | 
			
		||||
            this.binding.inCallActionLeft.setVisibility(View.VISIBLE);
 | 
			
		||||
            this.binding.inCallActionRight.setImageResource(R.drawable.ic_mic_black_24dp);
 | 
			
		||||
            this.binding.inCallActionRight.setVisibility(View.VISIBLE);
 | 
			
		||||
            final AppRTCAudioManager audioManager = requireRtpConnection().getAudioManager();
 | 
			
		||||
            updateInCallButtonConfiguration(
 | 
			
		||||
                    audioManager.getSelectedAudioDevice(),
 | 
			
		||||
                    audioManager.getAudioDevices().size(),
 | 
			
		||||
                    requireRtpConnection().isMicrophoneEnabled()
 | 
			
		||||
            );
 | 
			
		||||
        } else {
 | 
			
		||||
            this.binding.inCallActionLeft.setVisibility(View.GONE);
 | 
			
		||||
            this.binding.inCallActionRight.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("RestrictedApi")
 | 
			
		||||
    private void updateInCallButtonConfiguration(final AppRTCAudioManager.AudioDevice selectedAudioDevice, final int numberOfChoices, final boolean microphoneEnabled) {
 | 
			
		||||
        switch (selectedAudioDevice) {
 | 
			
		||||
            case EARPIECE:
 | 
			
		||||
                this.binding.inCallActionLeft.setImageResource(R.drawable.ic_volume_off_black_24dp);
 | 
			
		||||
                if (numberOfChoices >= 2) {
 | 
			
		||||
                    this.binding.inCallActionLeft.setOnClickListener(this::switchToSpeaker);
 | 
			
		||||
                } else {
 | 
			
		||||
                    this.binding.inCallActionLeft.setOnClickListener(null);
 | 
			
		||||
                    this.binding.inCallActionLeft.setClickable(false);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case WIRED_HEADSET:
 | 
			
		||||
                this.binding.inCallActionLeft.setImageResource(R.drawable.ic_headset_black_24dp);
 | 
			
		||||
                this.binding.inCallActionLeft.setOnClickListener(null);
 | 
			
		||||
                this.binding.inCallActionLeft.setClickable(false);
 | 
			
		||||
                break;
 | 
			
		||||
            case SPEAKER_PHONE:
 | 
			
		||||
                this.binding.inCallActionLeft.setImageResource(R.drawable.ic_volume_up_black_24dp);
 | 
			
		||||
                if (numberOfChoices >= 2) {
 | 
			
		||||
                    this.binding.inCallActionLeft.setOnClickListener(this::switchToEarpiece);
 | 
			
		||||
                } else {
 | 
			
		||||
                    this.binding.inCallActionLeft.setOnClickListener(null);
 | 
			
		||||
                    this.binding.inCallActionLeft.setClickable(false);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case BLUETOOTH:
 | 
			
		||||
                this.binding.inCallActionLeft.setImageResource(R.drawable.ic_bluetooth_audio_black_24dp);
 | 
			
		||||
                this.binding.inCallActionLeft.setOnClickListener(null);
 | 
			
		||||
                this.binding.inCallActionLeft.setClickable(false);
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        this.binding.inCallActionLeft.setVisibility(View.VISIBLE);
 | 
			
		||||
        if (microphoneEnabled) {
 | 
			
		||||
            this.binding.inCallActionRight.setImageResource(R.drawable.ic_mic_black_24dp);
 | 
			
		||||
            this.binding.inCallActionRight.setOnClickListener(this::disableMicrophone);
 | 
			
		||||
        } else {
 | 
			
		||||
            this.binding.inCallActionRight.setImageResource(R.drawable.ic_mic_off_black_24dp);
 | 
			
		||||
            this.binding.inCallActionRight.setOnClickListener(this::enableMicrophone);
 | 
			
		||||
        }
 | 
			
		||||
        this.binding.inCallActionRight.setVisibility(View.VISIBLE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void disableMicrophone(View view) {
 | 
			
		||||
        JingleRtpConnection rtpConnection = requireRtpConnection();
 | 
			
		||||
        rtpConnection.setMicrophoneEnabled(false);
 | 
			
		||||
        updateInCallButtonConfiguration();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void enableMicrophone(View view) {
 | 
			
		||||
        JingleRtpConnection rtpConnection = requireRtpConnection();
 | 
			
		||||
        rtpConnection.setMicrophoneEnabled(true);
 | 
			
		||||
        updateInCallButtonConfiguration();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void switchToEarpiece(View view) {
 | 
			
		||||
        requireRtpConnection().getAudioManager().setDefaultAudioDevice(AppRTCAudioManager.AudioDevice.EARPIECE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void switchToSpeaker(View view) {
 | 
			
		||||
        requireRtpConnection().getAudioManager().setDefaultAudioDevice(AppRTCAudioManager.AudioDevice.SPEAKER_PHONE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void retry(View view) {
 | 
			
		||||
        Log.d(Config.LOGTAG, "attempting retry");
 | 
			
		||||
        final Intent intent = getIntent();
 | 
			
		||||
| 
						 | 
				
			
			@ -419,6 +493,18 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
 | 
			
		|||
    @Override
 | 
			
		||||
    public void onAudioDeviceChanged(AppRTCAudioManager.AudioDevice selectedAudioDevice, Set<AppRTCAudioManager.AudioDevice> availableAudioDevices) {
 | 
			
		||||
        Log.d(Config.LOGTAG, "onAudioDeviceChanged in activity: selected:" + selectedAudioDevice + ", available:" + availableAudioDevices);
 | 
			
		||||
        try {
 | 
			
		||||
            if (requireRtpConnection().getEndUserState() == RtpEndUserState.CONNECTED) {
 | 
			
		||||
                final AppRTCAudioManager audioManager = requireRtpConnection().getAudioManager();
 | 
			
		||||
                updateInCallButtonConfiguration(
 | 
			
		||||
                        audioManager.getSelectedAudioDevice(),
 | 
			
		||||
                        audioManager.getAudioDevices().size(),
 | 
			
		||||
                        requireRtpConnection().isMicrophoneEnabled()
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        } catch (IllegalStateException e) {
 | 
			
		||||
            Log.d(Config.LOGTAG, "RTP connection was not available when audio device changed");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void updateRtpSessionProposalState(final Account account, final Jid with, final RtpEndUserState state) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -833,6 +833,18 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public AppRTCAudioManager getAudioManager() {
 | 
			
		||||
        return webRTCWrapper.getAudioManager();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setMicrophoneEnabled(final boolean enabled) {
 | 
			
		||||
        webRTCWrapper.setMicrophoneEnabled(enabled);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isMicrophoneEnabled() {
 | 
			
		||||
        return webRTCWrapper.isMicrophoneEnabled();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onAudioDeviceChanged(AppRTCAudioManager.AudioDevice selectedAudioDevice, Set<AppRTCAudioManager.AudioDevice> availableAudioDevices) {
 | 
			
		||||
        xmppConnectionService.notifyJingleRtpConnectionUpdate(selectedAudioDevice, availableAudioDevices);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -131,6 +131,7 @@ public class WebRTCWrapper {
 | 
			
		|||
    };
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private PeerConnection peerConnection = null;
 | 
			
		||||
    private AudioTrack localAudioTrack = null;
 | 
			
		||||
    private AppRTCAudioManager appRTCAudioManager = null;
 | 
			
		||||
    private final Handler mainHandler = new Handler(Looper.getMainLooper());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -201,10 +202,9 @@ public class WebRTCWrapper {
 | 
			
		|||
 | 
			
		||||
        final AudioSource audioSource = peerConnectionFactory.createAudioSource(new MediaConstraints());
 | 
			
		||||
 | 
			
		||||
        final AudioTrack audioTrack = peerConnectionFactory.createAudioTrack("my-audio-track", audioSource);
 | 
			
		||||
        Log.d(Config.LOGTAG, "audioTrack enabled:" + audioTrack.enabled() + " state=" + audioTrack.state());
 | 
			
		||||
        this.localAudioTrack = peerConnectionFactory.createAudioTrack("my-audio-track", audioSource);
 | 
			
		||||
        final MediaStream stream = peerConnectionFactory.createLocalMediaStream("my-media-stream");
 | 
			
		||||
        stream.addTrack(audioTrack);
 | 
			
		||||
        stream.addTrack(this.localAudioTrack);
 | 
			
		||||
        //stream.addTrack(videoTrack);
 | 
			
		||||
 | 
			
		||||
        this.localVideoTrack = videoTrack;
 | 
			
		||||
| 
						 | 
				
			
			@ -229,6 +229,22 @@ public class WebRTCWrapper {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setMicrophoneEnabled(final boolean enabled) {
 | 
			
		||||
        final AudioTrack audioTrack = this.localAudioTrack;
 | 
			
		||||
        if (audioTrack == null) {
 | 
			
		||||
            throw new IllegalStateException("Local audio track does not exist (yet)");
 | 
			
		||||
        }
 | 
			
		||||
        audioTrack.setEnabled(enabled);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isMicrophoneEnabled() {
 | 
			
		||||
        final AudioTrack audioTrack = this.localAudioTrack;
 | 
			
		||||
        if (audioTrack == null) {
 | 
			
		||||
            throw new IllegalStateException("Local audio track does not exist (yet)");
 | 
			
		||||
        }
 | 
			
		||||
        return audioTrack.enabled();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public ListenableFuture<SessionDescription> createOffer() {
 | 
			
		||||
        return Futures.transformAsync(getPeerConnectionFuture(), peerConnection -> {
 | 
			
		||||
| 
						 | 
				
			
			@ -330,6 +346,10 @@ public class WebRTCWrapper {
 | 
			
		|||
        return peerConnection;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public AppRTCAudioManager getAudioManager() {
 | 
			
		||||
        return appRTCAudioManager;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static abstract class SetSdpObserver implements SdpObserver {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
		 After Width: | Height: | Size: 420 B  | 
| 
		 After Width: | Height: | Size: 349 B  | 
| 
		 After Width: | Height: | Size: 283 B  | 
| 
		 After Width: | Height: | Size: 230 B  | 
| 
		 After Width: | Height: | Size: 479 B  | 
| 
		 After Width: | Height: | Size: 412 B  | 
| 
		 After Width: | Height: | Size: 724 B  | 
| 
		 After Width: | Height: | Size: 586 B  | 
| 
		 After Width: | Height: | Size: 867 B  | 
| 
		 After Width: | Height: | Size: 786 B  |