display status information in ui

This commit is contained in:
Daniel Gultsch 2020-04-07 14:22:12 +02:00
parent a9a35fb74b
commit 0e88b56eb4
7 changed files with 84 additions and 18 deletions

View file

@ -32,6 +32,7 @@
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission <uses-permission
android:name="android.permission.READ_PHONE_STATE" android:name="android.permission.READ_PHONE_STATE"

View file

@ -37,8 +37,13 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_rtp_session); this.binding = DataBindingUtil.setContentView(this, R.layout.activity_rtp_session);
this.binding.acceptCall.setOnClickListener(this::acceptCall);
this.binding.rejectCall.setOnClickListener(this::rejectCall); this.binding.rejectCall.setOnClickListener(this::rejectCall);
this.binding.endCall.setOnClickListener(this::endCall);
this.binding.acceptCall.setOnClickListener(this::acceptCall);
}
private void endCall(View view) {
requireRtpConnection().endCall();
} }
private void rejectCall(View view) { private void rejectCall(View view) {
@ -70,11 +75,13 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
} }
this.rtpConnectionReference = reference; this.rtpConnectionReference = reference;
binding.with.setText(getWith().getDisplayName()); binding.with.setText(getWith().getDisplayName());
showState(requireRtpConnection().getEndUserState()); final RtpEndUserState currentState = requireRtpConnection().getEndUserState();
updateStateDisplay(currentState);
updateButtonConfiguration(currentState);
} }
} }
private void showState(final RtpEndUserState state) { private void updateStateDisplay(final RtpEndUserState state) {
switch (state) { switch (state) {
case INCOMING_CALL: case INCOMING_CALL:
binding.status.setText(R.string.rtp_state_incoming_call); binding.status.setText(R.string.rtp_state_incoming_call);
@ -88,6 +95,25 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
case ACCEPTING_CALL: case ACCEPTING_CALL:
binding.status.setText(R.string.rtp_state_accepting_call); binding.status.setText(R.string.rtp_state_accepting_call);
break; break;
case ENDING_CALL:
binding.status.setText(R.string.rtp_state_ending_call);
break;
}
}
private void updateButtonConfiguration(final RtpEndUserState state) {
if (state == RtpEndUserState.INCOMING_CALL) {
this.binding.rejectCall.show();
this.binding.endCall.hide();
this.binding.acceptCall.show();
} else if (state == RtpEndUserState.ENDING_CALL) {
this.binding.rejectCall.hide();
this.binding.endCall.hide();
this.binding.acceptCall.hide();
} else {
this.binding.rejectCall.hide();
this.binding.endCall.show();
this.binding.acceptCall.hide();
} }
} }
@ -110,7 +136,8 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
final AbstractJingleConnection.Id id = requireRtpConnection().getId(); final AbstractJingleConnection.Id id = requireRtpConnection().getId();
if (account == id.account && id.with.equals(with)) { if (account == id.account && id.with.equals(with)) {
runOnUiThread(()->{ runOnUiThread(()->{
showState(state); updateStateDisplay(state);
updateButtonConfiguration(state);
}); });
} else { } else {
Log.d(Config.LOGTAG,"received update for other rtp session"); Log.d(Config.LOGTAG,"received update for other rtp session");

View file

@ -317,6 +317,8 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
return RtpEndUserState.CONNECTED; return RtpEndUserState.CONNECTED;
} else if (state == PeerConnection.PeerConnectionState.NEW || state == PeerConnection.PeerConnectionState.CONNECTING) { } else if (state == PeerConnection.PeerConnectionState.NEW || state == PeerConnection.PeerConnectionState.CONNECTING) {
return RtpEndUserState.CONNECTING; return RtpEndUserState.CONNECTING;
} else if (state == PeerConnection.PeerConnectionState.CLOSED) {
return RtpEndUserState.ENDING_CALL;
} else { } else {
return RtpEndUserState.FAILED; return RtpEndUserState.FAILED;
} }
@ -342,6 +344,14 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
Log.d(Config.LOGTAG, "todo rejecting call"); Log.d(Config.LOGTAG, "todo rejecting call");
} }
public void endCall() {
if (isInState(State.SESSION_INITIALIZED, State.SESSION_ACCEPTED)) {
webRTCWrapper.close();
} else {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": called 'endCall' while in state " + this.state);
}
}
private void setupWebRTC() { private void setupWebRTC() {
this.webRTCWrapper.setup(this.xmppConnectionService); this.webRTCWrapper.setup(this.xmppConnectionService);
this.webRTCWrapper.initializePeerConnection(); this.webRTCWrapper.initializePeerConnection();
@ -392,6 +402,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
@Override @Override
public void onConnectionChange(PeerConnection.PeerConnectionState newState) { public void onConnectionChange(PeerConnection.PeerConnectionState newState) {
Log.d(Config.LOGTAG,id.account.getJid().asBareJid()+": PeerConnectionState changed to "+newState);
updateEndUserState(); updateEndUserState();
} }

View file

@ -8,5 +8,6 @@ public enum RtpEndUserState {
RINGING, //'propose' has been sent out and it has been 184 acked RINGING, //'propose' has been sent out and it has been 184 acked
ACCEPTED_ON_OTHER_DEVICE, //received 'accept' from one of our own devices ACCEPTED_ON_OTHER_DEVICE, //received 'accept' from one of our own devices
ACCEPTING_CALL, //'proceed' message has been sent; but no session-initiate has been received ACCEPTING_CALL, //'proceed' message has been sent; but no session-initiate has been received
ENDING_CALL, //libwebrt says 'closed' but session-terminate hasnt gone through
FAILED //something went wrong. TODO needs more concrete error states FAILED //something went wrong. TODO needs more concrete error states
} }

View file

@ -81,8 +81,8 @@ public class WebRTCWrapper {
@Override @Override
public void onAddStream(MediaStream mediaStream) { public void onAddStream(MediaStream mediaStream) {
Log.d(Config.LOGTAG, "onAddStream"); Log.d(Config.LOGTAG, "onAddStream");
for(AudioTrack audioTrack : mediaStream.audioTracks) { for (AudioTrack audioTrack : mediaStream.audioTracks) {
Log.d(Config.LOGTAG,"remote? - audioTrack enabled:"+audioTrack.enabled()+" state="+audioTrack.state()); Log.d(Config.LOGTAG, "remote? - audioTrack enabled:" + audioTrack.enabled() + " state=" + audioTrack.state());
} }
final List<VideoTrack> videoTracks = mediaStream.videoTracks; final List<VideoTrack> videoTracks = mediaStream.videoTracks;
if (videoTracks.size() > 0) { if (videoTracks.size() > 0) {
@ -130,8 +130,8 @@ public class WebRTCWrapper {
CameraVideoCapturer capturer = null; CameraVideoCapturer capturer = null;
Camera1Enumerator camera1Enumerator = new Camera1Enumerator(); Camera1Enumerator camera1Enumerator = new Camera1Enumerator();
for(String deviceName : camera1Enumerator.getDeviceNames()) { for (String deviceName : camera1Enumerator.getDeviceNames()) {
Log.d(Config.LOGTAG,"camera device name: "+deviceName); Log.d(Config.LOGTAG, "camera device name: " + deviceName);
if (camera1Enumerator.isFrontFacing(deviceName)) { if (camera1Enumerator.isFrontFacing(deviceName)) {
capturer = camera1Enumerator.createCapturer(deviceName, new CameraVideoCapturer.CameraEventsHandler() { capturer = camera1Enumerator.createCapturer(deviceName, new CameraVideoCapturer.CameraEventsHandler() {
@Override @Override
@ -151,12 +151,12 @@ public class WebRTCWrapper {
@Override @Override
public void onCameraOpening(String s) { public void onCameraOpening(String s) {
Log.d(Config.LOGTAG,"onCameraOpening"); Log.d(Config.LOGTAG, "onCameraOpening");
} }
@Override @Override
public void onFirstFrameAvailable() { public void onFirstFrameAvailable() {
Log.d(Config.LOGTAG,"onFirstFrameAvailable"); Log.d(Config.LOGTAG, "onFirstFrameAvailable");
} }
@Override @Override
@ -179,7 +179,7 @@ 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); final AudioTrack audioTrack = peerConnectionFactory.createAudioTrack("my-audio-track", audioSource);
Log.d(Config.LOGTAG,"audioTrack enabled:"+audioTrack.enabled()+" state="+audioTrack.state()); 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(audioTrack);
//stream.addTrack(videoTrack); //stream.addTrack(videoTrack);
@ -200,6 +200,9 @@ public class WebRTCWrapper {
this.peerConnection = peerConnection; this.peerConnection = peerConnection;
} }
public void close() {
requirePeerConnection().close();
}
public ListenableFuture<SessionDescription> createOffer() { public ListenableFuture<SessionDescription> createOffer() {
@ -287,15 +290,19 @@ public class WebRTCWrapper {
} }
public void addIceCandidate(IceCandidate iceCandidate) { public void addIceCandidate(IceCandidate iceCandidate) {
requirePeerConnection().addIceCandidate(iceCandidate);
}
public PeerConnection.PeerConnectionState getState() {
return requirePeerConnection().connectionState();
}
private PeerConnection requirePeerConnection() {
final PeerConnection peerConnection = this.peerConnection; final PeerConnection peerConnection = this.peerConnection;
if (peerConnection == null) { if (peerConnection == null) {
throw new IllegalStateException("initialize PeerConnection first"); throw new IllegalStateException("initialize PeerConnection first");
} }
peerConnection.addIceCandidate(iceCandidate); return peerConnection;
}
public PeerConnection.PeerConnectionState getState() {
return this.peerConnection.connectionState();
} }
private static abstract class SetSdpObserver implements SdpObserver { private static abstract class SetSdpObserver implements SdpObserver {
@ -329,6 +336,7 @@ public class WebRTCWrapper {
public interface EventCallback { public interface EventCallback {
void onIceCandidate(IceCandidate iceCandidate); void onIceCandidate(IceCandidate iceCandidate);
void onConnectionChange(PeerConnection.PeerConnectionState newState); void onConnectionChange(PeerConnection.PeerConnectionState newState);
} }
} }

View file

@ -54,7 +54,22 @@
app:backgroundTint="@color/red700" app:backgroundTint="@color/red700"
app:elevation="4dp" app:elevation="4dp"
app:fabCustomSize="72dp" app:fabCustomSize="72dp"
app:maxImageSize="36dp" /> app:maxImageSize="36dp"
android:visibility="gone"
tools:visibility="visible"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/end_call"
android:layout_width="wrap_content"
android:layout_margin="16dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/ic_call_end_white_48dp"
app:backgroundTint="@color/red700"
app:elevation="4dp"
app:fabCustomSize="72dp"
app:maxImageSize="36dp"
android:visibility="gone"/>
<android.support.design.widget.FloatingActionButton <android.support.design.widget.FloatingActionButton
android:id="@+id/accept_call" android:id="@+id/accept_call"
@ -68,7 +83,9 @@
app:backgroundTint="@color/green700" app:backgroundTint="@color/green700"
app:elevation="4dp" app:elevation="4dp"
app:fabCustomSize="72dp" app:fabCustomSize="72dp"
app:maxImageSize="36dp" /> app:maxImageSize="36dp"
android:visibility="gone"
tools:visibility="visible"/>
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>

View file

@ -889,6 +889,7 @@
<string name="rtp_state_connecting">Connecting</string> <string name="rtp_state_connecting">Connecting</string>
<string name="rtp_state_connected">Connected</string> <string name="rtp_state_connected">Connected</string>
<string name="rtp_state_accepting_call">Accepting call</string> <string name="rtp_state_accepting_call">Accepting call</string>
<string name="rtp_state_ending_call">Ending call</string>
<plurals name="view_users"> <plurals name="view_users">
<item quantity="one">View %1$d Participant</item> <item quantity="one">View %1$d Participant</item>
<item quantity="other">View %1$d Participants</item> <item quantity="other">View %1$d Participants</item>