From 0ffc2958886691a8bafc45824e7c8c49d33ac55a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 17 Jan 2024 09:18:24 +0100 Subject: [PATCH] provide alternative method to create calls for Android <8 --- .../services/CallIntegration.java | 4 + .../CallIntegrationConnectionService.java | 113 ++++++++++++------ .../ui/ConversationFragment.java | 2 +- .../conversations/ui/RtpSessionActivity.java | 2 +- 4 files changed, 84 insertions(+), 37 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/CallIntegration.java b/src/main/java/eu/siacs/conversations/services/CallIntegration.java index 051a7de9a..b9b21e578 100644 --- a/src/main/java/eu/siacs/conversations/services/CallIntegration.java +++ b/src/main/java/eu/siacs/conversations/services/CallIntegration.java @@ -381,6 +381,10 @@ public class CallIntegration extends Connection { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; } + public static boolean notSelfManaged() { + return Build.VERSION.SDK_INT < Build.VERSION_CODES.O; + } + public void setInitialAudioDevice(final AudioDevice audioDevice) { Log.d(Config.LOGTAG, "setInitialAudioDevice(" + audioDevice + ")"); this.initialAudioDevice = audioDevice; diff --git a/src/main/java/eu/siacs/conversations/services/CallIntegrationConnectionService.java b/src/main/java/eu/siacs/conversations/services/CallIntegrationConnectionService.java index e1a9b3383..71ea897c2 100644 --- a/src/main/java/eu/siacs/conversations/services/CallIntegrationConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/CallIntegrationConnectionService.java @@ -18,6 +18,8 @@ import android.telecom.TelecomManager; import android.telecom.VideoProfile; import android.util.Log; +import androidx.annotation.NonNull; + import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; @@ -44,6 +46,7 @@ public class CallIntegrationConnectionService extends ConnectionService { @Override public void onCreate() { + Log.d(Config.LOGTAG, "CallIntegrationService.onCreate()"); super.onCreate(); this.serviceFuture = ServiceConnectionService.bindService(this); } @@ -62,38 +65,39 @@ public class CallIntegrationConnectionService extends ConnectionService { this.unbindService(serviceConnection); } - @Override - public Connection onCreateOutgoingConnection( - final PhoneAccountHandle phoneAccountHandle, final ConnectionRequest request) { - Log.d(Config.LOGTAG, "onCreateOutgoingConnection(" + request.getAddress() + ")"); - final var uri = request.getAddress(); - final var jid = Jid.ofEscaped(uri.getSchemeSpecificPart()); - final var extras = request.getExtras(); - final int videoState = extras.getInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE); - final Set media = - videoState == VideoProfile.STATE_AUDIO_ONLY - ? ImmutableSet.of(Media.AUDIO) - : ImmutableSet.of(Media.AUDIO, Media.VIDEO); - Log.d(Config.LOGTAG, "jid=" + jid); - Log.d(Config.LOGTAG, "phoneAccountHandle:" + phoneAccountHandle.getId()); - Log.d(Config.LOGTAG, "media " + media); - final var service = ServiceConnectionService.get(this.serviceFuture); + private static Connection createOutgoingRtpConnection( + final XmppConnectionService service, + final String phoneAccountHandle, + final Jid with, + final Set media) { if (service == null) { + Log.d( + Config.LOGTAG, + "CallIntegrationConnection service was unable to bind to XmppConnectionService"); return Connection.createFailedConnection( new DisconnectCause(DisconnectCause.ERROR, "service connection not found")); } - final Account account = service.findAccountByUuid(phoneAccountHandle.getId()); - final Intent intent = new Intent(this, RtpSessionActivity.class); + final var account = service.findAccountByUuid(phoneAccountHandle); + return createOutgoingRtpConnection(service, account, with, media); + } + + private static Connection createOutgoingRtpConnection( + @NonNull final XmppConnectionService service, + @NonNull final Account account, + final Jid with, + final Set media) { + Log.d(Config.LOGTAG, "create outgoing rtp connection!"); + final Intent intent = new Intent(service, RtpSessionActivity.class); intent.setAction(Intent.ACTION_VIEW); intent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, account.getJid().toEscapedString()); - intent.putExtra(RtpSessionActivity.EXTRA_WITH, jid.toEscapedString()); + intent.putExtra(RtpSessionActivity.EXTRA_WITH, with.toEscapedString()); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); final CallIntegration callIntegration; - if (jid.isBareJid()) { + if (with.isBareJid()) { final var proposal = service.getJingleConnectionManager() - .proposeJingleRtpSession(account, jid, media); + .proposeJingleRtpSession(account, with, media); intent.putExtra( RtpSessionActivity.EXTRA_LAST_REPORTED_STATE, @@ -110,16 +114,35 @@ public class CallIntegrationConnectionService extends ConnectionService { callIntegration = proposal.getCallIntegration(); } else { final JingleRtpConnection jingleRtpConnection = - service.getJingleConnectionManager().initializeRtpSession(account, jid, media); + service.getJingleConnectionManager().initializeRtpSession(account, with, media); final String sessionId = jingleRtpConnection.getId().sessionId; intent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, sessionId); callIntegration = jingleRtpConnection.getCallIntegration(); } - Log.d(Config.LOGTAG, "start activity!"); - startActivity(intent); + service.startActivity(intent); return callIntegration; } + @Override + public Connection onCreateOutgoingConnection( + final PhoneAccountHandle phoneAccountHandle, final ConnectionRequest request) { + Log.d(Config.LOGTAG, "onCreateOutgoingConnection(" + request.getAddress() + ")"); + final var uri = request.getAddress(); + final var jid = Jid.ofEscaped(uri.getSchemeSpecificPart()); + final var extras = request.getExtras(); + final int videoState = extras.getInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE); + final Set media = + videoState == VideoProfile.STATE_AUDIO_ONLY + ? ImmutableSet.of(Media.AUDIO) + : ImmutableSet.of(Media.AUDIO, Media.VIDEO); + Log.d(Config.LOGTAG, "jid=" + jid); + Log.d(Config.LOGTAG, "phoneAccountHandle:" + phoneAccountHandle.getId()); + Log.d(Config.LOGTAG, "media " + media); + final var service = ServiceConnectionService.get(this.serviceFuture); + return createOutgoingRtpConnection(service, phoneAccountHandle.getId(), jid, media); + } + + @Override public Connection onCreateIncomingConnection( final PhoneAccountHandle phoneAccountHandle, final ConnectionRequest request) { Log.d(Config.LOGTAG, "onCreateIncomingConnection()"); @@ -194,22 +217,42 @@ public class CallIntegrationConnectionService extends ConnectionService { } public static void placeCall( - final Context context, final Account account, final Jid with, final Set media) { + final XmppConnectionService service, + final Account account, + final Jid with, + final Set media) { Log.d(Config.LOGTAG, "place call media=" + media); - final var extras = new Bundle(); - extras.putParcelable( - TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, getHandle(context, account)); - extras.putInt( - TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, - Media.audioOnly(media) - ? VideoProfile.STATE_AUDIO_ONLY - : VideoProfile.STATE_BIDIRECTIONAL); - context.getSystemService(TelecomManager.class) - .placeCall(CallIntegration.address(with), extras); + if (CallIntegration.selfManaged()) { + final var extras = new Bundle(); + extras.putParcelable( + TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, getHandle(service, account)); + extras.putInt( + TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, + Media.audioOnly(media) + ? VideoProfile.STATE_AUDIO_ONLY + : VideoProfile.STATE_BIDIRECTIONAL); + service.getSystemService(TelecomManager.class) + .placeCall(CallIntegration.address(with), extras); + } else { + final var connection = createOutgoingRtpConnection(service, account, with, media); + if (connection != null) { + Log.d( + Config.LOGTAG, + "not adding outgoing call to TelecomManager on Android " + + Build.VERSION.RELEASE); + } + } } public static void addNewIncomingCall( final Context context, final AbstractJingleConnection.Id id) { + if (CallIntegration.notSelfManaged()) { + Log.d( + Config.LOGTAG, + "not adding incoming call to TelecomManager on Android " + + Build.VERSION.RELEASE); + return; + } final var phoneAccountHandle = CallIntegrationConnectionService.getHandle(context, id.account); final var bundle = new Bundle(); diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 01932a04e..a00a47209 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -1653,7 +1653,7 @@ public class ConversationFragment extends XmppFragment } private void triggerRtpSession(final Account account, final Jid with, final String action) { - CallIntegrationConnectionService.placeCall(requireActivity(),account,with,RtpSessionActivity.actionToMedia(action)); + CallIntegrationConnectionService.placeCall(activity.xmppConnectionService, account,with,RtpSessionActivity.actionToMedia(action)); } private void handleAttachmentSelection(MenuItem item) { diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index 598232467..2e4576f57 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -1312,7 +1312,7 @@ public class RtpSessionActivity extends XmppActivity final Set media = actionToMedia(lastAction == null ? action : lastAction); this.rtpConnectionReference = null; Log.d(Config.LOGTAG, "attempting retry with " + with.toEscapedString()); - CallIntegrationConnectionService.placeCall(this, account, with, media); + CallIntegrationConnectionService.placeCall(xmppConnectionService, account, with, media); } private void exit(final View view) {