diff --git a/src/main/java/eu/siacs/conversations/services/CallIntegration.java b/src/main/java/eu/siacs/conversations/services/CallIntegration.java index bf12f5f4b..fbd3e8c2c 100644 --- a/src/main/java/eu/siacs/conversations/services/CallIntegration.java +++ b/src/main/java/eu/siacs/conversations/services/CallIntegration.java @@ -60,7 +60,7 @@ public class CallIntegration extends Connection { @Override public void onAnswer() { - Log.d(Config.LOGTAG, "onAnswer()"); + this.callback.onCallIntegrationAnswer(); } @Override @@ -71,12 +71,13 @@ public class CallIntegration extends Connection { @Override public void onReject() { - Log.d(Config.LOGTAG, "onReject()"); + this.callback.onCallIntegrationReject(); } @Override public void onReject(final String replyMessage) { Log.d(Config.LOGTAG, "onReject(" + replyMessage + ")"); + this.callback.onCallIntegrationReject(); } @RequiresApi(api = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) @@ -404,5 +405,9 @@ public class CallIntegration extends Connection { void onAudioDeviceChanged( CallIntegration.AudioDevice selectedAudioDevice, Set availableAudioDevices); + + void onCallIntegrationReject(); + + void onCallIntegrationAnswer(); } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index 8153dc254..9101b939a 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -1109,5 +1109,15 @@ public class JingleConnectionManager extends AbstractConnectionManager { public void onAudioDeviceChanged( CallIntegration.AudioDevice selectedAudioDevice, Set availableAudioDevices) {} + + @Override + public void onCallIntegrationReject() { + + } + + @Override + public void onCallIntegrationAnswer() { + + } } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index 8d5aa8dfd..2ecd91253 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -1,6 +1,6 @@ package eu.siacs.conversations.xmpp.jingle; -import android.telecom.Call; +import android.content.Intent; import android.telecom.TelecomManager; import android.util.Log; @@ -35,6 +35,7 @@ import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.RtpSessionStatus; import eu.siacs.conversations.services.AppRTCAudioManager; import eu.siacs.conversations.services.CallIntegration; +import eu.siacs.conversations.ui.RtpSessionActivity; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xml.Namespace; import eu.siacs.conversations.xmpp.Jid; @@ -75,7 +76,8 @@ public class JingleRtpConnection extends AbstractJingleConnection private static final long BUSY_TIME_OUT = 30; private final WebRTCWrapper webRTCWrapper = new WebRTCWrapper(this); - private final Queue>> + private final Queue< + Map.Entry>> pendingIceCandidates = new LinkedList<>(); private final OmemoVerification omemoVerification = new OmemoVerification(); private final CallIntegration callIntegration; @@ -91,13 +93,28 @@ public class JingleRtpConnection extends AbstractJingleConnection private final Queue stateHistory = new LinkedList<>(); private ScheduledFuture ringingTimeoutFuture; - JingleRtpConnection(final JingleConnectionManager jingleConnectionManager, final Id id, final Jid initiator) { - this(jingleConnectionManager, id, initiator, new CallIntegration(jingleConnectionManager.getXmppConnectionService().getApplicationContext())); - this.callIntegration.setAddress(CallIntegration.address(id.with.asBareJid()), TelecomManager.PRESENTATION_ALLOWED); + JingleRtpConnection( + final JingleConnectionManager jingleConnectionManager, + final Id id, + final Jid initiator) { + this( + jingleConnectionManager, + id, + initiator, + new CallIntegration( + jingleConnectionManager + .getXmppConnectionService() + .getApplicationContext())); + this.callIntegration.setAddress( + CallIntegration.address(id.with.asBareJid()), TelecomManager.PRESENTATION_ALLOWED); this.callIntegration.setInitialized(); } - JingleRtpConnection(final JingleConnectionManager jingleConnectionManager, final Id id, final Jid initiator, final CallIntegration callIntegration) { + JingleRtpConnection( + final JingleConnectionManager jingleConnectionManager, + final Id id, + final Jid initiator, + final CallIntegration callIntegration) { super(jingleConnectionManager, id, initiator); final Conversation conversation = jingleConnectionManager @@ -231,8 +248,8 @@ public class JingleRtpConnection extends AbstractJingleConnection private void receiveTransportInfo( final JinglePacket jinglePacket, final RtpContentMap contentMap) { - final Set>> candidates = - contentMap.contents.entrySet(); + final Set>> + candidates = contentMap.contents.entrySet(); final RtpContentMap remote = getRemoteContentMap(); final Set remoteContentIds = remote == null ? Collections.emptySet() : remote.contents.keySet(); @@ -1004,14 +1021,17 @@ public class JingleRtpConnection extends AbstractJingleConnection } private void processCandidates( - final Set>> contents) { - for (final Map.Entry> content : contents) { + final Set>> + contents) { + for (final Map.Entry> + content : contents) { processCandidate(content); } } private void processCandidate( - final Map.Entry> content) { + final Map.Entry> + content) { final RtpContentMap rtpContentMap = getRemoteContentMap(); final List indices = toIdentificationTags(rtpContentMap); final String sdpMid = content.getKey(); // aka content name @@ -1382,7 +1402,7 @@ public class JingleRtpConnection extends AbstractJingleConnection } private void addIceCandidatesFromBlackLog() { - Map.Entry> foo; + Map.Entry> foo; while ((foo = this.pendingIceCandidates.poll()) != null) { processCandidate(foo); Log.d( @@ -1960,12 +1980,10 @@ public class JingleRtpConnection extends AbstractJingleConnection sendSessionTerminate(reason, null); } - protected void sendSessionTerminate(final Reason reason, final String text) { - sendSessionTerminate(reason,text, this::writeLogMessage); + sendSessionTerminate(reason, text, this::writeLogMessage); } - private void sendTransportInfo( final String contentName, IceUdpTransportInfo.Candidate candidate) { final RtpContentMap transportInfo; @@ -2351,7 +2369,6 @@ public class JingleRtpConnection extends AbstractJingleConnection sendSessionAccept(); } - @Override protected synchronized boolean transition(final State target, final Runnable runnable) { if (super.transition(target, runnable)) { @@ -2592,7 +2609,6 @@ public class JingleRtpConnection extends AbstractJingleConnection private void modifyLocalContentMap(final RtpContentMap rtpContentMap) { final RtpContentMap activeContents = rtpContentMap.activeContents(); setLocalContentMap(activeContents); - // TODO change audio device on callIntegration was (`switchSpeakerPhonePreference(AppRTCAudioManager.SpeakerPhonePreference.of(activeContents.getMedia())`) updateEndUserState(); } @@ -2625,7 +2641,6 @@ public class JingleRtpConnection extends AbstractJingleConnection return this.sessionDuration.elapsed(TimeUnit.MILLISECONDS); } - public CallIntegration getCallIntegration() { return this.callIntegration; } @@ -2673,11 +2688,37 @@ public class JingleRtpConnection extends AbstractJingleConnection } } + @Override + public void onCallIntegrationReject() { + Log.d(Config.LOGTAG, "rejecting call from system notification / call integration"); + try { + rejectCall(); + } catch (final IllegalStateException e) { + Log.w(Config.LOGTAG, "race condition on rejecting call from notification", e); + } + } + + @Override + public void onCallIntegrationAnswer() { + // we need to start the UI to a) show it and b) be able to ask for permissions + final Intent intent = new Intent(xmppConnectionService, RtpSessionActivity.class); + intent.setAction(RtpSessionActivity.ACTION_ACCEPT_CALL); + intent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, id.account.getJid().toEscapedString()); + intent.putExtra(RtpSessionActivity.EXTRA_WITH, id.with.toEscapedString()); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + intent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, id.sessionId); + Log.d(Config.LOGTAG, "start activity to accept call from call integration"); + xmppConnectionService.startActivity(intent); + } + @Override public void onAudioDeviceChanged( final CallIntegration.AudioDevice selectedAudioDevice, final Set availableAudioDevices) { - Log.d(Config.LOGTAG,"onAudioDeviceChanged("+selectedAudioDevice+","+availableAudioDevices+")"); + Log.d( + Config.LOGTAG, + "onAudioDeviceChanged(" + selectedAudioDevice + "," + availableAudioDevices + ")"); xmppConnectionService.notifyJingleRtpConnectionUpdate( selectedAudioDevice, availableAudioDevices); } @@ -2732,7 +2773,7 @@ public class JingleRtpConnection extends AbstractJingleConnection onIceServersDiscovered.onIceServersDiscovered(Collections.emptyList()); } } - + @Override protected void terminateTransport() { this.webRTCWrapper.close();