make mute and speaker button work
|
@ -16,6 +16,7 @@ import android.view.View;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
@ -344,18 +345,91 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
||||||
this.binding.endCall.setVisibility(View.VISIBLE);
|
this.binding.endCall.setVisibility(View.VISIBLE);
|
||||||
this.binding.acceptCall.setVisibility(View.INVISIBLE);
|
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) {
|
if (state == RtpEndUserState.CONNECTED) {
|
||||||
this.binding.inCallActionLeft.setImageResource(R.drawable.ic_volume_off_black_24dp);
|
final AppRTCAudioManager audioManager = requireRtpConnection().getAudioManager();
|
||||||
this.binding.inCallActionLeft.setVisibility(View.VISIBLE);
|
updateInCallButtonConfiguration(
|
||||||
this.binding.inCallActionRight.setImageResource(R.drawable.ic_mic_black_24dp);
|
audioManager.getSelectedAudioDevice(),
|
||||||
this.binding.inCallActionRight.setVisibility(View.VISIBLE);
|
audioManager.getAudioDevices().size(),
|
||||||
|
requireRtpConnection().isMicrophoneEnabled()
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.binding.inCallActionLeft.setVisibility(View.GONE);
|
this.binding.inCallActionLeft.setVisibility(View.GONE);
|
||||||
this.binding.inCallActionRight.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) {
|
private void retry(View view) {
|
||||||
Log.d(Config.LOGTAG, "attempting retry");
|
Log.d(Config.LOGTAG, "attempting retry");
|
||||||
final Intent intent = getIntent();
|
final Intent intent = getIntent();
|
||||||
|
@ -419,6 +493,18 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
||||||
@Override
|
@Override
|
||||||
public void onAudioDeviceChanged(AppRTCAudioManager.AudioDevice selectedAudioDevice, Set<AppRTCAudioManager.AudioDevice> availableAudioDevices) {
|
public void onAudioDeviceChanged(AppRTCAudioManager.AudioDevice selectedAudioDevice, Set<AppRTCAudioManager.AudioDevice> availableAudioDevices) {
|
||||||
Log.d(Config.LOGTAG, "onAudioDeviceChanged in activity: selected:" + selectedAudioDevice + ", available:" + 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) {
|
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
|
@Override
|
||||||
public void onAudioDeviceChanged(AppRTCAudioManager.AudioDevice selectedAudioDevice, Set<AppRTCAudioManager.AudioDevice> availableAudioDevices) {
|
public void onAudioDeviceChanged(AppRTCAudioManager.AudioDevice selectedAudioDevice, Set<AppRTCAudioManager.AudioDevice> availableAudioDevices) {
|
||||||
xmppConnectionService.notifyJingleRtpConnectionUpdate(selectedAudioDevice, availableAudioDevices);
|
xmppConnectionService.notifyJingleRtpConnectionUpdate(selectedAudioDevice, availableAudioDevices);
|
||||||
|
|
|
@ -131,6 +131,7 @@ public class WebRTCWrapper {
|
||||||
};
|
};
|
||||||
@Nullable
|
@Nullable
|
||||||
private PeerConnection peerConnection = null;
|
private PeerConnection peerConnection = null;
|
||||||
|
private AudioTrack localAudioTrack = null;
|
||||||
private AppRTCAudioManager appRTCAudioManager = null;
|
private AppRTCAudioManager appRTCAudioManager = null;
|
||||||
private final Handler mainHandler = new Handler(Looper.getMainLooper());
|
private final Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
|
@ -201,10 +202,9 @@ public class WebRTCWrapper {
|
||||||
|
|
||||||
final AudioSource audioSource = peerConnectionFactory.createAudioSource(new MediaConstraints());
|
final AudioSource audioSource = peerConnectionFactory.createAudioSource(new MediaConstraints());
|
||||||
|
|
||||||
final AudioTrack audioTrack = peerConnectionFactory.createAudioTrack("my-audio-track", audioSource);
|
this.localAudioTrack = peerConnectionFactory.createAudioTrack("my-audio-track", audioSource);
|
||||||
Log.d(Config.LOGTAG, "audioTrack enabled:" + audioTrack.enabled() + " state=" + audioTrack.state());
|
|
||||||
final MediaStream stream = peerConnectionFactory.createLocalMediaStream("my-media-stream");
|
final MediaStream stream = peerConnectionFactory.createLocalMediaStream("my-media-stream");
|
||||||
stream.addTrack(audioTrack);
|
stream.addTrack(this.localAudioTrack);
|
||||||
//stream.addTrack(videoTrack);
|
//stream.addTrack(videoTrack);
|
||||||
|
|
||||||
this.localVideoTrack = 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() {
|
public ListenableFuture<SessionDescription> createOffer() {
|
||||||
return Futures.transformAsync(getPeerConnectionFuture(), peerConnection -> {
|
return Futures.transformAsync(getPeerConnectionFuture(), peerConnection -> {
|
||||||
|
@ -330,6 +346,10 @@ public class WebRTCWrapper {
|
||||||
return peerConnection;
|
return peerConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AppRTCAudioManager getAudioManager() {
|
||||||
|
return appRTCAudioManager;
|
||||||
|
}
|
||||||
|
|
||||||
private static abstract class SetSdpObserver implements SdpObserver {
|
private static abstract class SetSdpObserver implements SdpObserver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
BIN
src/main/res/drawable-hdpi/ic_bluetooth_audio_black_24dp.png
Normal file
After Width: | Height: | Size: 420 B |
BIN
src/main/res/drawable-hdpi/ic_headset_black_24dp.png
Normal file
After Width: | Height: | Size: 349 B |
BIN
src/main/res/drawable-mdpi/ic_bluetooth_audio_black_24dp.png
Normal file
After Width: | Height: | Size: 283 B |
BIN
src/main/res/drawable-mdpi/ic_headset_black_24dp.png
Normal file
After Width: | Height: | Size: 230 B |
BIN
src/main/res/drawable-xhdpi/ic_bluetooth_audio_black_24dp.png
Normal file
After Width: | Height: | Size: 479 B |
BIN
src/main/res/drawable-xhdpi/ic_headset_black_24dp.png
Normal file
After Width: | Height: | Size: 412 B |
BIN
src/main/res/drawable-xxhdpi/ic_bluetooth_audio_black_24dp.png
Normal file
After Width: | Height: | Size: 724 B |
BIN
src/main/res/drawable-xxhdpi/ic_headset_black_24dp.png
Normal file
After Width: | Height: | Size: 586 B |
BIN
src/main/res/drawable-xxxhdpi/ic_bluetooth_audio_black_24dp.png
Normal file
After Width: | Height: | Size: 867 B |
BIN
src/main/res/drawable-xxxhdpi/ic_headset_black_24dp.png
Normal file
After Width: | Height: | Size: 786 B |