Fix state exception by always starting call service in foreground.

fork-5.53.8
Cody Henthorne 2021-04-02 14:59:15 -04:00
rodzic c4d317b33e
commit f332cbf1bc
11 zmienionych plików z 70 dodań i 18 usunięć

Wyświetl plik

@ -97,7 +97,12 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
@Override
protected @NonNull WebRtcServiceState handleLocalHangup(@NonNull WebRtcServiceState currentState) {
Log.i(tag, "handleLocalHangup(): call_id: " + currentState.getCallInfoState().requireActivePeer().getCallId());
RemotePeer remotePeer = currentState.getCallInfoState().getActivePeer();
if (remotePeer == null) {
Log.i(tag, "handleLocalHangup(): no active peer");
} else {
Log.i(tag, "handleLocalHangup(): call_id: " + remotePeer.getCallId());
}
ApplicationDependencies.getSignalServiceAccountManager().cancelInFlightRequests();
ApplicationDependencies.getSignalServiceMessageSender().cancelInFlightRequests();
@ -112,7 +117,7 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
webRtcInteractor.postStateUpdate(currentState);
return terminate(currentState, currentState.getCallInfoState().getActivePeer());
return terminate(currentState, remotePeer);
} catch (CallException e) {
return callFailure(currentState, "hangup() failed: ", e);
}

Wyświetl plik

@ -40,7 +40,6 @@ public class CallSetupActionProcessorDelegate extends WebRtcActionProcessor {
ApplicationDependencies.getAppForegroundObserver().removeListener(webRtcInteractor.getForegroundListener());
webRtcInteractor.startAudioCommunication(activePeer.getState() == CallState.REMOTE_RINGING);
webRtcInteractor.setWantsBluetoothConnection(true);
activePeer.connected();
@ -57,8 +56,9 @@ public class CallSetupActionProcessorDelegate extends WebRtcActionProcessor {
.callConnectedTime(System.currentTimeMillis())
.build();
webRtcInteractor.unregisterPowerButtonReceiver();
webRtcInteractor.setCallInProgressNotification(TYPE_ESTABLISHED, activePeer);
webRtcInteractor.unregisterPowerButtonReceiver();
webRtcInteractor.setWantsBluetoothConnection(true);
try {
CallManager callManager = webRtcInteractor.getCallManager();

Wyświetl plik

@ -329,10 +329,10 @@ public class GroupActionProcessor extends DeviceAwareActionProcessor {
public synchronized @NonNull WebRtcServiceState terminateGroupCall(@NonNull WebRtcServiceState currentState, boolean terminateVideo) {
webRtcInteractor.updatePhoneState(LockManager.PhoneState.PROCESSING);
webRtcInteractor.stopForegroundService();
boolean playDisconnectSound = currentState.getCallInfoState().getCallState() == WebRtcViewModel.State.CALL_DISCONNECTED;
webRtcInteractor.stopAudio(playDisconnectSound);
webRtcInteractor.setWantsBluetoothConnection(false);
webRtcInteractor.stopForegroundService();
webRtcInteractor.updatePhoneState(LockManager.PhoneState.IDLE);

Wyświetl plik

@ -62,7 +62,6 @@ public class GroupJoiningActionProcessor extends GroupActionProcessor {
if (device.getJoinState() == GroupCall.JoinState.JOINED) {
webRtcInteractor.startAudioCommunication(true);
webRtcInteractor.setWantsBluetoothConnection(true);
if (currentState.getLocalDeviceState().getCameraState().isEnabled()) {
webRtcInteractor.updatePhoneState(LockManager.PhoneState.IN_VIDEO);
@ -71,6 +70,7 @@ public class GroupJoiningActionProcessor extends GroupActionProcessor {
}
webRtcInteractor.setCallInProgressNotification(TYPE_ESTABLISHED, currentState.getCallInfoState().getCallRecipient());
webRtcInteractor.setWantsBluetoothConnection(true);
try {
groupCall.setOutgoingVideoMuted(!currentState.getLocalDeviceState().getCameraState().isEnabled());

Wyświetl plik

@ -145,8 +145,8 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor {
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context));
webRtcInteractor.initializeAudioForCall();
webRtcInteractor.setWantsBluetoothConnection(true);
webRtcInteractor.setCallInProgressNotification(TYPE_OUTGOING_RINGING, currentState.getCallInfoState().getCallRecipient());
webRtcInteractor.setWantsBluetoothConnection(true);
try {
groupCall.setOutgoingVideoSource(currentState.getVideoState().requireLocalSink(), currentState.getVideoState().requireCamera());

Wyświetl plik

@ -176,8 +176,8 @@ public class IncomingCallActionProcessor extends DeviceAwareActionProcessor {
webRtcInteractor.startIncomingRinger(ringtone, vibrateState == RecipientDatabase.VibrateState.ENABLED || (vibrateState == RecipientDatabase.VibrateState.DEFAULT && TextSecurePreferences.isCallNotificationVibrateEnabled(context)));
}
webRtcInteractor.registerPowerButtonReceiver();
webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_RINGING, activePeer);
webRtcInteractor.registerPowerButtonReceiver();
return currentState.builder()
.changeCallInfoState()

Wyświetl plik

@ -72,9 +72,9 @@ public class OutgoingCallActionProcessor extends DeviceAwareActionProcessor {
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context));
webRtcInteractor.initializeAudioForCall();
webRtcInteractor.startOutgoingRinger();
webRtcInteractor.setWantsBluetoothConnection(true);
webRtcInteractor.setCallInProgressNotification(TYPE_OUTGOING_RINGING, remotePeer);
webRtcInteractor.setWantsBluetoothConnection(true);
DatabaseFactory.getSmsDatabase(context).insertOutgoingCall(remotePeer.getId(), currentState.getCallSetupState().isEnableVideoOnCreate());

Wyświetl plik

@ -532,15 +532,15 @@ public abstract class WebRtcActionProcessor {
ApplicationDependencies.getAppForegroundObserver().removeListener(webRtcInteractor.getForegroundListener());
webRtcInteractor.updatePhoneState(LockManager.PhoneState.PROCESSING);
webRtcInteractor.stopForegroundService();
boolean playDisconnectSound = (activePeer.getState() == CallState.DIALING) ||
(activePeer.getState() == CallState.REMOTE_RINGING) ||
(activePeer.getState() == CallState.RECEIVED_BUSY) ||
(activePeer.getState() == CallState.CONNECTED);
webRtcInteractor.stopAudio(playDisconnectSound);
webRtcInteractor.setWantsBluetoothConnection(false);
webRtcInteractor.setWantsBluetoothConnection(false);
webRtcInteractor.updatePhoneState(LockManager.PhoneState.IDLE);
webRtcInteractor.stopForegroundService();
return WebRtcVideoUtil.deinitializeVideo(currentState)
.builder()

Wyświetl plik

@ -1,5 +1,6 @@
package org.thoughtcrime.securesms.service.webrtc;
import android.app.Notification;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -48,6 +49,8 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
private static final String EXTRA_RECIPIENT_ID = "RECIPIENT_ID";
private static final String EXTRA_ENABLED = "ENABLED";
private static final int INVALID_NOTIFICATION_ID = -1;
private SignalCallManager callManager;
private WiredHeadsetStateReceiver wiredHeadsetStateReceiver;
@ -56,6 +59,8 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
private UncaughtExceptionHandlerManager uncaughtExceptionHandlerManager;
private PhoneStateListener hangUpRtcOnDeviceCallAnswered;
private BluetoothStateManager bluetoothStateManager;
private int lastNotificationId;
private Notification lastNotification;
public static void update(@NonNull Context context, int type, @NonNull RecipientId recipientId) {
Intent intent = new Intent(context, WebRtcCallService.class);
@ -70,7 +75,7 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
Intent intent = new Intent(context, WebRtcCallService.class);
intent.setAction(ACTION_STOP);
context.startService(intent);
ContextCompat.startForegroundService(context, intent);
}
public static @NonNull Intent denyCallIntent(@NonNull Context context) {
@ -86,7 +91,7 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
intent.setAction(ACTION_WANTS_BLUETOOTH)
.putExtra(EXTRA_ENABLED, enabled);
context.startService(intent);
ContextCompat.startForegroundService(context, intent);
}
public static void changePowerButtonReceiver(@NonNull Context context, boolean register) {
@ -94,7 +99,7 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
intent.setAction(ACTION_CHANGE_POWER_BUTTON)
.putExtra(EXTRA_ENABLED, register);
context.startService(intent);
ContextCompat.startForegroundService(context, intent);
}
@Override
@ -104,6 +109,7 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
this.callManager = ApplicationDependencies.getSignalCallManager();
this.bluetoothStateManager = new BluetoothStateManager(this, this);
this.hangUpRtcOnDeviceCallAnswered = new HangUpRtcOnPstnCallAnsweredListener();
this.lastNotificationId = INVALID_NOTIFICATION_ID;
registerUncaughtExceptionHandler();
registerWiredHeadsetStateReceiver();
@ -151,11 +157,13 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
Objects.requireNonNull(intent.getParcelableExtra(EXTRA_RECIPIENT_ID)));
return START_STICKY;
case ACTION_WANTS_BLUETOOTH:
setCallNotification();
if (bluetoothStateManager != null) {
bluetoothStateManager.setWantsConnection(intent.getBooleanExtra(EXTRA_ENABLED, false));
}
return START_STICKY;
case ACTION_CHANGE_POWER_BUTTON:
setCallNotification();
if (intent.getBooleanExtra(EXTRA_ENABLED, false)) {
registerPowerButtonReceiver();
} else {
@ -163,13 +171,15 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
}
return START_STICKY;
case ACTION_STOP:
stopSelf();
stopForeground(true);
setCallNotification();
stop();
return START_NOT_STICKY;
case ACTION_DENY_CALL:
setCallNotification();
callManager.denyCall();
return START_NOT_STICKY;
case ACTION_LOCAL_HANGUP:
setCallNotification();
callManager.localHangup();
return START_NOT_STICKY;
default:
@ -177,9 +187,26 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
}
}
private void setCallNotification() {
if (lastNotificationId != INVALID_NOTIFICATION_ID) {
startForeground(lastNotificationId, lastNotification);
} else {
Log.w(TAG, "Service running without having called start first, show temp notification and terminate service.");
startForeground(CallNotificationBuilder.getStoppingNotificationId(), CallNotificationBuilder.getStoppingNotification(this));
stop();
}
}
public void setCallInProgressNotification(int type, @NonNull RecipientId id) {
startForeground(CallNotificationBuilder.getNotificationId(type),
CallNotificationBuilder.getCallInProgressNotification(this, type, Recipient.resolved(id)));
lastNotificationId = CallNotificationBuilder.getNotificationId(type);
lastNotification = CallNotificationBuilder.getCallInProgressNotification(this, type, Recipient.resolved(id));
startForeground(lastNotificationId, lastNotification);
}
private void stop() {
stopForeground(true);
stopSelf();
}
private void registerUncaughtExceptionHandler() {

Wyświetl plik

@ -11,6 +11,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.core.app.NotificationCompat;
import org.thoughtcrime.securesms.MainActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.WebRtcCallActivity;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
@ -79,6 +80,24 @@ public class CallNotificationBuilder {
}
}
public static @NonNull Notification getStoppingNotification(@NonNull Context context) {
Intent contentIntent = new Intent(context, MainActivity.class);
contentIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, contentIntent, 0);
return new NotificationCompat.Builder(context, NotificationChannels.OTHER).setSmallIcon(R.drawable.ic_call_secure_white_24dp)
.setContentIntent(pendingIntent)
.setOngoing(true)
.setContentTitle(context.getString(R.string.NotificationBarManager__stopping_signal_call_service))
.setPriority(NotificationCompat.PRIORITY_MIN)
.build();
}
public static int getStoppingNotificationId() {
return WEBRTC_NOTIFICATION;
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public static boolean isWebRtcNotification(int notificationId) {
return notificationId == WEBRTC_NOTIFICATION || notificationId == WEBRTC_NOTIFICATION_RINGING;

Wyświetl plik

@ -971,6 +971,7 @@
<string name="NotificationBarManager_signal_call_in_progress">Signal call in progress</string>
<string name="NotificationBarManager__establishing_signal_call">Establishing Signal call</string>
<string name="NotificationBarManager__incoming_signal_call">Incoming Signal call</string>
<string name="NotificationBarManager__stopping_signal_call_service">Stopping Signal call service</string>
<string name="NotificationBarManager__deny_call">Deny call</string>
<string name="NotificationBarManager__answer_call">Answer call</string>
<string name="NotificationBarManager__end_call">End call</string>