run RtpSessionService during phone calls
This commit is contained in:
parent
1be1334794
commit
49b4f54285
|
@ -81,6 +81,8 @@
|
|||
android:name=".service.ForegroundService"
|
||||
android:exported="false" />
|
||||
|
||||
<service android:name=".service.RtpSessionService" android:exported="false" android:foregroundServiceType="phoneCall"/>
|
||||
|
||||
<receiver
|
||||
android:name=".receiver.EventReceiver"
|
||||
android:exported="true">
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package eu.siacs.conversations.xmpp.jingle;
|
||||
|
||||
import android.content.Context;
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket;
|
||||
|
@ -84,6 +85,14 @@ public abstract class AbstractJingleConnection extends XmppConnection.Delegate {
|
|||
public int hashCode() {
|
||||
return Objects.hashCode(with, sessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MoreObjects.toStringHelper(this)
|
||||
.add("with", with)
|
||||
.add("sessionId", sessionId)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public enum State {
|
||||
|
|
|
@ -30,7 +30,9 @@ import im.conversations.android.BuildConfig;
|
|||
import im.conversations.android.axolotl.AxolotlEncryptionException;
|
||||
import im.conversations.android.axolotl.AxolotlService;
|
||||
import im.conversations.android.dns.IP;
|
||||
import im.conversations.android.notification.OngoingCall;
|
||||
import im.conversations.android.notification.RtpSessionNotification;
|
||||
import im.conversations.android.service.RtpSessionService;
|
||||
import im.conversations.android.transformer.CallLogTransformation;
|
||||
import im.conversations.android.util.BooleanFutures;
|
||||
import im.conversations.android.xml.Element;
|
||||
|
@ -592,7 +594,10 @@ public class JingleRtpConnection extends AbstractJingleConnection
|
|||
this.incomingContentAdd = null;
|
||||
updateEndUserState();
|
||||
} else {
|
||||
LOGGER.info("content add summary {} did not match remove summary {}", contentAddSummary, removeSummary);
|
||||
LOGGER.info(
|
||||
"content add summary {} did not match remove summary {}",
|
||||
contentAddSummary,
|
||||
removeSummary);
|
||||
webRTCWrapper.close();
|
||||
sendSessionTerminate(
|
||||
Reason.FAILED_APPLICATION,
|
||||
|
@ -2424,6 +2429,7 @@ public class JingleRtpConnection extends AbstractJingleConnection
|
|||
this.webRTCWrapper.switchSpeakerPhonePreference(
|
||||
AppRTCAudioManager.SpeakerPhonePreference.of(activeContents.getMedia()));
|
||||
updateEndUserState();
|
||||
updateOngoingCallNotification();
|
||||
}
|
||||
|
||||
private SessionDescription setLocalSessionDescription()
|
||||
|
@ -2505,21 +2511,26 @@ public class JingleRtpConnection extends AbstractJingleConnection
|
|||
private void updateOngoingCallNotification() {
|
||||
final State state = this.state;
|
||||
if (STATES_SHOWING_ONGOING_CALL.contains(state)) {
|
||||
final boolean reconnecting;
|
||||
RtpSessionService.updateOngoingCall(context, getAccount().id, id);
|
||||
} else {
|
||||
RtpSessionService.stop(context);
|
||||
}
|
||||
}
|
||||
|
||||
public OngoingCall getOngoingCall() {
|
||||
final State state = this.state;
|
||||
final boolean reconnecting;
|
||||
if (STATES_SHOWING_ONGOING_CALL.contains(state)) {
|
||||
if (state == State.SESSION_ACCEPTED) {
|
||||
reconnecting =
|
||||
getPeerConnectionStateAsEndUserState() == RtpEndUserState.RECONNECTING;
|
||||
} else {
|
||||
reconnecting = false;
|
||||
}
|
||||
|
||||
// TODO decide what we want to do with ongoing call? create a foreground service of
|
||||
// RtpSessionService?
|
||||
|
||||
// xmppConnectionService.setOngoingCall(id, getMedia(), reconnecting);
|
||||
} else {
|
||||
// xmppConnectionService.removeOngoingCall();
|
||||
reconnecting = false;
|
||||
}
|
||||
return new OngoingCall(id, getMedia(), reconnecting);
|
||||
}
|
||||
|
||||
private void discoverIceServers(final OnIceServersDiscovered onIceServersDiscovered) {
|
||||
|
|
|
@ -38,7 +38,9 @@ class TrackWrapper<T extends MediaStreamTrack> {
|
|||
final RtpTransceiver transceiver =
|
||||
peerConnection == null ? null : getTransceiver(peerConnection, trackWrapper);
|
||||
if (transceiver == null) {
|
||||
Log.w(Config.LOGTAG, "unable to detect transceiver for " + trackWrapper.getRtpSenderId());
|
||||
Log.w(
|
||||
Config.LOGTAG,
|
||||
"unable to detect transceiver for " + trackWrapper.getRtpSenderId());
|
||||
return Optional.of(trackWrapper.track);
|
||||
}
|
||||
final RtpTransceiver.RtpTransceiverDirection direction = transceiver.getDirection();
|
||||
|
@ -62,10 +64,13 @@ class TrackWrapper<T extends MediaStreamTrack> {
|
|||
public static <T extends MediaStreamTrack> RtpTransceiver getTransceiver(
|
||||
@Nonnull final PeerConnection peerConnection, final TrackWrapper<T> trackWrapper) {
|
||||
final String rtpSenderId = trackWrapper.getRtpSenderId();
|
||||
if (rtpSenderId == null) {
|
||||
return null;
|
||||
}
|
||||
for (final RtpTransceiver transceiver : peerConnection.getTransceivers()) {
|
||||
if (transceiver.getSender().id().equals(rtpSenderId)) {
|
||||
return transceiver;
|
||||
}
|
||||
if (transceiver.getSender().id().equals(rtpSenderId)) {
|
||||
return transceiver;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@ import im.conversations.android.R;
|
|||
public final class Channels {
|
||||
|
||||
static final String CHANNEL_FOREGROUND = "foreground";
|
||||
static final String INCOMING_CALLS_NOTIFICATION_CHANNEL = "incoming_calls_channel";
|
||||
static final String CHANNEL_INCOMING_CALL = "incoming_calls_channel";
|
||||
static final String CHANNEL_ONGOING_CALL = "ongoing_call";
|
||||
static final String CHANNEL_GROUP_STATUS = "status";
|
||||
static final String CHANNEL_GROUP_CALLS = "calls";
|
||||
private final Application application;
|
||||
|
@ -32,9 +33,22 @@ public final class Channels {
|
|||
this.initializeForegroundChannel(notificationManager);
|
||||
|
||||
this.initializeIncomingCallChannel(notificationManager);
|
||||
this.initializeOngoingCallChannel(notificationManager);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
private void initializeOngoingCallChannel(NotificationManager notificationManager) {
|
||||
final NotificationChannel ongoingCallsChannel =
|
||||
new NotificationChannel(
|
||||
CHANNEL_ONGOING_CALL,
|
||||
application.getString(R.string.ongoing_calls_channel_name),
|
||||
NotificationManager.IMPORTANCE_LOW);
|
||||
ongoingCallsChannel.setShowBadge(false);
|
||||
ongoingCallsChannel.setGroup(CHANNEL_GROUP_CALLS);
|
||||
notificationManager.createNotificationChannel(ongoingCallsChannel);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
private void initializeGroups(NotificationManager notificationManager) {
|
||||
notificationManager.createNotificationChannelGroup(
|
||||
|
@ -67,7 +81,7 @@ public final class Channels {
|
|||
private void initializeIncomingCallChannel(final NotificationManager notificationManager) {
|
||||
final NotificationChannel incomingCallsChannel =
|
||||
new NotificationChannel(
|
||||
INCOMING_CALLS_NOTIFICATION_CHANNEL,
|
||||
CHANNEL_INCOMING_CALL,
|
||||
application.getString(R.string.incoming_calls_channel_name),
|
||||
NotificationManager.IMPORTANCE_HIGH);
|
||||
incomingCallsChannel.setSound(null, null);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package im.conversations.android.notification;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Objects;
|
||||
import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection;
|
||||
import eu.siacs.conversations.xmpp.jingle.Media;
|
||||
|
@ -31,4 +32,13 @@ public class OngoingCall {
|
|||
public int hashCode() {
|
||||
return Objects.hashCode(id, media, reconnecting);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MoreObjects.toStringHelper(this)
|
||||
.add("id", id)
|
||||
.add("media", media)
|
||||
.add("reconnecting", reconnecting)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import android.net.Uri;
|
|||
import android.os.Build;
|
||||
import android.os.Vibrator;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
@ -40,6 +41,7 @@ public class RtpSessionNotification extends AbstractNotification {
|
|||
private static final Logger LOGGER = LoggerFactory.getLogger(RtpSessionNotification.class);
|
||||
|
||||
public static final int INCOMING_CALL_ID = 2;
|
||||
public static final int ONGOING_CALL_ID = 3;
|
||||
|
||||
public static final int LED_COLOR = 0xff00ff00;
|
||||
|
||||
|
@ -149,8 +151,7 @@ public class RtpSessionNotification extends AbstractNotification {
|
|||
fullScreenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
fullScreenIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
final NotificationCompat.Builder builder =
|
||||
new NotificationCompat.Builder(
|
||||
context, Channels.INCOMING_CALLS_NOTIFICATION_CHANNEL);
|
||||
new NotificationCompat.Builder(context, Channels.CHANNEL_INCOMING_CALL);
|
||||
if (media.contains(Media.VIDEO)) {
|
||||
builder.setSmallIcon(R.drawable.ic_videocam_24dp);
|
||||
builder.setContentTitle(context.getString(R.string.rtp_state_incoming_video_call));
|
||||
|
@ -181,7 +182,7 @@ public class RtpSessionNotification extends AbstractNotification {
|
|||
R.drawable.ic_call_end_24dp,
|
||||
context.getString(R.string.dismiss_call),
|
||||
createCallAction(
|
||||
id.sessionId, RtpSessionService.ACTION_DISMISS_CALL, 102))
|
||||
account, id, RtpSessionService.ACTION_REJECT_CALL, 102))
|
||||
.build());
|
||||
builder.addAction(
|
||||
new NotificationCompat.Action.Builder(
|
||||
|
@ -199,7 +200,7 @@ public class RtpSessionNotification extends AbstractNotification {
|
|||
public Notification getOngoingCallNotification(final Account account, OngoingCall ongoingCall) {
|
||||
final AbstractJingleConnection.Id id = ongoingCall.id;
|
||||
final NotificationCompat.Builder builder =
|
||||
new NotificationCompat.Builder(context, "ongoing_calls");
|
||||
new NotificationCompat.Builder(context, Channels.CHANNEL_ONGOING_CALL);
|
||||
if (ongoingCall.media.contains(Media.VIDEO)) {
|
||||
builder.setSmallIcon(R.drawable.ic_videocam_24dp);
|
||||
if (ongoingCall.reconnecting) {
|
||||
|
@ -216,7 +217,8 @@ public class RtpSessionNotification extends AbstractNotification {
|
|||
}
|
||||
}
|
||||
// TODO fix me when we have a Contact model
|
||||
// builder.setContentText(id.account.getRoster().getContact(id.with).getDisplayName());
|
||||
builder.setContentText(
|
||||
"Contact Name"); // id.account.getRoster().getContact(id.with).getDisplayName());
|
||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
builder.setPriority(NotificationCompat.PRIORITY_HIGH);
|
||||
builder.setCategory(NotificationCompat.CATEGORY_CALL);
|
||||
|
@ -227,11 +229,26 @@ public class RtpSessionNotification extends AbstractNotification {
|
|||
R.drawable.ic_call_end_24dp,
|
||||
context.getString(R.string.hang_up),
|
||||
createCallAction(
|
||||
id.sessionId, RtpSessionService.ACTION_END_CALL, 104))
|
||||
account, id, RtpSessionService.ACTION_END_CALL, 104))
|
||||
.build());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static boolean isShowingOngoingCallNotification(final Context context) {
|
||||
final var notificationManager =
|
||||
ContextCompat.getSystemService(context, NotificationManager.class);
|
||||
if (notificationManager == null) {
|
||||
return false;
|
||||
}
|
||||
for (final StatusBarNotification statusBarNotification :
|
||||
notificationManager.getActiveNotifications()) {
|
||||
if (statusBarNotification.getId() == ONGOING_CALL_ID) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private PendingIntent createPendingRtpSession(
|
||||
final Account account,
|
||||
final AbstractJingleConnection.Id id,
|
||||
|
@ -249,11 +266,14 @@ public class RtpSessionNotification extends AbstractNotification {
|
|||
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
}
|
||||
|
||||
private PendingIntent createCallAction(String sessionId, final String action, int requestCode) {
|
||||
private PendingIntent createCallAction(
|
||||
Account account, AbstractJingleConnection.Id id, final String action, int requestCode) {
|
||||
final Intent intent = new Intent(context, RtpSessionService.class);
|
||||
intent.setAction(action);
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, sessionId);
|
||||
intent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, account.id);
|
||||
intent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, id.sessionId);
|
||||
intent.putExtra(RtpSessionActivity.EXTRA_WITH, id.with.toString());
|
||||
return PendingIntent.getService(
|
||||
context,
|
||||
requestCode,
|
||||
|
@ -273,6 +293,8 @@ public class RtpSessionNotification extends AbstractNotification {
|
|||
|
||||
public void pushMissedCallNow(CallLogTransformation message) {}
|
||||
|
||||
public void cancelOngoingCallNotification() {}
|
||||
|
||||
private class VibrationRunnable implements Runnable {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.content.Intent;
|
|||
import androidx.core.content.ContextCompat;
|
||||
import androidx.lifecycle.LifecycleService;
|
||||
import im.conversations.android.notification.ForegroundServiceNotification;
|
||||
import im.conversations.android.notification.RtpSessionNotification;
|
||||
import im.conversations.android.xmpp.ConnectionPool;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -19,7 +20,6 @@ public class ForegroundService extends LifecycleService {
|
|||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
LOGGER.info("Creating service");
|
||||
final var pool = ConnectionPool.getInstance(this);
|
||||
startForeground(
|
||||
ForegroundServiceNotification.ID,
|
||||
|
@ -39,6 +39,14 @@ public class ForegroundService extends LifecycleService {
|
|||
}
|
||||
|
||||
public static void start(final Context context) {
|
||||
if (RtpSessionNotification.isShowingOngoingCallNotification(context)) {
|
||||
LOGGER.info("Do not start foreground service. Ongoing call.");
|
||||
return;
|
||||
}
|
||||
startForegroundService(context);
|
||||
}
|
||||
|
||||
static void startForegroundService(final Context context) {
|
||||
try {
|
||||
ContextCompat.startForegroundService(
|
||||
context, new Intent(context, ForegroundService.class));
|
||||
|
@ -46,4 +54,9 @@ public class ForegroundService extends LifecycleService {
|
|||
LOGGER.error("Could not start foreground service", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void stop(final Context context) {
|
||||
final var intent = new Intent(context, ForegroundService.class);
|
||||
context.stopService(intent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,153 @@
|
|||
package im.conversations.android.service;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.lifecycle.LifecycleService;
|
||||
import com.google.common.base.Strings;
|
||||
import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection;
|
||||
import eu.siacs.conversations.xmpp.jingle.JingleRtpConnection;
|
||||
import im.conversations.android.notification.RtpSessionNotification;
|
||||
import im.conversations.android.ui.activity.RtpSessionActivity;
|
||||
import im.conversations.android.xmpp.ConnectionPool;
|
||||
import im.conversations.android.xmpp.manager.JingleConnectionManager;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RtpSessionService extends LifecycleService {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RtpSessionService.class);
|
||||
|
||||
public static final String ACTION_DISMISS_CALL = "dismiss_call";
|
||||
public static final String ACTION_REJECT_CALL = "dismiss_call";
|
||||
public static final String ACTION_END_CALL = "end_call";
|
||||
|
||||
public static final String ACTION_UPDATE_ONGOING_CALL = "update_ongoing_call";
|
||||
|
||||
@Override
|
||||
public int onStartCommand(final Intent intent, final int flags, final int startId) {
|
||||
|
||||
if (intent == null) {
|
||||
LOGGER.info("Intent was null");
|
||||
return Service.START_NOT_STICKY;
|
||||
}
|
||||
final String sessionId = intent.getStringExtra(RtpSessionActivity.EXTRA_SESSION_ID);
|
||||
final long accountId = intent.getLongExtra(RtpSessionActivity.EXTRA_ACCOUNT, -1);
|
||||
final String with = intent.getStringExtra(RtpSessionActivity.EXTRA_WITH);
|
||||
if (Strings.isNullOrEmpty(sessionId) || accountId < 0 || Strings.isNullOrEmpty(with)) {
|
||||
LOGGER.warn("intent was missing mandatory extras");
|
||||
return Service.START_NOT_STICKY;
|
||||
}
|
||||
final String action = intent.getAction();
|
||||
switch (Strings.nullToEmpty(action)) {
|
||||
case ACTION_UPDATE_ONGOING_CALL:
|
||||
updateOngoingCall(accountId, JidCreate.fromOrThrowUnchecked(with), sessionId);
|
||||
break;
|
||||
case ACTION_REJECT_CALL:
|
||||
rejectCall(accountId, JidCreate.fromOrThrowUnchecked(with), sessionId);
|
||||
break;
|
||||
case ACTION_END_CALL:
|
||||
endCall(accountId, JidCreate.fromOrThrowUnchecked(with), sessionId);
|
||||
break;
|
||||
default:
|
||||
LOGGER.error("Service does not know how to handle {} action", action);
|
||||
}
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
|
||||
private void endCall(final long account, final Jid with, final String sessionId) {
|
||||
final var jmc =
|
||||
ConnectionPool.getInstance(this)
|
||||
.getOptional(account)
|
||||
.transform(xc -> xc.getManager(JingleConnectionManager.class));
|
||||
if (jmc.isPresent()) {
|
||||
endCall(jmc.get(), with, sessionId);
|
||||
} else {
|
||||
LOGGER.error("Could not end call. JingleConnectionManager not found");
|
||||
}
|
||||
}
|
||||
|
||||
private void endCall(
|
||||
final JingleConnectionManager jingleConnectionManager,
|
||||
final Jid with,
|
||||
final String sessionId) {
|
||||
final var rtpConnection = jingleConnectionManager.getJingleRtpConnection(with, sessionId);
|
||||
if (rtpConnection.isPresent()) {
|
||||
rtpConnection.get().endCall();
|
||||
} else {
|
||||
LOGGER.error("Could not end {} with {}", sessionId, with);
|
||||
}
|
||||
}
|
||||
|
||||
private void rejectCall(long account, Jid with, String sessionId) {
|
||||
final var jmc =
|
||||
ConnectionPool.getInstance(this)
|
||||
.getOptional(account)
|
||||
.transform(xc -> xc.getManager(JingleConnectionManager.class));
|
||||
if (jmc.isPresent()) {
|
||||
rejectCall(jmc.get(), with, sessionId);
|
||||
} else {
|
||||
LOGGER.error("Could not reject call. JingleConnectionManager not found");
|
||||
}
|
||||
}
|
||||
|
||||
private void rejectCall(
|
||||
JingleConnectionManager jingleConnectionManager, Jid with, String sessionId) {
|
||||
final var rtpConnection = jingleConnectionManager.getJingleRtpConnection(with, sessionId);
|
||||
if (rtpConnection.isPresent()) {
|
||||
rtpConnection.get().rejectCall();
|
||||
} else {
|
||||
LOGGER.error("Could not reject call {} with {}", sessionId, with);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateOngoingCall(final long account, final Jid with, final String sessionId) {
|
||||
final var jmc =
|
||||
ConnectionPool.getInstance(this)
|
||||
.getOptional(account)
|
||||
.transform(xc -> xc.getManager(JingleConnectionManager.class));
|
||||
if (jmc.isPresent()) {
|
||||
updateOngoingCall(jmc.get(), with, sessionId);
|
||||
} else {
|
||||
LOGGER.error("JingleConnectionManager not found for {}", account);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateOngoingCall(
|
||||
final JingleConnectionManager jingleConnectionManager,
|
||||
final Jid with,
|
||||
final String sessionId) {
|
||||
final var ongoingCall =
|
||||
jingleConnectionManager
|
||||
.getJingleRtpConnection(with, sessionId)
|
||||
.transform(JingleRtpConnection::getOngoingCall);
|
||||
if (ongoingCall.isPresent()) {
|
||||
LOGGER.info("Updating notification for {}", ongoingCall.get());
|
||||
ForegroundService.stop(this);
|
||||
startForeground(
|
||||
RtpSessionNotification.ONGOING_CALL_ID,
|
||||
jingleConnectionManager
|
||||
.getNotificationService()
|
||||
.getOngoingCallNotification(
|
||||
jingleConnectionManager.getAccount(), ongoingCall.get()));
|
||||
} else {
|
||||
LOGGER.error("JingleRtpConnection not found for {}", sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateOngoingCall(
|
||||
final Context context, final long account, final AbstractJingleConnection.Id id) {
|
||||
final var intent = new Intent(context, RtpSessionService.class);
|
||||
intent.setAction(ACTION_UPDATE_ONGOING_CALL);
|
||||
intent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, account);
|
||||
intent.putExtra(RtpSessionActivity.EXTRA_WITH, id.with.toString());
|
||||
intent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, id.sessionId);
|
||||
ContextCompat.startForegroundService(context, intent);
|
||||
}
|
||||
|
||||
public static void stop(final Context context) {
|
||||
final var intent = new Intent(context, RtpSessionService.class);
|
||||
context.stopService(intent);
|
||||
ForegroundService.startForegroundService(context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ public class MainActivity extends BaseActivity {
|
|||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ForegroundService.start(this);
|
||||
final ActivityMainBinding binding =
|
||||
DataBindingUtil.setContentView(this, R.layout.activity_main);
|
||||
final ViewModelProvider viewModelProvider =
|
||||
|
@ -33,4 +32,10 @@ public class MainActivity extends BaseActivity {
|
|||
});
|
||||
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
ForegroundService.start(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -732,7 +732,7 @@ public class RtpSessionActivity extends BaseActivity
|
|||
private boolean initializeActivityWithRunningRtpSession(
|
||||
final Account account, Jid with, String sessionId) {
|
||||
final WeakReference<JingleRtpConnection> reference =
|
||||
requireJingleConnectionManager().findJingleRtpConnection(with, sessionId);
|
||||
requireJingleConnectionManager().getWeakJingleRtpConnection(with, sessionId);
|
||||
if (reference == null || reference.get() == null) {
|
||||
final JingleConnectionManager.TerminatedRtpSession terminatedRtpSession =
|
||||
requireJingleConnectionManager().getTerminalSessionState(with, sessionId);
|
||||
|
|
|
@ -13,7 +13,6 @@ public class SettingsActivity extends BaseActivity {
|
|||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ForegroundService.start(this);
|
||||
final ActivitySettingsBinding binding =
|
||||
DataBindingUtil.setContentView(this, R.layout.activity_settings);
|
||||
setSupportActionBar(binding.materialToolbar);
|
||||
|
@ -36,4 +35,10 @@ public class SettingsActivity extends BaseActivity {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
ForegroundService.start(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,6 +109,10 @@ public class ConnectionPool {
|
|||
reconfigurationExecutor);
|
||||
}
|
||||
|
||||
public synchronized Optional<XmppConnection> getOptional(final long id) {
|
||||
return Iterables.tryFind(this.connections, c -> id == c.getAccount().id);
|
||||
}
|
||||
|
||||
public synchronized ListenableFuture<XmppConnection> get(final long id) {
|
||||
final var configured = Iterables.tryFind(this.connections, c -> id == c.getAccount().id);
|
||||
if (configured.isPresent()) {
|
||||
|
|
|
@ -26,6 +26,7 @@ import eu.siacs.conversations.xmpp.jingle.stanzas.Reason;
|
|||
import eu.siacs.conversations.xmpp.jingle.stanzas.RtpDescription;
|
||||
import im.conversations.android.IDs;
|
||||
import im.conversations.android.database.model.Account;
|
||||
import im.conversations.android.notification.OngoingCall;
|
||||
import im.conversations.android.notification.RtpSessionNotification;
|
||||
import im.conversations.android.xml.Element;
|
||||
import im.conversations.android.xml.Namespace;
|
||||
|
@ -522,6 +523,18 @@ public class JingleConnectionManager extends AbstractManager {
|
|||
return Optional.absent();
|
||||
}
|
||||
|
||||
public OngoingCall getOngoingCall(final String sessionId) {
|
||||
for (final Map.Entry<AbstractJingleConnection.Id, AbstractJingleConnection> entry :
|
||||
this.connections.entrySet()) {
|
||||
if (entry.getValue() instanceof JingleRtpConnection
|
||||
&& entry.getKey().sessionId.equals(sessionId)) {
|
||||
final var jingleRtpConnection = (JingleRtpConnection) entry.getValue();
|
||||
return jingleRtpConnection.getOngoingCall();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void finishConnection(final AbstractJingleConnection connection) {
|
||||
this.connections.remove(connection.getId());
|
||||
}
|
||||
|
@ -646,13 +659,21 @@ public class JingleConnectionManager extends AbstractManager {
|
|||
resendSessionProposals();
|
||||
}
|
||||
|
||||
public WeakReference<JingleRtpConnection> findJingleRtpConnection(Jid with, String sessionId) {
|
||||
public WeakReference<JingleRtpConnection> getWeakJingleRtpConnection(
|
||||
Jid with, String sessionId) {
|
||||
final var jingleRtpConnection = getJingleRtpConnection(with, sessionId);
|
||||
return jingleRtpConnection.isPresent()
|
||||
? new WeakReference<>(jingleRtpConnection.get())
|
||||
: null;
|
||||
}
|
||||
|
||||
public Optional<JingleRtpConnection> getJingleRtpConnection(Jid with, String sessionId) {
|
||||
final AbstractJingleConnection.Id id = AbstractJingleConnection.Id.of(with, sessionId);
|
||||
final AbstractJingleConnection connection = connections.get(id);
|
||||
if (connection instanceof JingleRtpConnection) {
|
||||
return new WeakReference<>((JingleRtpConnection) connection);
|
||||
return Optional.of((JingleRtpConnection) connection);
|
||||
}
|
||||
return null;
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
private void resendSessionProposals() {
|
||||
|
@ -701,34 +722,6 @@ public class JingleConnectionManager extends AbstractManager {
|
|||
}
|
||||
}
|
||||
|
||||
public void rejectRtpSession(final String sessionId) {
|
||||
for (final AbstractJingleConnection connection : this.connections.values()) {
|
||||
if (connection.getId().sessionId.equals(sessionId)) {
|
||||
if (connection instanceof JingleRtpConnection) {
|
||||
try {
|
||||
((JingleRtpConnection) connection).rejectCall();
|
||||
return;
|
||||
} catch (final IllegalStateException e) {
|
||||
Log.w(
|
||||
Config.LOGTAG,
|
||||
"race condition on rejecting call from notification",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void endRtpSession(final String sessionId) {
|
||||
for (final AbstractJingleConnection connection : this.connections.values()) {
|
||||
if (connection.getId().sessionId.equals(sessionId)) {
|
||||
if (connection instanceof JingleRtpConnection) {
|
||||
((JingleRtpConnection) connection).endCall();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void failProceed(final Jid with, final String sessionId, final String message) {
|
||||
final AbstractJingleConnection.Id id = AbstractJingleConnection.Id.of(with, sessionId);
|
||||
final AbstractJingleConnection existingJingleConnection = connections.get(id);
|
||||
|
|
Loading…
Reference in a new issue