mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-20 00:29:11 +01:00
Refactor call audio routing and bluetooth management.
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
package org.thoughtcrime.securesms.service.webrtc;
|
||||
|
||||
import android.media.AudioManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
@@ -13,7 +11,6 @@ import org.thoughtcrime.securesms.events.CallParticipantId;
|
||||
import org.thoughtcrime.securesms.events.WebRtcViewModel;
|
||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
|
||||
|
||||
import static org.thoughtcrime.securesms.webrtc.CallNotificationBuilder.TYPE_INCOMING_CONNECTING;
|
||||
@@ -76,9 +73,6 @@ public class BeginCallActionProcessorDelegate extends WebRtcActionProcessor {
|
||||
|
||||
Log.i(tag, "assign activePeer callId: " + remotePeer.getCallId() + " key: " + remotePeer.hashCode());
|
||||
|
||||
AudioManager androidAudioManager = ServiceUtil.getAudioManager(context);
|
||||
androidAudioManager.setSpeakerphoneOn(false);
|
||||
|
||||
webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_CONNECTING, remotePeer);
|
||||
webRtcInteractor.retrieveTurnServers(remotePeer);
|
||||
|
||||
|
||||
@@ -7,11 +7,11 @@ 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;
|
||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
import org.thoughtcrime.securesms.util.NetworkUtil;
|
||||
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager;
|
||||
import org.thoughtcrime.securesms.webrtc.locks.LockManager;
|
||||
|
||||
import static org.thoughtcrime.securesms.webrtc.CallNotificationBuilder.TYPE_ESTABLISHED;
|
||||
@@ -39,7 +39,7 @@ public class CallSetupActionProcessorDelegate extends WebRtcActionProcessor {
|
||||
RemotePeer activePeer = currentState.getCallInfoState().requireActivePeer();
|
||||
|
||||
ApplicationDependencies.getAppForegroundObserver().removeListener(webRtcInteractor.getForegroundListener());
|
||||
webRtcInteractor.startAudioCommunication(activePeer.getState() == CallState.REMOTE_RINGING);
|
||||
webRtcInteractor.startAudioCommunication();
|
||||
|
||||
activePeer.connected();
|
||||
|
||||
@@ -56,12 +56,10 @@ public class CallSetupActionProcessorDelegate extends WebRtcActionProcessor {
|
||||
.callConnectedTime(System.currentTimeMillis())
|
||||
.commit()
|
||||
.changeLocalDeviceState()
|
||||
.wantsBluetooth(true)
|
||||
.build();
|
||||
|
||||
webRtcInteractor.setCallInProgressNotification(TYPE_ESTABLISHED, activePeer);
|
||||
webRtcInteractor.unregisterPowerButtonReceiver();
|
||||
webRtcInteractor.setWantsBluetoothConnection(true);
|
||||
|
||||
try {
|
||||
CallManager callManager = webRtcInteractor.getCallManager();
|
||||
@@ -77,6 +75,12 @@ public class CallSetupActionProcessorDelegate extends WebRtcActionProcessor {
|
||||
currentState = currentState.getActionProcessor().handleSetEnableVideo(currentState, true);
|
||||
}
|
||||
|
||||
if (currentState.getCallSetupState().isAcceptWithVideo() || currentState.getLocalDeviceState().getCameraState().isEnabled()) {
|
||||
webRtcInteractor.setDefaultAudioDevice(SignalAudioManager.AudioDevice.SPEAKER_PHONE, false);
|
||||
} else {
|
||||
webRtcInteractor.setDefaultAudioDevice(SignalAudioManager.AudioDevice.EARPIECE, false);
|
||||
}
|
||||
|
||||
return currentState;
|
||||
}
|
||||
|
||||
@@ -98,7 +102,7 @@ public class CallSetupActionProcessorDelegate extends WebRtcActionProcessor {
|
||||
.cameraState(camera.getCameraState())
|
||||
.build();
|
||||
|
||||
WebRtcUtil.enableSpeakerPhoneIfNeeded(context, currentState.getCallSetupState().isEnableVideoOnCreate());
|
||||
WebRtcUtil.enableSpeakerPhoneIfNeeded(webRtcInteractor, currentState);
|
||||
|
||||
return currentState;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class ConnectedCallActionProcessor extends DeviceAwareActionProcessor {
|
||||
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context));
|
||||
}
|
||||
|
||||
WebRtcUtil.enableSpeakerPhoneIfNeeded(context, currentState.getLocalDeviceState().getCameraState().isEnabled());
|
||||
WebRtcUtil.enableSpeakerPhoneIfNeeded(webRtcInteractor, currentState);
|
||||
|
||||
return currentState;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package org.thoughtcrime.securesms.service.webrtc;
|
||||
|
||||
import android.media.AudioManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink;
|
||||
import org.thoughtcrime.securesms.ringrtc.Camera;
|
||||
import org.thoughtcrime.securesms.ringrtc.CameraState;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Encapsulates the shared logic to deal with local device actions. Other action processors inherit
|
||||
@@ -23,76 +22,29 @@ public abstract class DeviceAwareActionProcessor extends WebRtcActionProcessor {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull WebRtcServiceState handleWiredHeadsetChange(@NonNull WebRtcServiceState currentState, boolean present) {
|
||||
Log.i(tag, "handleWiredHeadsetChange():");
|
||||
protected @NonNull WebRtcServiceState handleAudioDeviceChanged(@NonNull WebRtcServiceState currentState, @NonNull SignalAudioManager.AudioDevice activeDevice, @NonNull Set<SignalAudioManager.AudioDevice> availableDevices) {
|
||||
Log.i(tag, "handleAudioDeviceChanged(): active: " + activeDevice + " available: " + availableDevices);
|
||||
|
||||
AudioManager androidAudioManager = ServiceUtil.getAudioManager(context);
|
||||
|
||||
if (present && androidAudioManager.isSpeakerphoneOn()) {
|
||||
androidAudioManager.setSpeakerphoneOn(false);
|
||||
androidAudioManager.setBluetoothScoOn(false);
|
||||
} else if (!present && !androidAudioManager.isSpeakerphoneOn() && !androidAudioManager.isBluetoothScoOn() && currentState.getLocalDeviceState().getCameraState().isEnabled()) {
|
||||
androidAudioManager.setSpeakerphoneOn(true);
|
||||
if (!currentState.getLocalDeviceState().getCameraState().isEnabled()) {
|
||||
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context));
|
||||
}
|
||||
|
||||
webRtcInteractor.postStateUpdate(currentState);
|
||||
return currentState.builder()
|
||||
.changeLocalDeviceState()
|
||||
.setActiveDevice(activeDevice)
|
||||
.setAvailableDevices(availableDevices)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull WebRtcServiceState handleSetUserAudioDevice(@NonNull WebRtcServiceState currentState, @NonNull SignalAudioManager.AudioDevice userDevice) {
|
||||
Log.i(tag, "handleSetUserAudioDevice(): userDevice: " + userDevice);
|
||||
|
||||
webRtcInteractor.setUserAudioDevice(userDevice);
|
||||
|
||||
return currentState;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull WebRtcServiceState handleBluetoothChange(@NonNull WebRtcServiceState currentState, boolean available) {
|
||||
Log.i(tag, "handleBluetoothChange(): " + available);
|
||||
|
||||
if (available && currentState.getLocalDeviceState().wantsBluetooth()) {
|
||||
webRtcInteractor.setWantsBluetoothConnection(true);
|
||||
}
|
||||
|
||||
return currentState.builder()
|
||||
.changeLocalDeviceState()
|
||||
.isBluetoothAvailable(available)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull WebRtcServiceState handleSetSpeakerAudio(@NonNull WebRtcServiceState currentState, boolean isSpeaker) {
|
||||
Log.i(tag, "handleSetSpeakerAudio(): " + isSpeaker);
|
||||
|
||||
AudioManager androidAudioManager = ServiceUtil.getAudioManager(context);
|
||||
|
||||
webRtcInteractor.setWantsBluetoothConnection(false);
|
||||
androidAudioManager.setSpeakerphoneOn(isSpeaker);
|
||||
|
||||
if (!currentState.getLocalDeviceState().getCameraState().isEnabled()) {
|
||||
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context));
|
||||
}
|
||||
|
||||
webRtcInteractor.postStateUpdate(currentState);
|
||||
|
||||
return currentState.builder()
|
||||
.changeLocalDeviceState()
|
||||
.wantsBluetooth(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull WebRtcServiceState handleSetBluetoothAudio(@NonNull WebRtcServiceState currentState, boolean isBluetooth) {
|
||||
Log.i(tag, "handleSetBluetoothAudio(): " + isBluetooth);
|
||||
|
||||
webRtcInteractor.setWantsBluetoothConnection(isBluetooth);
|
||||
|
||||
if (!currentState.getLocalDeviceState().getCameraState().isEnabled()) {
|
||||
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context));
|
||||
}
|
||||
|
||||
webRtcInteractor.postStateUpdate(currentState);
|
||||
|
||||
return currentState.builder()
|
||||
.changeLocalDeviceState()
|
||||
.wantsBluetooth(isBluetooth)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull WebRtcServiceState handleSetCameraFlip(@NonNull WebRtcServiceState currentState) {
|
||||
Log.i(tag, "handleSetCameraFlip():");
|
||||
|
||||
@@ -84,7 +84,7 @@ public class GroupConnectedActionProcessor extends GroupActionProcessor {
|
||||
.cameraState(camera.getCameraState())
|
||||
.build();
|
||||
|
||||
WebRtcUtil.enableSpeakerPhoneIfNeeded(context, currentState.getCallSetupState().isEnableVideoOnCreate());
|
||||
WebRtcUtil.enableSpeakerPhoneIfNeeded(webRtcInteractor, currentState);
|
||||
|
||||
return currentState;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.thoughtcrime.securesms.service.webrtc;
|
||||
|
||||
import static org.thoughtcrime.securesms.webrtc.CallNotificationBuilder.TYPE_ESTABLISHED;
|
||||
|
||||
import android.os.ResultReceiver;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -18,6 +16,8 @@ import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.NetworkUtil;
|
||||
import org.thoughtcrime.securesms.webrtc.locks.LockManager;
|
||||
|
||||
import static org.thoughtcrime.securesms.webrtc.CallNotificationBuilder.TYPE_ESTABLISHED;
|
||||
|
||||
/**
|
||||
* Process actions to go from lobby to a joined call.
|
||||
*/
|
||||
@@ -62,7 +62,8 @@ public class GroupJoiningActionProcessor extends GroupActionProcessor {
|
||||
case CONNECTED:
|
||||
if (device.getJoinState() == GroupCall.JoinState.JOINED) {
|
||||
|
||||
webRtcInteractor.startAudioCommunication(true);
|
||||
webRtcInteractor.setCallInProgressNotification(TYPE_ESTABLISHED, currentState.getCallInfoState().getCallRecipient());
|
||||
webRtcInteractor.startAudioCommunication();
|
||||
|
||||
if (currentState.getLocalDeviceState().getCameraState().isEnabled()) {
|
||||
webRtcInteractor.updatePhoneState(LockManager.PhoneState.IN_VIDEO);
|
||||
@@ -70,9 +71,6 @@ public class GroupJoiningActionProcessor extends GroupActionProcessor {
|
||||
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context));
|
||||
}
|
||||
|
||||
webRtcInteractor.setCallInProgressNotification(TYPE_ESTABLISHED, currentState.getCallInfoState().getCallRecipient());
|
||||
webRtcInteractor.setWantsBluetoothConnection(true);
|
||||
|
||||
try {
|
||||
groupCall.setOutgoingVideoMuted(!currentState.getLocalDeviceState().getCameraState().isEnabled());
|
||||
groupCall.setOutgoingAudioMuted(!currentState.getLocalDeviceState().isMicrophoneEnabled());
|
||||
@@ -96,7 +94,6 @@ public class GroupJoiningActionProcessor extends GroupActionProcessor {
|
||||
.callConnectedTime(System.currentTimeMillis())
|
||||
.commit()
|
||||
.changeLocalDeviceState()
|
||||
.wantsBluetooth(true)
|
||||
.commit()
|
||||
.actionProcessor(new GroupConnectedActionProcessor(webRtcInteractor));
|
||||
} else if (device.getJoinState() == GroupCall.JoinState.JOINING) {
|
||||
@@ -152,7 +149,7 @@ public class GroupJoiningActionProcessor extends GroupActionProcessor {
|
||||
.cameraState(camera.getCameraState())
|
||||
.build();
|
||||
|
||||
WebRtcUtil.enableSpeakerPhoneIfNeeded(context, currentState.getCallSetupState().isEnableVideoOnCreate());
|
||||
WebRtcUtil.enableSpeakerPhoneIfNeeded(webRtcInteractor, currentState);
|
||||
|
||||
return currentState;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.thoughtcrime.securesms.service.webrtc;
|
||||
|
||||
import android.media.AudioManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
@@ -20,7 +18,6 @@ import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder;
|
||||
import org.thoughtcrime.securesms.util.NetworkUtil;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
|
||||
|
||||
import java.util.List;
|
||||
@@ -148,13 +145,9 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor {
|
||||
|
||||
currentState = WebRtcVideoUtil.reinitializeCamera(context, webRtcInteractor.getCameraEventListener(), currentState);
|
||||
|
||||
AudioManager androidAudioManager = ServiceUtil.getAudioManager(context);
|
||||
androidAudioManager.setSpeakerphoneOn(false);
|
||||
|
||||
webRtcInteractor.setCallInProgressNotification(TYPE_OUTGOING_RINGING, currentState.getCallInfoState().getCallRecipient());
|
||||
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context));
|
||||
webRtcInteractor.initializeAudioForCall();
|
||||
webRtcInteractor.setCallInProgressNotification(TYPE_OUTGOING_RINGING, currentState.getCallInfoState().getCallRecipient());
|
||||
webRtcInteractor.setWantsBluetoothConnection(true);
|
||||
|
||||
try {
|
||||
groupCall.setOutgoingVideoSource(currentState.getVideoState().requireLocalSink(), currentState.getVideoState().requireCamera());
|
||||
@@ -174,7 +167,6 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor {
|
||||
.groupCallState(WebRtcViewModel.GroupCallState.CONNECTED_AND_JOINING)
|
||||
.commit()
|
||||
.changeLocalDeviceState()
|
||||
.wantsBluetooth(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.thoughtcrime.securesms.service.webrtc;
|
||||
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -23,7 +22,6 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
import org.thoughtcrime.securesms.util.NetworkUtil;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.webrtc.locks.LockManager;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
@@ -108,11 +106,9 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||
|
||||
currentState = WebRtcVideoUtil.initializeVideo(context, webRtcInteractor.getCameraEventListener(), currentState);
|
||||
|
||||
AudioManager androidAudioManager = ServiceUtil.getAudioManager(context);
|
||||
androidAudioManager.setSpeakerphoneOn(false);
|
||||
|
||||
webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_RINGING, remotePeerGroup);
|
||||
webRtcInteractor.updatePhoneState(LockManager.PhoneState.INTERACTIVE);
|
||||
webRtcInteractor.initializeAudioForCall();
|
||||
|
||||
boolean shouldDisturbUserWithCall = DoNotDisturbUtil.shouldDisturbUserWithCall(context.getApplicationContext());
|
||||
if (shouldDisturbUserWithCall) {
|
||||
@@ -123,7 +119,6 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||
}
|
||||
}
|
||||
|
||||
webRtcInteractor.initializeAudioForCall();
|
||||
if (shouldDisturbUserWithCall && SignalStore.settings().isCallNotificationsEnabled()) {
|
||||
Uri ringtone = recipient.resolve().getCallRingtone();
|
||||
RecipientDatabase.VibrateState vibrateState = recipient.resolve().getCallVibrate();
|
||||
@@ -135,7 +130,6 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||
webRtcInteractor.startIncomingRinger(ringtone, vibrateState == RecipientDatabase.VibrateState.ENABLED || (vibrateState == RecipientDatabase.VibrateState.DEFAULT && SignalStore.settings().isCallVibrateEnabled()));
|
||||
}
|
||||
|
||||
webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_RINGING, remotePeerGroup);
|
||||
webRtcInteractor.registerPowerButtonReceiver();
|
||||
|
||||
return currentState.builder()
|
||||
@@ -196,13 +190,9 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||
.enableVideoOnCreate(answerWithVideo)
|
||||
.build();
|
||||
|
||||
AudioManager androidAudioManager = ServiceUtil.getAudioManager(context);
|
||||
androidAudioManager.setSpeakerphoneOn(false);
|
||||
|
||||
webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_CONNECTING, currentState.getCallInfoState().getCallRecipient());
|
||||
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context));
|
||||
webRtcInteractor.initializeAudioForCall();
|
||||
webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_CONNECTING, currentState.getCallInfoState().getCallRecipient());
|
||||
webRtcInteractor.setWantsBluetoothConnection(true);
|
||||
|
||||
try {
|
||||
groupCall.setOutgoingVideoSource(currentState.getVideoState().requireLocalSink(), currentState.getVideoState().requireCamera());
|
||||
@@ -222,7 +212,6 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||
.groupCallState(WebRtcViewModel.GroupCallState.CONNECTED_AND_JOINING)
|
||||
.commit()
|
||||
.changeLocalDeviceState()
|
||||
.wantsBluetooth(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -246,7 +235,6 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||
|
||||
webRtcInteractor.updatePhoneState(LockManager.PhoneState.PROCESSING);
|
||||
webRtcInteractor.stopAudio(false);
|
||||
webRtcInteractor.setWantsBluetoothConnection(false);
|
||||
webRtcInteractor.updatePhoneState(LockManager.PhoneState.IDLE);
|
||||
webRtcInteractor.stopForegroundService();
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.thoughtcrime.securesms.service.webrtc;
|
||||
|
||||
import android.media.AudioManager;
|
||||
import android.os.ResultReceiver;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -23,7 +22,7 @@ import org.thoughtcrime.securesms.service.webrtc.state.VideoState;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder;
|
||||
import org.thoughtcrime.securesms.util.NetworkUtil;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager;
|
||||
import org.webrtc.PeerConnection;
|
||||
import org.whispersystems.libsignal.InvalidKeyException;
|
||||
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
|
||||
@@ -66,17 +65,14 @@ public class OutgoingCallActionProcessor extends DeviceAwareActionProcessor {
|
||||
|
||||
Log.i(TAG, "assign activePeer callId: " + remotePeer.getCallId() + " key: " + remotePeer.hashCode());
|
||||
|
||||
AudioManager androidAudioManager = ServiceUtil.getAudioManager(context);
|
||||
androidAudioManager.setSpeakerphoneOn(false);
|
||||
WebRtcUtil.enableSpeakerPhoneIfNeeded(context, currentState.getCallSetupState().isEnableVideoOnCreate());
|
||||
|
||||
webRtcInteractor.setCallInProgressNotification(TYPE_OUTGOING_RINGING, remotePeer);
|
||||
webRtcInteractor.setDefaultAudioDevice(currentState.getCallSetupState().isEnableVideoOnCreate() ? SignalAudioManager.AudioDevice.SPEAKER_PHONE
|
||||
: SignalAudioManager.AudioDevice.EARPIECE,
|
||||
false);
|
||||
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context));
|
||||
webRtcInteractor.initializeAudioForCall();
|
||||
webRtcInteractor.startOutgoingRinger();
|
||||
|
||||
webRtcInteractor.setCallInProgressNotification(TYPE_OUTGOING_RINGING, remotePeer);
|
||||
webRtcInteractor.setWantsBluetoothConnection(true);
|
||||
|
||||
RecipientUtil.setAndSendUniversalExpireTimerIfNecessary(context, Recipient.resolved(remotePeer.getId()), DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(remotePeer.getId()));
|
||||
DatabaseFactory.getSmsDatabase(context).insertOutgoingCall(remotePeer.getId(), currentState.getCallSetupState().isEnableVideoOnCreate());
|
||||
|
||||
@@ -87,7 +83,6 @@ public class OutgoingCallActionProcessor extends DeviceAwareActionProcessor {
|
||||
.callState(WebRtcViewModel.State.CALL_OUTGOING)
|
||||
.commit()
|
||||
.changeLocalDeviceState()
|
||||
.wantsBluetooth(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
package org.thoughtcrime.securesms.service.webrtc;
|
||||
|
||||
import static org.thoughtcrime.securesms.events.WebRtcViewModel.GroupCallState.IDLE;
|
||||
import static org.thoughtcrime.securesms.events.WebRtcViewModel.State.CALL_INCOMING;
|
||||
import static org.thoughtcrime.securesms.events.WebRtcViewModel.State.NETWORK_FAILURE;
|
||||
import static org.thoughtcrime.securesms.events.WebRtcViewModel.State.NO_SUCH_USER;
|
||||
import static org.thoughtcrime.securesms.events.WebRtcViewModel.State.UNTRUSTED_IDENTITY;
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcUtil.getUrgencyFromCallUrgency;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -85,6 +78,13 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.thoughtcrime.securesms.events.WebRtcViewModel.GroupCallState.IDLE;
|
||||
import static org.thoughtcrime.securesms.events.WebRtcViewModel.State.CALL_INCOMING;
|
||||
import static org.thoughtcrime.securesms.events.WebRtcViewModel.State.NETWORK_FAILURE;
|
||||
import static org.thoughtcrime.securesms.events.WebRtcViewModel.State.NO_SUCH_USER;
|
||||
import static org.thoughtcrime.securesms.events.WebRtcViewModel.State.UNTRUSTED_IDENTITY;
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcUtil.getUrgencyFromCallUrgency;
|
||||
|
||||
/**
|
||||
* Entry point for all things calling. Lives for the life of the app instance and will spin up a foreground service when needed to
|
||||
* handle "active" calls.
|
||||
@@ -126,7 +126,6 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
this.serviceState = new WebRtcServiceState(new IdleActionProcessor(new WebRtcInteractor(this.context,
|
||||
this,
|
||||
lockManager,
|
||||
new SignalAudioManager(context),
|
||||
this,
|
||||
this,
|
||||
this)));
|
||||
@@ -193,14 +192,6 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
process((s, p) -> p.handleOrientationChanged(s, isLandscapeEnabled, degrees));
|
||||
}
|
||||
|
||||
public void setAudioSpeaker(boolean isSpeaker) {
|
||||
process((s, p) -> p.handleSetSpeakerAudio(s, isSpeaker));
|
||||
}
|
||||
|
||||
public void setAudioBluetooth(boolean isBluetooth) {
|
||||
process((s, p) -> p.handleSetBluetoothAudio(s, isBluetooth));
|
||||
}
|
||||
|
||||
public void setMuteAudio(boolean enabled) {
|
||||
process((s, p) -> p.handleSetMuteAudio(s, enabled));
|
||||
}
|
||||
@@ -237,10 +228,6 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
process((s, p) -> p.handleIsInCallQuery(s, resultReceiver));
|
||||
}
|
||||
|
||||
public void wiredHeadsetChange(boolean available) {
|
||||
process((s, p) -> p.handleWiredHeadsetChange(s, available));
|
||||
}
|
||||
|
||||
public void networkChange(boolean available) {
|
||||
process((s, p) -> p.handleNetworkChanged(s, available));
|
||||
}
|
||||
@@ -253,10 +240,6 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
process((s, p) -> p.handleScreenOffChange(s));
|
||||
}
|
||||
|
||||
public void bluetoothChange(boolean available) {
|
||||
process((s, p) -> p.handleBluetoothChange(s, available));
|
||||
}
|
||||
|
||||
public void postStateUpdate(@NonNull WebRtcServiceState state) {
|
||||
EventBus.getDefault().postSticky(new WebRtcViewModel(state));
|
||||
}
|
||||
@@ -299,6 +282,14 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
process((s, p) -> p.handleReceivedGroupCallPeekForRingingCheck(s, groupCallRingCheckInfo, deviceCount));
|
||||
}
|
||||
|
||||
public void onAudioDeviceChanged(@NonNull SignalAudioManager.AudioDevice activeDevice, @NonNull Set<SignalAudioManager.AudioDevice> availableDevices) {
|
||||
process((s, p) -> p.handleAudioDeviceChanged(s, activeDevice, availableDevices));
|
||||
}
|
||||
|
||||
public void selectAudioDevice(@NonNull SignalAudioManager.AudioDevice desiredDevice) {
|
||||
process((s, p) -> p.handleSetUserAudioDevice(s, desiredDevice));
|
||||
}
|
||||
|
||||
public void peekGroupCall(@NonNull RecipientId id) {
|
||||
if (callManager == null) {
|
||||
Log.i(TAG, "Unable to peekGroupCall, call manager is null");
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
package org.thoughtcrime.securesms.service.webrtc;
|
||||
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcData.AnswerMetadata;
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcData.HangupMetadata;
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcData.ReceivedAnswerMetadata;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.ResultReceiver;
|
||||
|
||||
@@ -39,6 +35,7 @@ import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder;
|
||||
import org.thoughtcrime.securesms.util.NetworkUtil;
|
||||
import org.thoughtcrime.securesms.util.TelephonyUtil;
|
||||
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager;
|
||||
import org.thoughtcrime.securesms.webrtc.locks.LockManager;
|
||||
import org.webrtc.PeerConnection;
|
||||
import org.whispersystems.libsignal.IdentityKey;
|
||||
@@ -52,8 +49,13 @@ import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMess
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcData.AnswerMetadata;
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcData.HangupMetadata;
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcData.ReceivedAnswerMetadata;
|
||||
|
||||
/**
|
||||
* Base WebRTC action processor and core of the calling state machine. As actions (as intents)
|
||||
* are sent to the service, they are passed to an instance of the current state's action processor.
|
||||
@@ -370,6 +372,16 @@ public abstract class WebRtcActionProcessor {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
protected @NonNull WebRtcServiceState handleAudioDeviceChanged(@NonNull WebRtcServiceState currentState, @NonNull SignalAudioManager.AudioDevice activeDevice, @NonNull Set<SignalAudioManager.AudioDevice> availableDevices) {
|
||||
Log.i(tag, "handleAudioDeviceChanged not processed");
|
||||
return currentState;
|
||||
}
|
||||
|
||||
protected @NonNull WebRtcServiceState handleSetUserAudioDevice(@NonNull WebRtcServiceState currentState, @NonNull SignalAudioManager.AudioDevice userDevice) {
|
||||
Log.i(tag, "handleSetUserAudioDevice not processed");
|
||||
return currentState;
|
||||
}
|
||||
|
||||
//endregion Active call
|
||||
|
||||
//region Call setup
|
||||
@@ -410,16 +422,6 @@ public abstract class WebRtcActionProcessor {
|
||||
return currentState;
|
||||
}
|
||||
|
||||
protected @NonNull WebRtcServiceState handleSetSpeakerAudio(@NonNull WebRtcServiceState currentState, boolean isSpeaker) {
|
||||
Log.i(tag, "handleSetSpeakerAudio not processed");
|
||||
return currentState;
|
||||
}
|
||||
|
||||
protected @NonNull WebRtcServiceState handleSetBluetoothAudio(@NonNull WebRtcServiceState currentState, boolean isBluetooth) {
|
||||
Log.i(tag, "handleSetBluetoothAudio not processed");
|
||||
return currentState;
|
||||
}
|
||||
|
||||
protected @NonNull WebRtcServiceState handleSetCameraFlip(@NonNull WebRtcServiceState currentState) {
|
||||
Log.i(tag, "handleSetCameraFlip not processed");
|
||||
return currentState;
|
||||
@@ -430,16 +432,6 @@ public abstract class WebRtcActionProcessor {
|
||||
return currentState;
|
||||
}
|
||||
|
||||
protected @NonNull WebRtcServiceState handleBluetoothChange(@NonNull WebRtcServiceState currentState, boolean available) {
|
||||
Log.i(tag, "handleBluetoothChange not processed");
|
||||
return currentState;
|
||||
}
|
||||
|
||||
protected @NonNull WebRtcServiceState handleWiredHeadsetChange(@NonNull WebRtcServiceState currentState, boolean present) {
|
||||
Log.i(tag, "handleWiredHeadsetChange not processed");
|
||||
return currentState;
|
||||
}
|
||||
|
||||
public @NonNull WebRtcServiceState handleCameraSwitchCompleted(@NonNull WebRtcServiceState currentState, @NonNull CameraState newCameraState) {
|
||||
Log.i(tag, "handleCameraSwitchCompleted not processed");
|
||||
return currentState;
|
||||
@@ -564,7 +556,6 @@ public abstract class WebRtcActionProcessor {
|
||||
(activePeer.getState() == CallState.CONNECTED);
|
||||
webRtcInteractor.stopAudio(playDisconnectSound);
|
||||
|
||||
webRtcInteractor.setWantsBluetoothConnection(false);
|
||||
webRtcInteractor.updatePhoneState(LockManager.PhoneState.IDLE);
|
||||
webRtcInteractor.stopForegroundService();
|
||||
|
||||
@@ -574,7 +565,6 @@ public abstract class WebRtcActionProcessor {
|
||||
.activePeer(null)
|
||||
.commit()
|
||||
.changeLocalDeviceState()
|
||||
.wantsBluetooth(false)
|
||||
.commit()
|
||||
.actionProcessor(currentState.getCallInfoState().getCallState() == WebRtcViewModel.State.CALL_DISCONNECTED ? new DisconnectingCallActionProcessor(webRtcInteractor) : new IdleActionProcessor(webRtcInteractor))
|
||||
.terminate()
|
||||
@@ -723,7 +713,6 @@ public abstract class WebRtcActionProcessor {
|
||||
webRtcInteractor.updatePhoneState(LockManager.PhoneState.PROCESSING);
|
||||
boolean playDisconnectSound = currentState.getCallInfoState().getCallState() == WebRtcViewModel.State.CALL_DISCONNECTED;
|
||||
webRtcInteractor.stopAudio(playDisconnectSound);
|
||||
webRtcInteractor.setWantsBluetoothConnection(false);
|
||||
webRtcInteractor.updatePhoneState(LockManager.PhoneState.IDLE);
|
||||
webRtcInteractor.stopForegroundService();
|
||||
|
||||
|
||||
@@ -6,10 +6,8 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.media.AudioManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.TelephonyManager;
|
||||
@@ -25,16 +23,18 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.TelephonyUtil;
|
||||
import org.thoughtcrime.securesms.webrtc.CallNotificationBuilder;
|
||||
import org.thoughtcrime.securesms.webrtc.UncaughtExceptionHandlerManager;
|
||||
import org.thoughtcrime.securesms.webrtc.audio.BluetoothStateManager;
|
||||
import org.thoughtcrime.securesms.webrtc.audio.AudioManagerCommand;
|
||||
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager;
|
||||
import org.thoughtcrime.securesms.webrtc.locks.LockManager;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Provide a foreground service for {@link SignalCallManager} to leverage to run in the background when necessary. Also
|
||||
* provides devices listeners needed for during a call (i.e., bluetooth, power button).
|
||||
*/
|
||||
public final class WebRtcCallService extends Service implements BluetoothStateManager.BluetoothStateListener {
|
||||
public final class WebRtcCallService extends Service implements SignalAudioManager.EventListener {
|
||||
|
||||
private static final String TAG = Log.tag(WebRtcCallService.class);
|
||||
|
||||
@@ -42,23 +42,23 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
|
||||
private static final String ACTION_STOP = "STOP";
|
||||
private static final String ACTION_DENY_CALL = "DENY_CALL";
|
||||
private static final String ACTION_LOCAL_HANGUP = "LOCAL_HANGUP";
|
||||
private static final String ACTION_WANTS_BLUETOOTH = "WANTS_BLUETOOTH";
|
||||
private static final String ACTION_CHANGE_POWER_BUTTON = "CHANGE_POWER_BUTTON";
|
||||
private static final String ACTION_SEND_AUDIO_COMMAND = "SEND_AUDIO_COMMAND";
|
||||
|
||||
private static final String EXTRA_UPDATE_TYPE = "UPDATE_TYPE";
|
||||
private static final String EXTRA_RECIPIENT_ID = "RECIPIENT_ID";
|
||||
private static final String EXTRA_ENABLED = "ENABLED";
|
||||
private static final String EXTRA_UPDATE_TYPE = "UPDATE_TYPE";
|
||||
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 int INVALID_NOTIFICATION_ID = -1;
|
||||
|
||||
private SignalCallManager callManager;
|
||||
|
||||
private WiredHeadsetStateReceiver wiredHeadsetStateReceiver;
|
||||
private NetworkReceiver networkReceiver;
|
||||
private PowerButtonReceiver powerButtonReceiver;
|
||||
private UncaughtExceptionHandlerManager uncaughtExceptionHandlerManager;
|
||||
private PhoneStateListener hangUpRtcOnDeviceCallAnswered;
|
||||
private BluetoothStateManager bluetoothStateManager;
|
||||
private SignalAudioManager signalAudioManager;
|
||||
private int lastNotificationId;
|
||||
private Notification lastNotification;
|
||||
|
||||
@@ -86,11 +86,10 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
|
||||
return new Intent(context, WebRtcCallService.class).setAction(ACTION_LOCAL_HANGUP);
|
||||
}
|
||||
|
||||
public static void setWantsBluetoothConnection(@NonNull Context context, boolean enabled) {
|
||||
public static void sendAudioManagerCommand(@NonNull Context context, @NonNull AudioManagerCommand command) {
|
||||
Intent intent = new Intent(context, WebRtcCallService.class);
|
||||
intent.setAction(ACTION_WANTS_BLUETOOTH)
|
||||
.putExtra(EXTRA_ENABLED, enabled);
|
||||
|
||||
intent.setAction(ACTION_SEND_AUDIO_COMMAND)
|
||||
.putExtra(EXTRA_AUDIO_COMMAND, command);
|
||||
ContextCompat.startForegroundService(context, intent);
|
||||
}
|
||||
|
||||
@@ -107,12 +106,11 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
|
||||
Log.v(TAG, "onCreate");
|
||||
super.onCreate();
|
||||
this.callManager = ApplicationDependencies.getSignalCallManager();
|
||||
this.bluetoothStateManager = new BluetoothStateManager(this, this);
|
||||
this.signalAudioManager = new SignalAudioManager(this, this);
|
||||
this.hangUpRtcOnDeviceCallAnswered = new HangUpRtcOnPstnCallAnsweredListener();
|
||||
this.lastNotificationId = INVALID_NOTIFICATION_ID;
|
||||
|
||||
registerUncaughtExceptionHandler();
|
||||
registerWiredHeadsetStateReceiver();
|
||||
registerNetworkReceiver();
|
||||
|
||||
TelephonyUtil.getManager(this)
|
||||
@@ -128,13 +126,8 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
|
||||
uncaughtExceptionHandlerManager.unregister();
|
||||
}
|
||||
|
||||
if (bluetoothStateManager != null) {
|
||||
bluetoothStateManager.onDestroy();
|
||||
}
|
||||
|
||||
if (wiredHeadsetStateReceiver != null) {
|
||||
unregisterReceiver(wiredHeadsetStateReceiver);
|
||||
wiredHeadsetStateReceiver = null;
|
||||
if (signalAudioManager != null) {
|
||||
signalAudioManager.shutdown();
|
||||
}
|
||||
|
||||
unregisterNetworkReceiver();
|
||||
@@ -157,11 +150,9 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
|
||||
setCallInProgressNotification(intent.getIntExtra(EXTRA_UPDATE_TYPE, 0),
|
||||
Objects.requireNonNull(intent.getParcelableExtra(EXTRA_RECIPIENT_ID)));
|
||||
return START_STICKY;
|
||||
case ACTION_WANTS_BLUETOOTH:
|
||||
case ACTION_SEND_AUDIO_COMMAND:
|
||||
setCallNotification();
|
||||
if (bluetoothStateManager != null) {
|
||||
bluetoothStateManager.setWantsConnection(intent.getBooleanExtra(EXTRA_ENABLED, false));
|
||||
}
|
||||
signalAudioManager.handleCommand(Objects.requireNonNull(intent.getParcelableExtra(EXTRA_AUDIO_COMMAND)));
|
||||
return START_STICKY;
|
||||
case ACTION_CHANGE_POWER_BUTTON:
|
||||
setCallNotification();
|
||||
@@ -215,20 +206,6 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
|
||||
uncaughtExceptionHandlerManager.registerHandler(new ProximityLockRelease(callManager.getLockManager()));
|
||||
}
|
||||
|
||||
private void registerWiredHeadsetStateReceiver() {
|
||||
wiredHeadsetStateReceiver = new WiredHeadsetStateReceiver();
|
||||
|
||||
String action;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
action = AudioManager.ACTION_HEADSET_PLUG;
|
||||
} else {
|
||||
action = Intent.ACTION_HEADSET_PLUG;
|
||||
}
|
||||
|
||||
registerReceiver(wiredHeadsetStateReceiver, new IntentFilter(action));
|
||||
}
|
||||
|
||||
private void registerNetworkReceiver() {
|
||||
if (networkReceiver == null) {
|
||||
networkReceiver = new NetworkReceiver();
|
||||
@@ -267,8 +244,8 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBluetoothStateChanged(boolean isAvailable) {
|
||||
callManager.bluetoothChange(isAvailable);
|
||||
public void onAudioDeviceChanged(@NonNull SignalAudioManager.AudioDevice activeDevice, @NonNull Set<SignalAudioManager.AudioDevice> availableDevices) {
|
||||
callManager.onAudioDeviceChanged(activeDevice, availableDevices);
|
||||
}
|
||||
|
||||
private class HangUpRtcOnPstnCallAnsweredListener extends PhoneStateListener {
|
||||
@@ -286,15 +263,6 @@ public final class WebRtcCallService extends Service implements BluetoothStateMa
|
||||
}
|
||||
}
|
||||
|
||||
private static class WiredHeadsetStateReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(@NonNull Context context, @NonNull Intent intent) {
|
||||
int state = intent.getIntExtra("state", -1);
|
||||
|
||||
ApplicationDependencies.getSignalCallManager().wiredHeadsetChange(state != 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NetworkReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
@@ -14,7 +14,7 @@ import org.thoughtcrime.securesms.ringrtc.CameraEventListener;
|
||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
import org.thoughtcrime.securesms.util.AppForegroundObserver;
|
||||
import org.thoughtcrime.securesms.webrtc.audio.OutgoingRinger;
|
||||
import org.thoughtcrime.securesms.webrtc.audio.AudioManagerCommand;
|
||||
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager;
|
||||
import org.thoughtcrime.securesms.webrtc.locks.LockManager;
|
||||
import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage;
|
||||
@@ -32,7 +32,6 @@ public class WebRtcInteractor {
|
||||
@NonNull private final Context context;
|
||||
@NonNull private final SignalCallManager signalCallManager;
|
||||
@NonNull private final LockManager lockManager;
|
||||
@NonNull private final SignalAudioManager audioManager;
|
||||
@NonNull private final CameraEventListener cameraEventListener;
|
||||
@NonNull private final GroupCall.Observer groupCallObserver;
|
||||
@NonNull private final AppForegroundObserver.Listener foregroundListener;
|
||||
@@ -40,7 +39,6 @@ public class WebRtcInteractor {
|
||||
public WebRtcInteractor(@NonNull Context context,
|
||||
@NonNull SignalCallManager signalCallManager,
|
||||
@NonNull LockManager lockManager,
|
||||
@NonNull SignalAudioManager audioManager,
|
||||
@NonNull CameraEventListener cameraEventListener,
|
||||
@NonNull GroupCall.Observer groupCallObserver,
|
||||
@NonNull AppForegroundObserver.Listener foregroundListener)
|
||||
@@ -48,7 +46,6 @@ public class WebRtcInteractor {
|
||||
this.context = context;
|
||||
this.signalCallManager = signalCallManager;
|
||||
this.lockManager = lockManager;
|
||||
this.audioManager = audioManager;
|
||||
this.cameraEventListener = cameraEventListener;
|
||||
this.groupCallObserver = groupCallObserver;
|
||||
this.foregroundListener = foregroundListener;
|
||||
@@ -74,10 +71,6 @@ public class WebRtcInteractor {
|
||||
return foregroundListener;
|
||||
}
|
||||
|
||||
void setWantsBluetoothConnection(boolean enabled) {
|
||||
WebRtcCallService.setWantsBluetoothConnection(context, enabled);
|
||||
}
|
||||
|
||||
void updatePhoneState(@NonNull LockManager.PhoneState phoneState) {
|
||||
lockManager.updatePhoneState(phoneState);
|
||||
}
|
||||
@@ -131,27 +124,35 @@ public class WebRtcInteractor {
|
||||
}
|
||||
|
||||
void silenceIncomingRinger() {
|
||||
audioManager.silenceIncomingRinger();
|
||||
WebRtcCallService.sendAudioManagerCommand(context, new AudioManagerCommand.SilenceIncomingRinger());
|
||||
}
|
||||
|
||||
void initializeAudioForCall() {
|
||||
audioManager.initializeAudioForCall();
|
||||
WebRtcCallService.sendAudioManagerCommand(context, new AudioManagerCommand.Initialize());
|
||||
}
|
||||
|
||||
void startIncomingRinger(@Nullable Uri ringtoneUri, boolean vibrate) {
|
||||
audioManager.startIncomingRinger(ringtoneUri, vibrate);
|
||||
WebRtcCallService.sendAudioManagerCommand(context, new AudioManagerCommand.StartIncomingRinger(ringtoneUri, vibrate));
|
||||
}
|
||||
|
||||
void startOutgoingRinger() {
|
||||
audioManager.startOutgoingRinger(OutgoingRinger.Type.RINGING);
|
||||
WebRtcCallService.sendAudioManagerCommand(context, new AudioManagerCommand.StartOutgoingRinger());
|
||||
}
|
||||
|
||||
void stopAudio(boolean playDisconnect) {
|
||||
audioManager.stop(playDisconnect);
|
||||
WebRtcCallService.sendAudioManagerCommand(context, new AudioManagerCommand.Stop(playDisconnect));
|
||||
}
|
||||
|
||||
void startAudioCommunication(boolean preserveSpeakerphone) {
|
||||
audioManager.startCommunication(preserveSpeakerphone);
|
||||
void startAudioCommunication() {
|
||||
WebRtcCallService.sendAudioManagerCommand(context, new AudioManagerCommand.Start());
|
||||
}
|
||||
|
||||
public void setUserAudioDevice(@NonNull SignalAudioManager.AudioDevice userDevice) {
|
||||
WebRtcCallService.sendAudioManagerCommand(context, new AudioManagerCommand.SetUserDevice(userDevice));
|
||||
}
|
||||
|
||||
public void setDefaultAudioDevice(@NonNull SignalAudioManager.AudioDevice userDevice, boolean clearUserEarpieceSelection) {
|
||||
WebRtcCallService.sendAudioManagerCommand(context, new AudioManagerCommand.SetDefaultDevice(userDevice, clearUserEarpieceSelection));
|
||||
}
|
||||
|
||||
void peekGroupCallForRingingCheck(@NonNull GroupCallRingCheckInfo groupCallRingCheckInfo) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.thoughtcrime.securesms.service.webrtc;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -9,8 +8,11 @@ import androidx.annotation.Nullable;
|
||||
import org.signal.ringrtc.CallManager;
|
||||
import org.signal.ringrtc.GroupCall;
|
||||
import org.signal.ringrtc.PeekInfo;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.events.WebRtcViewModel;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
import org.thoughtcrime.securesms.webrtc.audio.AudioManagerCompat;
|
||||
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager;
|
||||
import org.thoughtcrime.securesms.webrtc.locks.LockManager;
|
||||
import org.whispersystems.libsignal.InvalidKeyException;
|
||||
import org.whispersystems.libsignal.ecc.Curve;
|
||||
@@ -32,7 +34,7 @@ public final class WebRtcUtil {
|
||||
}
|
||||
|
||||
public static @NonNull LockManager.PhoneState getInCallPhoneState(@NonNull Context context) {
|
||||
AudioManager audioManager = ServiceUtil.getAudioManager(context);
|
||||
AudioManagerCompat audioManager = ApplicationDependencies.getAndroidCallAudioManager();
|
||||
if (audioManager.isSpeakerphoneOn() || audioManager.isBluetoothScoOn() || audioManager.isWiredHeadsetOn()) {
|
||||
return LockManager.PhoneState.IN_HANDS_FREE_CALL;
|
||||
} else {
|
||||
@@ -72,17 +74,15 @@ public final class WebRtcUtil {
|
||||
return OpaqueMessage.Urgency.DROPPABLE;
|
||||
}
|
||||
|
||||
public static void enableSpeakerPhoneIfNeeded(@NonNull Context context, boolean enable) {
|
||||
if (!enable) {
|
||||
public static void enableSpeakerPhoneIfNeeded(@NonNull WebRtcInteractor webRtcInteractor, WebRtcServiceState currentState) {
|
||||
if (!currentState.getLocalDeviceState().getCameraState().isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AudioManager androidAudioManager = ServiceUtil.getAudioManager(context);
|
||||
//noinspection deprecation
|
||||
boolean shouldEnable = !(androidAudioManager.isSpeakerphoneOn() || androidAudioManager.isBluetoothScoOn() || androidAudioManager.isWiredHeadsetOn());
|
||||
|
||||
if (shouldEnable) {
|
||||
androidAudioManager.setSpeakerphoneOn(true);
|
||||
if (currentState.getLocalDeviceState().getActiveDevice() == SignalAudioManager.AudioDevice.EARPIECE ||
|
||||
currentState.getLocalDeviceState().getActiveDevice() == SignalAudioManager.AudioDevice.NONE)
|
||||
{
|
||||
webRtcInteractor.setDefaultAudioDevice(SignalAudioManager.AudioDevice.SPEAKER_PHONE, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
package org.thoughtcrime.securesms.service.webrtc.state;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.components.sensors.Orientation;
|
||||
import org.thoughtcrime.securesms.ringrtc.CameraState;
|
||||
|
||||
/**
|
||||
* Local device specific state.
|
||||
*/
|
||||
public final class LocalDeviceState {
|
||||
CameraState cameraState;
|
||||
boolean microphoneEnabled;
|
||||
boolean bluetoothAvailable;
|
||||
boolean wantsBluetooth;
|
||||
Orientation orientation;
|
||||
boolean isLandscapeEnabled;
|
||||
Orientation deviceOrientation;
|
||||
|
||||
LocalDeviceState() {
|
||||
this(CameraState.UNKNOWN, true, false, false, Orientation.PORTRAIT_BOTTOM_EDGE, false, Orientation.PORTRAIT_BOTTOM_EDGE);
|
||||
}
|
||||
|
||||
LocalDeviceState(@NonNull LocalDeviceState toCopy) {
|
||||
this(toCopy.cameraState, toCopy.microphoneEnabled, toCopy.bluetoothAvailable, toCopy.wantsBluetooth, toCopy.orientation, toCopy.isLandscapeEnabled, toCopy.deviceOrientation);
|
||||
}
|
||||
|
||||
LocalDeviceState(@NonNull CameraState cameraState,
|
||||
boolean microphoneEnabled,
|
||||
boolean bluetoothAvailable,
|
||||
boolean wantsBluetooth,
|
||||
@NonNull Orientation orientation,
|
||||
boolean isLandscapeEnabled,
|
||||
@NonNull Orientation deviceOrientation)
|
||||
{
|
||||
this.cameraState = cameraState;
|
||||
this.microphoneEnabled = microphoneEnabled;
|
||||
this.bluetoothAvailable = bluetoothAvailable;
|
||||
this.wantsBluetooth = wantsBluetooth;
|
||||
this.orientation = orientation;
|
||||
this.isLandscapeEnabled = isLandscapeEnabled;
|
||||
this.deviceOrientation = deviceOrientation;
|
||||
}
|
||||
|
||||
public @NonNull CameraState getCameraState() {
|
||||
return cameraState;
|
||||
}
|
||||
|
||||
public boolean isMicrophoneEnabled() {
|
||||
return microphoneEnabled;
|
||||
}
|
||||
|
||||
public boolean isBluetoothAvailable() {
|
||||
return bluetoothAvailable;
|
||||
}
|
||||
|
||||
public boolean wantsBluetooth() {
|
||||
return wantsBluetooth;
|
||||
}
|
||||
|
||||
public @NonNull Orientation getOrientation() {
|
||||
return orientation;
|
||||
}
|
||||
|
||||
public boolean isLandscapeEnabled() {
|
||||
return isLandscapeEnabled;
|
||||
}
|
||||
|
||||
public @NonNull Orientation getDeviceOrientation() {
|
||||
return deviceOrientation;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.thoughtcrime.securesms.service.webrtc.state
|
||||
|
||||
import org.thoughtcrime.securesms.components.sensors.Orientation
|
||||
import org.thoughtcrime.securesms.ringrtc.CameraState
|
||||
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager
|
||||
|
||||
/**
|
||||
* Local device specific state.
|
||||
*/
|
||||
data class LocalDeviceState constructor(
|
||||
var cameraState: CameraState = CameraState.UNKNOWN,
|
||||
var isMicrophoneEnabled: Boolean = true,
|
||||
var orientation: Orientation = Orientation.PORTRAIT_BOTTOM_EDGE,
|
||||
var isLandscapeEnabled: Boolean = false,
|
||||
var deviceOrientation: Orientation = Orientation.PORTRAIT_BOTTOM_EDGE,
|
||||
var activeDevice: SignalAudioManager.AudioDevice = SignalAudioManager.AudioDevice.NONE,
|
||||
var availableDevices: Set<SignalAudioManager.AudioDevice> = emptySet()
|
||||
) {
|
||||
|
||||
fun duplicate(): LocalDeviceState {
|
||||
return copy()
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ public final class WebRtcServiceState {
|
||||
this.actionProcessor = toCopy.actionProcessor;
|
||||
this.callSetupState = toCopy.callSetupState.duplicate();
|
||||
this.callInfoState = new CallInfoState(toCopy.callInfoState);
|
||||
this.localDeviceState = new LocalDeviceState(toCopy.localDeviceState);
|
||||
this.localDeviceState = toCopy.localDeviceState.duplicate();
|
||||
this.videoState = new VideoState(toCopy.videoState);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,10 @@ import org.thoughtcrime.securesms.ringrtc.Camera;
|
||||
import org.thoughtcrime.securesms.ringrtc.CameraState;
|
||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
||||
import org.thoughtcrime.securesms.service.webrtc.WebRtcActionProcessor;
|
||||
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Builder that creates a new {@link WebRtcServiceState} from an existing one and allows
|
||||
@@ -73,7 +75,7 @@ public class WebRtcServiceStateBuilder {
|
||||
private LocalDeviceState toBuild;
|
||||
|
||||
public LocalDeviceStateBuilder() {
|
||||
toBuild = new LocalDeviceState(WebRtcServiceStateBuilder.this.toBuild.localDeviceState);
|
||||
toBuild = WebRtcServiceStateBuilder.this.toBuild.localDeviceState.duplicate();
|
||||
}
|
||||
|
||||
public @NonNull WebRtcServiceStateBuilder commit() {
|
||||
@@ -87,37 +89,37 @@ public class WebRtcServiceStateBuilder {
|
||||
}
|
||||
|
||||
public @NonNull LocalDeviceStateBuilder cameraState(@NonNull CameraState cameraState) {
|
||||
toBuild.cameraState = cameraState;
|
||||
toBuild.setCameraState(cameraState);
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull LocalDeviceStateBuilder isMicrophoneEnabled(boolean enabled) {
|
||||
toBuild.microphoneEnabled = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull LocalDeviceStateBuilder isBluetoothAvailable(boolean available) {
|
||||
toBuild.bluetoothAvailable = available;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull LocalDeviceStateBuilder wantsBluetooth(boolean wantsBluetooth) {
|
||||
toBuild.wantsBluetooth = wantsBluetooth;
|
||||
toBuild.setMicrophoneEnabled(enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull LocalDeviceStateBuilder setOrientation(@NonNull Orientation orientation) {
|
||||
toBuild.orientation = orientation;
|
||||
toBuild.setOrientation(orientation);
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull LocalDeviceStateBuilder setLandscapeEnabled(boolean isLandscapeEnabled) {
|
||||
toBuild.isLandscapeEnabled = isLandscapeEnabled;
|
||||
toBuild.setLandscapeEnabled(isLandscapeEnabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull LocalDeviceStateBuilder setDeviceOrientation(@NonNull Orientation deviceOrientation) {
|
||||
toBuild.deviceOrientation = deviceOrientation;
|
||||
toBuild.setDeviceOrientation(deviceOrientation);
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull LocalDeviceStateBuilder setActiveDevice(@NonNull SignalAudioManager.AudioDevice audioDevice) {
|
||||
toBuild.setActiveDevice(audioDevice);
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull LocalDeviceStateBuilder setAvailableDevices(@NonNull Set<SignalAudioManager.AudioDevice> availableDevices) {
|
||||
toBuild.setAvailableDevices(availableDevices);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user