Fix several issues with call notifications.

This commit is contained in:
Alex Hart
2023-06-14 15:30:29 -03:00
committed by Cody Henthorne
parent 38f2b39ac4
commit 6cd59daf0a
13 changed files with 62 additions and 43 deletions

View File

@@ -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())) {

View File

@@ -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();

View File

@@ -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)
}

View File

@@ -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();

View File

@@ -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 {

View File

@@ -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()) {

View File

@@ -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();

View File

@@ -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()

View File

@@ -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();

View File

@@ -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);

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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<Notification> getCallInProgressNotification(Context context, int type, Recipient recipient) {
public static Single<Notification> 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());
}
}
}