Improve Call Notification UX when things don't go as planned.

This commit is contained in:
Cody Henthorne
2021-03-31 13:45:28 -04:00
committed by Alex Hart
parent b053fbc4a7
commit d8dead82b6
15 changed files with 442 additions and 27 deletions

View File

@@ -31,10 +31,8 @@ import org.signal.ringrtc.HttpHeader;
import org.signal.ringrtc.Remote;
import org.signal.storageservice.protos.groups.GroupExternalCredential;
import org.signal.zkgroup.VerificationFailedException;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.WebRtcCallActivity;
import org.thoughtcrime.securesms.components.sensors.DeviceOrientationMonitor;
import org.thoughtcrime.securesms.crypto.IdentityKeyParcelable;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.database.DatabaseFactory;
@@ -57,6 +55,7 @@ import org.thoughtcrime.securesms.service.webrtc.IdleActionProcessor;
import org.thoughtcrime.securesms.service.webrtc.WebRtcInteractor;
import org.thoughtcrime.securesms.service.webrtc.WebRtcUtil;
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
import org.thoughtcrime.securesms.util.AppForegroundObserver;
import org.thoughtcrime.securesms.util.BubbleUtil;
import org.thoughtcrime.securesms.util.FutureTaskListener;
import org.thoughtcrime.securesms.util.ListenableFutureTask;
@@ -90,10 +89,14 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import static org.thoughtcrime.securesms.events.WebRtcViewModel.GroupCallState.IDLE;
import static org.thoughtcrime.securesms.events.WebRtcViewModel.State.CALL_INCOMING;
public class WebRtcCallService extends Service implements CallManager.Observer,
BluetoothStateManager.BluetoothStateListener,
CameraEventListener,
GroupCall.Observer
BluetoothStateManager.BluetoothStateListener,
CameraEventListener,
GroupCall.Observer,
AppForegroundObserver.Listener
{
private static final String TAG = Log.tag(WebRtcCallService.class);
@@ -276,6 +279,7 @@ public class WebRtcCallService extends Service implements CallManager.Observer,
new SignalAudioManager(this),
bluetoothStateManager,
this,
this,
this);
return true;
}
@@ -479,15 +483,16 @@ public class WebRtcCallService extends Service implements CallManager.Observer,
return listenableFutureTask;
}
public void startCallCardActivityIfPossible() {
public boolean startCallCardActivityIfPossible() {
if (Build.VERSION.SDK_INT >= 29 && !ApplicationDependencies.getAppForegroundObserver().isForegrounded()) {
return;
return false;
}
Intent activityIntent = new Intent();
activityIntent.setClass(this, WebRtcCallActivity.class);
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(activityIntent);
return true;
}
private static @NonNull OfferMessage.Type getOfferTypeFromCallMediaType(@NonNull CallManager.CallMediaType mediaType) {
@@ -516,6 +521,18 @@ public class WebRtcCallService extends Service implements CallManager.Observer,
return null;
}
@Override
public void onForeground() {
WebRtcViewModel.State callState = serviceState.getCallInfoState().getCallState();
if (callState == CALL_INCOMING && serviceState.getCallInfoState().getGroupCallState() == IDLE) {
startCallCardActivityIfPossible();
}
ApplicationDependencies.getAppForegroundObserver().removeListener(this);
}
@Override
public void onBackground() { }
private static class WiredHeadsetStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(@NonNull Context context, @NonNull Intent intent) {

View File

@@ -5,6 +5,7 @@ import androidx.annotation.NonNull;
import org.signal.core.util.logging.Log;
import org.signal.ringrtc.CallException;
import org.signal.ringrtc.CallManager;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.events.WebRtcViewModel;
import org.thoughtcrime.securesms.ringrtc.CallState;
import org.thoughtcrime.securesms.ringrtc.Camera;
@@ -37,6 +38,7 @@ public class CallSetupActionProcessorDelegate extends WebRtcActionProcessor {
RemotePeer activePeer = currentState.getCallInfoState().requireActivePeer();
ApplicationDependencies.getAppForegroundObserver().removeListener(webRtcInteractor.getForegroundListener());
webRtcInteractor.startAudioCommunication(activePeer.getState() == CallState.REMOTE_RINGING);
webRtcInteractor.setWantsBluetoothConnection(true);

View File

@@ -12,6 +12,7 @@ import org.signal.ringrtc.CallId;
import org.thoughtcrime.securesms.components.webrtc.OrientationAwareVideoSink;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.events.CallParticipant;
import org.thoughtcrime.securesms.events.WebRtcViewModel;
import org.thoughtcrime.securesms.notifications.DoNotDisturbUtil;
@@ -157,7 +158,11 @@ public class IncomingCallActionProcessor extends DeviceAwareActionProcessor {
boolean shouldDisturbUserWithCall = DoNotDisturbUtil.shouldDisturbUserWithCall(context.getApplicationContext(), recipient);
if (shouldDisturbUserWithCall) {
webRtcInteractor.startWebRtcCallActivityIfPossible();
boolean started = webRtcInteractor.startWebRtcCallActivityIfPossible();
if (!started) {
Log.i(TAG, "Unable to start call activity due to OS version or not being in the foreground");
ApplicationDependencies.getAppForegroundObserver().addListener(webRtcInteractor.getForegroundListener());
}
}
webRtcInteractor.initializeAudioForCall();

View File

@@ -13,6 +13,7 @@ import org.signal.ringrtc.CallId;
import org.signal.ringrtc.GroupCall;
import org.thoughtcrime.securesms.components.sensors.Orientation;
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.events.CallParticipant;
import org.thoughtcrime.securesms.events.WebRtcViewModel;
import org.thoughtcrime.securesms.recipients.RecipientId;
@@ -723,6 +724,8 @@ public abstract class WebRtcActionProcessor {
return currentState;
}
ApplicationDependencies.getAppForegroundObserver().removeListener(webRtcInteractor.getForegroundListener());
webRtcInteractor.updatePhoneState(LockManager.PhoneState.PROCESSING);
webRtcInteractor.stopForegroundService();
boolean playDisconnectSound = (activePeer.getState() == CallState.DIALING) ||

View File

@@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.ringrtc.CameraEventListener;
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
import org.thoughtcrime.securesms.service.WebRtcCallService;
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
import org.thoughtcrime.securesms.util.AppForegroundObserver;
import org.thoughtcrime.securesms.webrtc.audio.BluetoothStateManager;
import org.thoughtcrime.securesms.webrtc.audio.OutgoingRinger;
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager;
@@ -29,13 +30,14 @@ import java.util.UUID;
*/
public class WebRtcInteractor {
@NonNull private final WebRtcCallService webRtcCallService;
@NonNull private final CallManager callManager;
@NonNull private final LockManager lockManager;
@NonNull private final SignalAudioManager audioManager;
@NonNull private final BluetoothStateManager bluetoothStateManager;
@NonNull private final CameraEventListener cameraEventListener;
@NonNull private final GroupCall.Observer groupCallObserver;
@NonNull private final WebRtcCallService webRtcCallService;
@NonNull private final CallManager callManager;
@NonNull private final LockManager lockManager;
@NonNull private final SignalAudioManager audioManager;
@NonNull private final BluetoothStateManager bluetoothStateManager;
@NonNull private final CameraEventListener cameraEventListener;
@NonNull private final GroupCall.Observer groupCallObserver;
@NonNull private final AppForegroundObserver.Listener foregroundListener;
public WebRtcInteractor(@NonNull WebRtcCallService webRtcCallService,
@NonNull CallManager callManager,
@@ -43,7 +45,8 @@ public class WebRtcInteractor {
@NonNull SignalAudioManager audioManager,
@NonNull BluetoothStateManager bluetoothStateManager,
@NonNull CameraEventListener cameraEventListener,
@NonNull GroupCall.Observer groupCallObserver)
@NonNull GroupCall.Observer groupCallObserver,
@NonNull AppForegroundObserver.Listener foregroundListener)
{
this.webRtcCallService = webRtcCallService;
this.callManager = callManager;
@@ -52,6 +55,7 @@ public class WebRtcInteractor {
this.bluetoothStateManager = bluetoothStateManager;
this.cameraEventListener = cameraEventListener;
this.groupCallObserver = groupCallObserver;
this.foregroundListener = foregroundListener;
}
@NonNull CameraEventListener getCameraEventListener() {
@@ -70,6 +74,10 @@ public class WebRtcInteractor {
return groupCallObserver;
}
@NonNull AppForegroundObserver.Listener getForegroundListener() {
return foregroundListener;
}
void setWantsBluetoothConnection(boolean enabled) {
bluetoothStateManager.setWantsConnection(enabled);
}
@@ -118,8 +126,8 @@ public class WebRtcInteractor {
webRtcCallService.insertMissedCall(remotePeer, signal, timestamp, isVideoOffer);
}
void startWebRtcCallActivityIfPossible() {
webRtcCallService.startCallCardActivityIfPossible();
boolean startWebRtcCallActivityIfPossible() {
return webRtcCallService.startCallCardActivityIfPossible();
}
void registerPowerButtonReceiver() {