diff --git a/app/src/main/java/org/thoughtcrime/securesms/WebRtcCallActivity.java b/app/src/main/java/org/thoughtcrime/securesms/WebRtcCallActivity.java index 208ab1abb0..a5287657ba 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/WebRtcCallActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/WebRtcCallActivity.java @@ -106,9 +106,10 @@ public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChan private static final int STANDARD_DELAY_FINISH = 1000; private static final int VIBRATE_DURATION = 50; - public static final String ANSWER_ACTION = WebRtcCallActivity.class.getCanonicalName() + ".ANSWER_ACTION"; - public static final String DENY_ACTION = WebRtcCallActivity.class.getCanonicalName() + ".DENY_ACTION"; - public static final String END_CALL_ACTION = WebRtcCallActivity.class.getCanonicalName() + ".END_CALL_ACTION"; + public static final String ANSWER_ACTION = WebRtcCallActivity.class.getCanonicalName() + ".ANSWER_ACTION"; + public static final String ANSWER_VIDEO_ACTION = WebRtcCallActivity.class.getCanonicalName() + ".ANSWER_ACTION"; + public static final String DENY_ACTION = WebRtcCallActivity.class.getCanonicalName() + ".DENY_ACTION"; + public static final String END_CALL_ACTION = WebRtcCallActivity.class.getCanonicalName() + ".END_CALL_ACTION"; public static final String EXTRA_ENABLE_VIDEO_IF_AVAILABLE = WebRtcCallActivity.class.getCanonicalName() + ".ENABLE_VIDEO_IF_AVAILABLE"; public static final String EXTRA_STARTED_FROM_FULLSCREEN = WebRtcCallActivity.class.getCanonicalName() + ".STARTED_FROM_FULLSCREEN"; @@ -302,6 +303,8 @@ public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChan private void processIntent(@NonNull Intent intent) { if (ANSWER_ACTION.equals(intent.getAction())) { handleAnswerWithAudio(); + } else if (ANSWER_VIDEO_ACTION.equals(intent.getAction())) { + handleAnswerWithVideo(); } else if (DENY_ACTION.equals(intent.getAction())) { handleDenyCall(); } else if (END_CALL_ACTION.equals(intent.getAction())) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/ActiveCallActionProcessorDelegate.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/ActiveCallActionProcessorDelegate.java index f977dc3599..57bee95d9b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/ActiveCallActionProcessorDelegate.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/ActiveCallActionProcessorDelegate.java @@ -116,24 +116,25 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor { @Override protected @NonNull WebRtcServiceState handleReceivedOfferWhileActive(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) { - RemotePeer activePeer = currentState.getCallInfoState().requireActivePeer(); + RemotePeer activePeer = currentState.getCallInfoState().requireActivePeer(); + boolean isRemoteVideoOffer = currentState.getCallSetupState(activePeer).isRemoteVideoOffer(); Log.i(tag, "handleReceivedOfferWhileActive(): call_id: " + remotePeer.getCallId()); switch (activePeer.getState()) { case DIALING: case REMOTE_RINGING: - webRtcInteractor.setCallInProgressNotification(TYPE_OUTGOING_RINGING, activePeer); + webRtcInteractor.setCallInProgressNotification(TYPE_OUTGOING_RINGING, activePeer, isRemoteVideoOffer); break; case IDLE: case ANSWERING: - webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_CONNECTING, activePeer); + webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_CONNECTING, activePeer, isRemoteVideoOffer); break; case LOCAL_RINGING: - webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_RINGING, activePeer); + webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_RINGING, activePeer, isRemoteVideoOffer); break; case CONNECTED: - webRtcInteractor.setCallInProgressNotification(TYPE_ESTABLISHED, activePeer); + webRtcInteractor.setCallInProgressNotification(TYPE_ESTABLISHED, activePeer, isRemoteVideoOffer); break; default: throw new IllegalStateException(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/AndroidCallConnection.kt b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/AndroidCallConnection.kt index fd554b132b..ca8b34046c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/AndroidCallConnection.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/AndroidCallConnection.kt @@ -23,7 +23,7 @@ class AndroidCallConnection( private val context: Context, private val recipientId: RecipientId, isOutgoing: Boolean, - isVideoCall: Boolean + private val isVideoCall: Boolean ) : Connection() { private var needToResetAudioRoute = isOutgoing && !isVideoCall @@ -38,7 +38,7 @@ class AndroidCallConnection( override fun onShowIncomingCallUi() { Log.i(TAG, "onShowIncomingCallUi()") - WebRtcCallService.update(context, CallNotificationBuilder.TYPE_INCOMING_CONNECTING, recipientId) + WebRtcCallService.update(context, CallNotificationBuilder.TYPE_INCOMING_CONNECTING, recipientId, isVideoCall) setRinging() } @@ -67,7 +67,7 @@ class AndroidCallConnection( ApplicationDependencies.getSignalCallManager().acceptCall(false) } else { val intent = Intent(context, WebRtcCallActivity::class.java) - intent.action = WebRtcCallActivity.ANSWER_ACTION + intent.action = if (isVideoCall) WebRtcCallActivity.ANSWER_VIDEO_ACTION else WebRtcCallActivity.ANSWER_ACTION intent.flags = intent.flags or Intent.FLAG_ACTIVITY_NEW_TASK context.startActivity(intent) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/BeginCallActionProcessorDelegate.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/BeginCallActionProcessorDelegate.java index 263ae1acd7..3c7903e31e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/BeginCallActionProcessorDelegate.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/BeginCallActionProcessorDelegate.java @@ -75,7 +75,10 @@ public class BeginCallActionProcessorDelegate extends WebRtcActionProcessor { Log.i(tag, "assign activePeer callId: " + remotePeer.getCallId() + " key: " + remotePeer.hashCode()); - webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_CONNECTING, remotePeer); + + boolean isRemoteVideoOffer = currentState.getCallSetupState(remotePeer).isRemoteVideoOffer(); + + webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_CONNECTING, remotePeer, isRemoteVideoOffer); webRtcInteractor.retrieveTurnServers(remotePeer); webRtcInteractor.initializeAudioForCall(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallSetupActionProcessorDelegate.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallSetupActionProcessorDelegate.java index 3c0a9319e5..54eae3365b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallSetupActionProcessorDelegate.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallSetupActionProcessorDelegate.java @@ -64,7 +64,9 @@ public class CallSetupActionProcessorDelegate extends WebRtcActionProcessor { .changeLocalDeviceState() .build(); - webRtcInteractor.setCallInProgressNotification(TYPE_ESTABLISHED, activePeer); + boolean isRemoteVideoOffer = currentState.getCallSetupState(activePeer).isRemoteVideoOffer(); + + webRtcInteractor.setCallInProgressNotification(TYPE_ESTABLISHED, activePeer, isRemoteVideoOffer); webRtcInteractor.unregisterPowerButtonReceiver(); try { diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupJoiningActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupJoiningActionProcessor.java index d230187d9c..d10eca2437 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupJoiningActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupJoiningActionProcessor.java @@ -65,7 +65,7 @@ public class GroupJoiningActionProcessor extends GroupActionProcessor { case CONNECTED: if (device.getJoinState() == GroupCall.JoinState.JOINED) { - webRtcInteractor.setCallInProgressNotification(TYPE_ESTABLISHED, currentState.getCallInfoState().getCallRecipient()); + webRtcInteractor.setCallInProgressNotification(TYPE_ESTABLISHED, currentState.getCallInfoState().getCallRecipient(), true); webRtcInteractor.startAudioCommunication(); if (currentState.getLocalDeviceState().getCameraState().isEnabled()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java index b23f3ae372..167cf73b90 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java @@ -158,7 +158,7 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor { currentState = WebRtcVideoUtil.reinitializeCamera(context, webRtcInteractor.getCameraEventListener(), currentState); - webRtcInteractor.setCallInProgressNotification(TYPE_OUTGOING_RINGING, currentState.getCallInfoState().getCallRecipient()); + webRtcInteractor.setCallInProgressNotification(TYPE_OUTGOING_RINGING, currentState.getCallInfoState().getCallRecipient(), true); webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context)); webRtcInteractor.initializeAudioForCall(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java index d187749d14..7d6162d23a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java @@ -205,7 +205,9 @@ public class IncomingCallActionProcessor extends DeviceAwareActionProcessor { webRtcInteractor.startIncomingRinger(ringtone, vibrateState == RecipientTable.VibrateState.ENABLED || (vibrateState == RecipientTable.VibrateState.DEFAULT && SignalStore.settings().isCallVibrateEnabled())); } - webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_RINGING, activePeer); + boolean isRemoteVideoOffer = currentState.getCallSetupState(activePeer).isRemoteVideoOffer(); + + webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_RINGING, activePeer, isRemoteVideoOffer); webRtcInteractor.registerPowerButtonReceiver(); return currentState.builder() diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingGroupCallActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingGroupCallActionProcessor.java index 55e67cf079..3f49eb32e2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingGroupCallActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingGroupCallActionProcessor.java @@ -119,7 +119,7 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro currentState = WebRtcVideoUtil.initializeVideo(context, webRtcInteractor.getCameraEventListener(), currentState, RemotePeer.GROUP_CALL_ID.longValue()); - webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_RINGING, remotePeerGroup); + webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_RINGING, remotePeerGroup, true); webRtcInteractor.updatePhoneState(LockManager.PhoneState.INTERACTIVE); webRtcInteractor.initializeAudioForCall(); @@ -207,7 +207,7 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro .enableVideoOnCreate(answerWithVideo) .build(); - webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_CONNECTING, currentState.getCallInfoState().getCallRecipient()); + webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_CONNECTING, currentState.getCallInfoState().getCallRecipient(), true); webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context)); webRtcInteractor.initializeAudioForCall(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java index bdb8b606b5..3df6477f52 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java @@ -70,7 +70,7 @@ public class OutgoingCallActionProcessor extends DeviceAwareActionProcessor { boolean isVideoCall = offerType == OfferMessage.Type.VIDEO_CALL; - webRtcInteractor.setCallInProgressNotification(TYPE_OUTGOING_RINGING, remotePeer); + webRtcInteractor.setCallInProgressNotification(TYPE_OUTGOING_RINGING, remotePeer, isVideoCall); webRtcInteractor.setDefaultAudioDevice(remotePeer.getId(), isVideoCall ? SignalAudioManager.AudioDevice.SPEAKER_PHONE : SignalAudioManager.AudioDevice.EARPIECE, false); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcCallService.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcCallService.java index 166c5b2818..5daf92e454 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcCallService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcCallService.java @@ -57,6 +57,7 @@ public final class WebRtcCallService extends Service implements SignalAudioManag private static final String EXTRA_RECIPIENT_ID = "RECIPIENT_ID"; private static final String EXTRA_ENABLED = "ENABLED"; private static final String EXTRA_AUDIO_COMMAND = "AUDIO_COMMAND"; + private static final String EXTRA_IS_VIDEO_CALL = "IS_VIDEO_CALL"; private static final int INVALID_NOTIFICATION_ID = -1; private static final long REQUEST_WEBSOCKET_STAY_OPEN_DELAY = TimeUnit.MINUTES.toMillis(1); @@ -76,11 +77,12 @@ public final class WebRtcCallService extends Service implements SignalAudioManag private boolean isGroup = true; private Disposable notificationDisposable = Disposable.empty(); - public static void update(@NonNull Context context, int type, @NonNull RecipientId recipientId) { + public static void update(@NonNull Context context, int type, @NonNull RecipientId recipientId, boolean isVideoCall) { Intent intent = new Intent(context, WebRtcCallService.class); intent.setAction(ACTION_UPDATE) .putExtra(EXTRA_UPDATE_TYPE, type) - .putExtra(EXTRA_RECIPIENT_ID, recipientId); + .putExtra(EXTRA_RECIPIENT_ID, recipientId) + .putExtra(EXTRA_IS_VIDEO_CALL, isVideoCall); ForegroundServiceUtil.startWhenCapableOrThrow(context, intent, FOREGROUND_SERVICE_TIMEOUT); } @@ -184,7 +186,8 @@ public final class WebRtcCallService extends Service implements SignalAudioManag RecipientId recipientId = Objects.requireNonNull(intent.getParcelableExtra(EXTRA_RECIPIENT_ID)); isGroup = Recipient.resolved(recipientId).isGroup(); setCallInProgressNotification(intent.getIntExtra(EXTRA_UPDATE_TYPE, 0), - Objects.requireNonNull(intent.getParcelableExtra(EXTRA_RECIPIENT_ID))); + Objects.requireNonNull(intent.getParcelableExtra(EXTRA_RECIPIENT_ID)), + intent.getBooleanExtra(EXTRA_IS_VIDEO_CALL, false)); return START_STICKY; case ACTION_SEND_AUDIO_COMMAND: setCallNotification(); @@ -230,7 +233,7 @@ public final class WebRtcCallService extends Service implements SignalAudioManag } } - public void setCallInProgressNotification(int type, @NonNull RecipientId id) { + public void setCallInProgressNotification(int type, @NonNull RecipientId id, boolean isVideoCall) { if (lastNotificationId == INVALID_NOTIFICATION_ID) { lastNotificationId = CallNotificationBuilder.getStartingStoppingNotificationId(); lastNotification = CallNotificationBuilder.getStartingNotification(this); @@ -238,7 +241,7 @@ public final class WebRtcCallService extends Service implements SignalAudioManag } notificationDisposable.dispose(); - notificationDisposable = CallNotificationBuilder.getCallInProgressNotification(this, type, Recipient.resolved(id)) + notificationDisposable = CallNotificationBuilder.getCallInProgressNotification(this, type, Recipient.resolved(id), isVideoCall) .subscribe(notification -> { lastNotificationId = CallNotificationBuilder.getNotificationId(type); lastNotification = notification; diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcInteractor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcInteractor.java index b91c573365..ffee8f9265 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcInteractor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcInteractor.java @@ -93,12 +93,12 @@ public class WebRtcInteractor { signalCallManager.updateGroupCallUpdateMessage(groupId, groupCallEraId, joinedMembers, isCallFull); } - void setCallInProgressNotification(int type, @NonNull RemotePeer remotePeer) { - WebRtcCallService.update(context, type, remotePeer.getRecipient().getId()); + void setCallInProgressNotification(int type, @NonNull RemotePeer remotePeer, boolean isVideoCall) { + WebRtcCallService.update(context, type, remotePeer.getRecipient().getId(), isVideoCall); } - void setCallInProgressNotification(int type, @NonNull Recipient recipient) { - WebRtcCallService.update(context, type, recipient.getId()); + void setCallInProgressNotification(int type, @NonNull Recipient recipient, boolean isVideoCall) { + WebRtcCallService.update(context, type, recipient.getId(), isVideoCall); } void retrieveTurnServers(@NonNull RemotePeer remotePeer) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallNotificationBuilder.java b/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallNotificationBuilder.java index 5ffebaa42e..f8e78e28db 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallNotificationBuilder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallNotificationBuilder.java @@ -10,6 +10,7 @@ import androidx.annotation.NonNull; import androidx.core.app.NotificationCompat; import org.signal.core.util.PendingIntentFlags; +import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.MainActivity; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.WebRtcCallActivity; @@ -17,7 +18,6 @@ import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.service.webrtc.WebRtcCallService; import org.thoughtcrime.securesms.util.ConversationUtil; -import org.thoughtcrime.securesms.util.ServiceUtil; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.core.Single; @@ -50,10 +50,11 @@ public class CallNotificationBuilder { */ public static final int API_LEVEL_CALL_STYLE = 29; - public static Single getCallInProgressNotification(Context context, int type, Recipient recipient) { + public static Single getCallInProgressNotification(Context context, int type, Recipient recipient, boolean isVideoCall) { Intent contentIntent = new Intent(context, WebRtcCallActivity.class); contentIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); contentIntent.putExtra(WebRtcCallActivity.EXTRA_STARTED_FROM_FULLSCREEN, true); + contentIntent.putExtra(WebRtcCallActivity.EXTRA_ENABLE_VIDEO_IF_AVAILABLE, isVideoCall); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, contentIntent, PendingIntentFlags.mutable()); @@ -83,8 +84,8 @@ public class CallNotificationBuilder { builder.setStyle(NotificationCompat.CallStyle.forIncomingCall( person, getServicePendingIntent(context, WebRtcCallService.denyCallIntent(context)), - getActivityPendingIntent(context, WebRtcCallActivity.ANSWER_ACTION) - )); + getActivityPendingIntent(context, isVideoCall ? WebRtcCallActivity.ANSWER_VIDEO_ACTION : WebRtcCallActivity.ANSWER_ACTION) + ).setIsVideo(isVideoCall)); return builder.build(); }); } else { @@ -97,19 +98,23 @@ public class CallNotificationBuilder { } else { builder.setContentText(context.getString(R.string.NotificationBarManager_signal_call_in_progress)); builder.setOnlyAlertOnce(true); - builder.setPriority(NotificationCompat.PRIORITY_HIGH); + builder.setPriority(NotificationCompat.PRIORITY_DEFAULT); builder.setCategory(NotificationCompat.CATEGORY_CALL); - return Single.fromCallable(() -> ConversationUtil.buildPerson(context, recipient)) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .map(person -> { - builder.setStyle(NotificationCompat.CallStyle.forOngoingCall( - person, - getServicePendingIntent(context, WebRtcCallService.hangupIntent(context)) - )); - return builder.build(); - }); + if (deviceVersionSupportsIncomingCallStyle()) { + return Single.fromCallable(() -> ConversationUtil.buildPerson(context, recipient)) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .map(person -> { + builder.setStyle(NotificationCompat.CallStyle.forOngoingCall( + person, + getServicePendingIntent(context, WebRtcCallService.hangupIntent(context)) + ).setIsVideo(isVideoCall)); + return builder.build(); + }); + } else { + return Single.just(builder.build()); + } } }