support mute via call integration
This commit is contained in:
parent
069b02004f
commit
d904b5e303
|
@ -39,7 +39,7 @@ public class CallIntegration extends Connection {
|
||||||
private static final List<String> BROKEN_DEVICE_MODELS =
|
private static final List<String> BROKEN_DEVICE_MODELS =
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
"OnePlus6" // OnePlus 6 (Android 8.1-11) Device is buggy and always starts the
|
"OnePlus6" // OnePlus 6 (Android 8.1-11) Device is buggy and always starts the
|
||||||
// OS call screen even though we want to be self managed
|
// OS call screen even though we want to be self managed
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final int DEFAULT_TONE_VOLUME = 60;
|
public static final int DEFAULT_TONE_VOLUME = 60;
|
||||||
|
@ -56,6 +56,7 @@ public class CallIntegration extends Connection {
|
||||||
private final AtomicBoolean isDestroyed = new AtomicBoolean(false);
|
private final AtomicBoolean isDestroyed = new AtomicBoolean(false);
|
||||||
|
|
||||||
private List<CallEndpoint> availableEndpoints = Collections.emptyList();
|
private List<CallEndpoint> availableEndpoints = Collections.emptyList();
|
||||||
|
private boolean isMicrophoneEnabled = true;
|
||||||
|
|
||||||
private Callback callback = null;
|
private Callback callback = null;
|
||||||
|
|
||||||
|
@ -74,6 +75,7 @@ public class CallIntegration extends Connection {
|
||||||
this.appRTCAudioManager.setAudioManagerEvents(this::onAudioDeviceChanged);
|
this.appRTCAudioManager.setAudioManagerEvents(this::onAudioDeviceChanged);
|
||||||
}
|
}
|
||||||
setRingbackRequested(true);
|
setRingbackRequested(true);
|
||||||
|
setConnectionCapabilities(CAPABILITY_MUTE | CAPABILITY_RESPOND_VIA_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCallback(final Callback callback) {
|
public void setCallback(final Callback callback) {
|
||||||
|
@ -139,10 +141,26 @@ public class CallIntegration extends Connection {
|
||||||
Log.d(Config.LOGTAG, "ignoring onCallAudioStateChange() on Upside Down Cake");
|
Log.d(Config.LOGTAG, "ignoring onCallAudioStateChange() on Upside Down Cake");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
setMicrophoneEnabled(!state.isMuted());
|
||||||
Log.d(Config.LOGTAG, "onCallAudioStateChange(" + state + ")");
|
Log.d(Config.LOGTAG, "onCallAudioStateChange(" + state + ")");
|
||||||
this.onAudioDeviceChanged(getAudioDeviceOreo(state), getAudioDevicesOreo(state));
|
this.onAudioDeviceChanged(getAudioDeviceOreo(state), getAudioDevicesOreo(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMuteStateChanged(final boolean isMuted) {
|
||||||
|
Log.d(Config.LOGTAG, "onMuteStateChanged(" + isMuted + ")");
|
||||||
|
setMicrophoneEnabled(!isMuted);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setMicrophoneEnabled(final boolean enabled) {
|
||||||
|
this.isMicrophoneEnabled = enabled;
|
||||||
|
this.callback.onCallIntegrationMicrophoneEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMicrophoneEnabled() {
|
||||||
|
return this.isMicrophoneEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
public Set<AudioDevice> getAudioDevices() {
|
public Set<AudioDevice> getAudioDevices() {
|
||||||
if (notSelfManaged(context)) {
|
if (notSelfManaged(context)) {
|
||||||
return getAudioDevicesFallback();
|
return getAudioDevicesFallback();
|
||||||
|
@ -578,5 +596,7 @@ public class CallIntegration extends Connection {
|
||||||
void onCallIntegrationAnswer();
|
void onCallIntegrationAnswer();
|
||||||
|
|
||||||
void onCallIntegrationSilence();
|
void onCallIntegrationSilence();
|
||||||
|
|
||||||
|
void onCallIntegrationMicrophoneEnabled(boolean enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ public class NotificationsSettingsFragment extends XmppPreferenceFragment {
|
||||||
try {
|
try {
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
} catch (final ActivityNotFoundException e) {
|
} catch (final ActivityNotFoundException e) {
|
||||||
Toast.makeText(requireContext(), R.string.no_application_found, Toast.LENGTH_SHORT)
|
Toast.makeText(requireContext(), R.string.unsupported_operation, Toast.LENGTH_SHORT)
|
||||||
.show();
|
.show();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -649,7 +649,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public JingleRtpConnection getOngoingRtpConnection() {
|
public JingleRtpConnection getOngoingRtpConnection() {
|
||||||
for(final AbstractJingleConnection jingleConnection : this.connections.values()) {
|
for (final AbstractJingleConnection jingleConnection : this.connections.values()) {
|
||||||
if (jingleConnection instanceof JingleRtpConnection jingleRtpConnection) {
|
if (jingleConnection instanceof JingleRtpConnection jingleRtpConnection) {
|
||||||
if (jingleRtpConnection.isTerminated()) {
|
if (jingleRtpConnection.isTerminated()) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -986,10 +986,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
this.rtpSessionProposals.remove(sessionProposal);
|
this.rtpSessionProposals.remove(sessionProposal);
|
||||||
sessionProposal.getCallIntegration().error();
|
sessionProposal.getCallIntegration().error();
|
||||||
mXmppConnectionService.notifyJingleRtpConnectionUpdate(
|
mXmppConnectionService.notifyJingleRtpConnectionUpdate(
|
||||||
account,
|
account, sessionProposal.with, sessionProposal.sessionId, endUserState);
|
||||||
sessionProposal.with,
|
|
||||||
sessionProposal.sessionId,
|
|
||||||
endUserState);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1226,5 +1223,8 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCallIntegrationSilence() {}
|
public void onCallIntegrationSilence() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCallIntegrationMicrophoneEnabled(boolean enabled) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2324,6 +2324,7 @@ public class JingleRtpConnection extends AbstractJingleConnection
|
||||||
this.jingleConnectionManager.ensureConnectionIsRegistered(this);
|
this.jingleConnectionManager.ensureConnectionIsRegistered(this);
|
||||||
this.webRTCWrapper.setup(this.xmppConnectionService);
|
this.webRTCWrapper.setup(this.xmppConnectionService);
|
||||||
this.webRTCWrapper.initializePeerConnection(media, iceServers, trickle);
|
this.webRTCWrapper.initializePeerConnection(media, iceServers, trickle);
|
||||||
|
this.webRTCWrapper.setMicrophoneEnabledOrThrow(callIntegration.isMicrophoneEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void acceptCallFromProposed() {
|
private void acceptCallFromProposed() {
|
||||||
|
@ -2686,7 +2687,7 @@ public class JingleRtpConnection extends AbstractJingleConnection
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setMicrophoneEnabled(final boolean enabled) {
|
public boolean setMicrophoneEnabled(final boolean enabled) {
|
||||||
return webRTCWrapper.setMicrophoneEnabled(enabled);
|
return webRTCWrapper.setMicrophoneEnabledOrThrow(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVideoEnabled() {
|
public boolean isVideoEnabled() {
|
||||||
|
@ -2762,6 +2763,11 @@ public class JingleRtpConnection extends AbstractJingleConnection
|
||||||
xmppConnectionService.getNotificationService().stopSoundAndVibration();
|
xmppConnectionService.getNotificationService().stopSoundAndVibration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCallIntegrationMicrophoneEnabled(final boolean enabled) {
|
||||||
|
this.webRTCWrapper.setMicrophoneEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAudioDeviceChanged(
|
public void onAudioDeviceChanged(
|
||||||
final CallIntegration.AudioDevice selectedAudioDevice,
|
final CallIntegration.AudioDevice selectedAudioDevice,
|
||||||
|
|
|
@ -506,23 +506,36 @@ public class WebRTCWrapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean setMicrophoneEnabled(final boolean enabled) {
|
boolean setMicrophoneEnabledOrThrow(final boolean enabled) {
|
||||||
final Optional<AudioTrack> audioTrack =
|
final Optional<AudioTrack> audioTrack =
|
||||||
TrackWrapper.get(peerConnection, this.localAudioTrack);
|
TrackWrapper.get(peerConnection, this.localAudioTrack);
|
||||||
if (audioTrack.isPresent()) {
|
if (audioTrack.isPresent()) {
|
||||||
try {
|
return setEnabled(audioTrack.get(), enabled);
|
||||||
audioTrack.get().setEnabled(enabled);
|
|
||||||
return true;
|
|
||||||
} catch (final IllegalStateException e) {
|
|
||||||
Log.d(Config.LOGTAG, "unable to toggle microphone", e);
|
|
||||||
// ignoring race condition in case MediaStreamTrack has been disposed
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Local audio track does not exist (yet)");
|
throw new IllegalStateException("Local audio track does not exist (yet)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean setEnabled(final AudioTrack audioTrack, final boolean enabled) {
|
||||||
|
try {
|
||||||
|
audioTrack.setEnabled(enabled);
|
||||||
|
return true;
|
||||||
|
} catch (final IllegalStateException e) {
|
||||||
|
Log.d(Config.LOGTAG, "unable to toggle audio track", e);
|
||||||
|
// ignoring race condition in case MediaStreamTrack has been disposed
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMicrophoneEnabled(final boolean enabled) {
|
||||||
|
final Optional<AudioTrack> audioTrack =
|
||||||
|
TrackWrapper.get(peerConnection, this.localAudioTrack);
|
||||||
|
if (audioTrack.isPresent()) {
|
||||||
|
setEnabled(audioTrack.get(), enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean isVideoEnabled() {
|
boolean isVideoEnabled() {
|
||||||
final Optional<VideoTrack> videoTrack =
|
final Optional<VideoTrack> videoTrack =
|
||||||
TrackWrapper.get(peerConnection, this.localVideoTrack);
|
TrackWrapper.get(peerConnection, this.localVideoTrack);
|
||||||
|
|
|
@ -1064,5 +1064,5 @@
|
||||||
<string name="pref_backup_recurring">Recurring backup</string>
|
<string name="pref_backup_recurring">Recurring backup</string>
|
||||||
<string name="pref_fullscreen_notification">Full screen notifications</string>
|
<string name="pref_fullscreen_notification">Full screen notifications</string>
|
||||||
<string name="pref_fullscreen_notification_summary">Allow this app to show incoming call notifications that take up the full screen when the device is locked.</string>
|
<string name="pref_fullscreen_notification_summary">Allow this app to show incoming call notifications that take up the full screen when the device is locked.</string>
|
||||||
|
<string name="unsupported_operation">Unsupported operation</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue