get rid of ToneManager and play sounds in CallIntegration instead
CallIntegration takes care of audio routing so it makes sense to play and sounds here too
This commit is contained in:
parent
66cd50e163
commit
d31b24d05a
|
@ -120,7 +120,7 @@ public final class Config {
|
||||||
public static final boolean DISABLE_PROXY_LOOKUP =
|
public static final boolean DISABLE_PROXY_LOOKUP =
|
||||||
false; // disables STUN/TURN and Proxy65 look up (useful to debug IBB fallback)
|
false; // disables STUN/TURN and Proxy65 look up (useful to debug IBB fallback)
|
||||||
public static final boolean USE_DIRECT_JINGLE_CANDIDATES = true;
|
public static final boolean USE_DIRECT_JINGLE_CANDIDATES = true;
|
||||||
public static final boolean USE_JINGLE_DIRECT_INIT = true;
|
public static final boolean USE_JINGLE_MESSAGE_INIT = true;
|
||||||
public static final boolean DISABLE_HTTP_UPLOAD = false;
|
public static final boolean DISABLE_HTTP_UPLOAD = false;
|
||||||
public static final boolean EXTENDED_SM_LOGGING = false; // log stanza counts
|
public static final boolean EXTENDED_SM_LOGGING = false; // log stanza counts
|
||||||
public static final boolean BACKGROUND_STANZA_LOGGING =
|
public static final boolean BACKGROUND_STANZA_LOGGING =
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package eu.siacs.conversations.services;
|
package eu.siacs.conversations.services;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
import android.media.ToneGenerator;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.telecom.CallAudioState;
|
import android.telecom.CallAudioState;
|
||||||
|
@ -20,11 +22,13 @@ import com.google.common.collect.Lists;
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.ui.util.MainThreadExecutor;
|
import eu.siacs.conversations.ui.util.MainThreadExecutor;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
|
import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager;
|
||||||
import eu.siacs.conversations.xmpp.jingle.Media;
|
import eu.siacs.conversations.xmpp.jingle.Media;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class CallIntegration extends Connection {
|
public class CallIntegration extends Connection {
|
||||||
|
@ -32,6 +36,7 @@ public class CallIntegration extends Connection {
|
||||||
private final AppRTCAudioManager appRTCAudioManager;
|
private final AppRTCAudioManager appRTCAudioManager;
|
||||||
private AudioDevice initialAudioDevice = null;
|
private AudioDevice initialAudioDevice = null;
|
||||||
private final AtomicBoolean initialAudioDeviceConfigured = new AtomicBoolean(false);
|
private final AtomicBoolean initialAudioDeviceConfigured = new AtomicBoolean(false);
|
||||||
|
private final AtomicBoolean delayedDestructionInitiated = new AtomicBoolean(false);
|
||||||
|
|
||||||
private List<CallEndpoint> availableEndpoints = Collections.emptyList();
|
private List<CallEndpoint> availableEndpoints = Collections.emptyList();
|
||||||
|
|
||||||
|
@ -302,7 +307,9 @@ public class CallIntegration extends Connection {
|
||||||
|
|
||||||
public void success() {
|
public void success() {
|
||||||
Log.d(Config.LOGTAG, "CallIntegration.success()");
|
Log.d(Config.LOGTAG, "CallIntegration.success()");
|
||||||
this.destroyWith(new DisconnectCause(DisconnectCause.LOCAL, null));
|
final var toneGenerator = new ToneGenerator(AudioManager.STREAM_MUSIC, 100);
|
||||||
|
toneGenerator.startTone(ToneGenerator.TONE_CDMA_CALLDROP_LITE, 375);
|
||||||
|
this.destroyWithDelay(new DisconnectCause(DisconnectCause.LOCAL, null), 375);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void accepted() {
|
public void accepted() {
|
||||||
|
@ -316,6 +323,9 @@ public class CallIntegration extends Connection {
|
||||||
|
|
||||||
public void error() {
|
public void error() {
|
||||||
Log.d(Config.LOGTAG, "CallIntegration.error()");
|
Log.d(Config.LOGTAG, "CallIntegration.error()");
|
||||||
|
final var toneGenerator = new ToneGenerator(AudioManager.STREAM_MUSIC, 80);
|
||||||
|
toneGenerator.startTone(ToneGenerator.TONE_CDMA_CALLDROP_LITE, 375);
|
||||||
|
this.destroyWithDelay(new DisconnectCause(DisconnectCause.ERROR, null), 375);
|
||||||
this.destroyWith(new DisconnectCause(DisconnectCause.ERROR, null));
|
this.destroyWith(new DisconnectCause(DisconnectCause.ERROR, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,16 +342,33 @@ public class CallIntegration extends Connection {
|
||||||
|
|
||||||
public void busy() {
|
public void busy() {
|
||||||
Log.d(Config.LOGTAG, "CallIntegration.busy()");
|
Log.d(Config.LOGTAG, "CallIntegration.busy()");
|
||||||
this.destroyWith(new DisconnectCause(DisconnectCause.BUSY, null));
|
final var toneGenerator = new ToneGenerator(AudioManager.STREAM_MUSIC, 80);
|
||||||
|
toneGenerator.startTone(ToneGenerator.TONE_CDMA_NETWORK_BUSY, 2500);
|
||||||
|
this.destroyWithDelay(new DisconnectCause(DisconnectCause.BUSY, null), 2500);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void destroyWithDelay(final DisconnectCause disconnectCause, final int delay) {
|
||||||
|
if (this.delayedDestructionInitiated.compareAndSet(false, true)) {
|
||||||
|
JingleConnectionManager.SCHEDULED_EXECUTOR_SERVICE.schedule(
|
||||||
|
() -> {
|
||||||
|
this.setDisconnected(disconnectCause);
|
||||||
|
this.destroy();
|
||||||
|
},
|
||||||
|
delay,
|
||||||
|
TimeUnit.MILLISECONDS);
|
||||||
|
} else {
|
||||||
|
Log.w(Config.LOGTAG, "CallIntegration destruction has already been scheduled!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void destroyWith(final DisconnectCause disconnectCause) {
|
private void destroyWith(final DisconnectCause disconnectCause) {
|
||||||
if (this.getState() == STATE_DISCONNECTED) {
|
if (this.getState() == STATE_DISCONNECTED || this.delayedDestructionInitiated.get()) {
|
||||||
Log.d(Config.LOGTAG, "CallIntegration has already been destroyed");
|
Log.d(Config.LOGTAG, "CallIntegration has already been destroyed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setDisconnected(disconnectCause);
|
this.setDisconnected(disconnectCause);
|
||||||
this.destroy();
|
this.destroy();
|
||||||
|
Log.d(Config.LOGTAG, "destroyed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uri address(final Jid contact) {
|
public static Uri address(final Jid contact) {
|
||||||
|
@ -349,7 +376,7 @@ public class CallIntegration extends Connection {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void verifyDisconnected() {
|
public void verifyDisconnected() {
|
||||||
if (this.getState() == STATE_DISCONNECTED) {
|
if (this.getState() == STATE_DISCONNECTED || this.delayedDestructionInitiated.get()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw new AssertionError("CallIntegration has not been disconnected");
|
throw new AssertionError("CallIntegration has not been disconnected");
|
||||||
|
|
|
@ -1633,7 +1633,7 @@ public class ConversationFragment extends XmppFragment
|
||||||
activity.xmppConnectionService.updateAccount(account);
|
activity.xmppConnectionService.updateAccount(account);
|
||||||
}
|
}
|
||||||
final Contact contact = conversation.getContact();
|
final Contact contact = conversation.getContact();
|
||||||
if (Config.USE_JINGLE_DIRECT_INIT && RtpCapability.jmiSupport(contact)) {
|
if (Config.USE_JINGLE_MESSAGE_INIT && RtpCapability.jmiSupport(contact)) {
|
||||||
triggerRtpSession(contact.getAccount(), contact.getJid().asBareJid(), action);
|
triggerRtpSession(contact.getAccount(), contact.getJid().asBareJid(), action);
|
||||||
} else {
|
} else {
|
||||||
final RtpCapability.Capability capability;
|
final RtpCapability.Capability capability;
|
||||||
|
|
|
@ -54,9 +54,8 @@ import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class JingleConnectionManager extends AbstractConnectionManager {
|
public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE =
|
public static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE =
|
||||||
Executors.newSingleThreadScheduledExecutor();
|
Executors.newSingleThreadScheduledExecutor();
|
||||||
final ToneManager toneManager;
|
|
||||||
private final HashMap<RtpSessionProposal, DeviceDiscoveryState> rtpSessionProposals =
|
private final HashMap<RtpSessionProposal, DeviceDiscoveryState> rtpSessionProposals =
|
||||||
new HashMap<>();
|
new HashMap<>();
|
||||||
private final ConcurrentHashMap<AbstractJingleConnection.Id, AbstractJingleConnection>
|
private final ConcurrentHashMap<AbstractJingleConnection.Id, AbstractJingleConnection>
|
||||||
|
@ -67,7 +66,6 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
|
|
||||||
public JingleConnectionManager(XmppConnectionService service) {
|
public JingleConnectionManager(XmppConnectionService service) {
|
||||||
super(service);
|
super(service);
|
||||||
this.toneManager = new ToneManager(service);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static String nextRandomId() {
|
static String nextRandomId() {
|
||||||
|
@ -490,7 +488,6 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
proposal.callIntegration.busy();
|
proposal.callIntegration.busy();
|
||||||
writeLogMissedOutgoing(
|
writeLogMissedOutgoing(
|
||||||
account, proposal.with, proposal.sessionId, serverMsgId, timestamp);
|
account, proposal.with, proposal.sessionId, serverMsgId, timestamp);
|
||||||
toneManager.transition(RtpEndUserState.DECLINED_OR_BUSY, proposal.media);
|
|
||||||
mXmppConnectionService.notifyJingleRtpConnectionUpdate(
|
mXmppConnectionService.notifyJingleRtpConnectionUpdate(
|
||||||
account,
|
account,
|
||||||
proposal.with,
|
proposal.with,
|
||||||
|
@ -667,7 +664,6 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
|
|
||||||
private void retractSessionProposal(final RtpSessionProposal rtpSessionProposal) {
|
private void retractSessionProposal(final RtpSessionProposal rtpSessionProposal) {
|
||||||
final Account account = rtpSessionProposal.account;
|
final Account account = rtpSessionProposal.account;
|
||||||
toneManager.transition(RtpEndUserState.ENDED, rtpSessionProposal.media);
|
|
||||||
Log.d(
|
Log.d(
|
||||||
Config.LOGTAG,
|
Config.LOGTAG,
|
||||||
account.getJid().asBareJid()
|
account.getJid().asBareJid()
|
||||||
|
@ -713,7 +709,6 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
if (preexistingState != null
|
if (preexistingState != null
|
||||||
&& preexistingState != DeviceDiscoveryState.FAILED) {
|
&& preexistingState != DeviceDiscoveryState.FAILED) {
|
||||||
final RtpEndUserState endUserState = preexistingState.toEndUserState();
|
final RtpEndUserState endUserState = preexistingState.toEndUserState();
|
||||||
toneManager.transition(endUserState, media);
|
|
||||||
mXmppConnectionService.notifyJingleRtpConnectionUpdate(
|
mXmppConnectionService.notifyJingleRtpConnectionUpdate(
|
||||||
account, with, proposal.sessionId, endUserState);
|
account, with, proposal.sessionId, endUserState);
|
||||||
return proposal;
|
return proposal;
|
||||||
|
|
|
@ -2727,7 +2727,6 @@ public class JingleRtpConnection extends AbstractJingleConnection
|
||||||
|
|
||||||
private void updateEndUserState() {
|
private void updateEndUserState() {
|
||||||
final RtpEndUserState endUserState = getEndUserState();
|
final RtpEndUserState endUserState = getEndUserState();
|
||||||
jingleConnectionManager.toneManager.transition(isInitiator(), endUserState, getMedia());
|
|
||||||
this.updateCallIntegrationState();
|
this.updateCallIntegrationState();
|
||||||
xmppConnectionService.notifyJingleRtpConnectionUpdate(
|
xmppConnectionService.notifyJingleRtpConnectionUpdate(
|
||||||
id.account, id.with, id.sessionId, endUserState);
|
id.account, id.with, id.sessionId, endUserState);
|
||||||
|
|
|
@ -1,238 +0,0 @@
|
||||||
package eu.siacs.conversations.xmpp.jingle;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.media.ToneGenerator;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
|
|
||||||
class ToneManager {
|
|
||||||
|
|
||||||
private ToneGenerator toneGenerator;
|
|
||||||
private final Context context;
|
|
||||||
|
|
||||||
private ToneState state = null;
|
|
||||||
private RtpEndUserState endUserState = null;
|
|
||||||
private ScheduledFuture<?> currentTone;
|
|
||||||
private ScheduledFuture<?> currentResetFuture;
|
|
||||||
private boolean appRtcAudioManagerHasControl = false;
|
|
||||||
|
|
||||||
ToneManager(final Context context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ToneState of(final boolean isInitiator, final RtpEndUserState state, final Set<Media> media) {
|
|
||||||
if (isInitiator) {
|
|
||||||
if (asList(RtpEndUserState.FINDING_DEVICE, RtpEndUserState.RINGING, RtpEndUserState.CONNECTING).contains(state)) {
|
|
||||||
return ToneState.RINGING;
|
|
||||||
}
|
|
||||||
if (state == RtpEndUserState.DECLINED_OR_BUSY) {
|
|
||||||
return ToneState.BUSY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (state == RtpEndUserState.ENDING_CALL) {
|
|
||||||
if (media.contains(Media.VIDEO)) {
|
|
||||||
return ToneState.NULL;
|
|
||||||
} else {
|
|
||||||
return ToneState.ENDING_CALL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Arrays.asList(
|
|
||||||
RtpEndUserState.CONNECTED,
|
|
||||||
RtpEndUserState.RECONNECTING,
|
|
||||||
RtpEndUserState.INCOMING_CONTENT_ADD)
|
|
||||||
.contains(state)) {
|
|
||||||
if (media.contains(Media.VIDEO)) {
|
|
||||||
return ToneState.NULL;
|
|
||||||
} else {
|
|
||||||
return ToneState.CONNECTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ToneState.NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void transition(final RtpEndUserState state, final Set<Media> media) {
|
|
||||||
transition(state, of(true, state, media), media);
|
|
||||||
}
|
|
||||||
|
|
||||||
void transition(final boolean isInitiator, final RtpEndUserState state, final Set<Media> media) {
|
|
||||||
transition(state, of(isInitiator, state, media), media);
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void transition(final RtpEndUserState endUserState, final ToneState state, final Set<Media> media) {
|
|
||||||
final RtpEndUserState normalizeEndUserState = normalize(endUserState);
|
|
||||||
if (this.endUserState == normalizeEndUserState) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.endUserState = normalizeEndUserState;
|
|
||||||
if (this.state == state) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (state == ToneState.NULL && this.state == ToneState.ENDING_CALL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cancelCurrentTone();
|
|
||||||
Log.d(Config.LOGTAG, getClass().getName() + ".transition(" + state + ")");
|
|
||||||
if (state != ToneState.NULL) {
|
|
||||||
configureAudioManagerForCall(media);
|
|
||||||
}
|
|
||||||
switch (state) {
|
|
||||||
case RINGING:
|
|
||||||
// ringing can be removed as this is now handled by 'CallIntegration'
|
|
||||||
//scheduleWaitingTone();
|
|
||||||
break;
|
|
||||||
case CONNECTED:
|
|
||||||
scheduleConnected();
|
|
||||||
break;
|
|
||||||
case BUSY:
|
|
||||||
scheduleBusy();
|
|
||||||
break;
|
|
||||||
case ENDING_CALL:
|
|
||||||
scheduleEnding();
|
|
||||||
break;
|
|
||||||
case NULL:
|
|
||||||
if (noResetScheduled()) {
|
|
||||||
resetAudioManager();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException("Unable to handle transition to "+state);
|
|
||||||
}
|
|
||||||
this.state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static RtpEndUserState normalize(final RtpEndUserState endUserState) {
|
|
||||||
if (Arrays.asList(
|
|
||||||
RtpEndUserState.CONNECTED,
|
|
||||||
RtpEndUserState.RECONNECTING,
|
|
||||||
RtpEndUserState.INCOMING_CONTENT_ADD)
|
|
||||||
.contains(endUserState)) {
|
|
||||||
return RtpEndUserState.CONNECTED;
|
|
||||||
} else {
|
|
||||||
return endUserState;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAppRtcAudioManagerHasControl(final boolean appRtcAudioManagerHasControl) {
|
|
||||||
this.appRtcAudioManagerHasControl = appRtcAudioManagerHasControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void scheduleConnected() {
|
|
||||||
this.currentTone = JingleConnectionManager.SCHEDULED_EXECUTOR_SERVICE.schedule(() -> {
|
|
||||||
startTone(ToneGenerator.TONE_PROP_PROMPT, 200);
|
|
||||||
}, 0, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void scheduleEnding() {
|
|
||||||
this.currentTone = JingleConnectionManager.SCHEDULED_EXECUTOR_SERVICE.schedule(() -> {
|
|
||||||
startTone(ToneGenerator.TONE_CDMA_CALLDROP_LITE, 375);
|
|
||||||
}, 0, TimeUnit.SECONDS);
|
|
||||||
this.currentResetFuture = JingleConnectionManager.SCHEDULED_EXECUTOR_SERVICE.schedule(this::resetAudioManager, 375, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void scheduleBusy() {
|
|
||||||
this.currentTone = JingleConnectionManager.SCHEDULED_EXECUTOR_SERVICE.schedule(() -> {
|
|
||||||
startTone(ToneGenerator.TONE_CDMA_NETWORK_BUSY, 2500);
|
|
||||||
}, 0, TimeUnit.SECONDS);
|
|
||||||
this.currentResetFuture = JingleConnectionManager.SCHEDULED_EXECUTOR_SERVICE.schedule(this::resetAudioManager, 2500, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void scheduleWaitingTone() {
|
|
||||||
this.currentTone = JingleConnectionManager.SCHEDULED_EXECUTOR_SERVICE.scheduleAtFixedRate(() -> {
|
|
||||||
startTone(ToneGenerator.TONE_CDMA_DIAL_TONE_LITE, 750);
|
|
||||||
}, 0, 3, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean noResetScheduled() {
|
|
||||||
return this.currentResetFuture == null || this.currentResetFuture.isDone();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cancelCurrentTone() {
|
|
||||||
if (currentTone != null) {
|
|
||||||
currentTone.cancel(true);
|
|
||||||
}
|
|
||||||
stopTone(toneGenerator);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void stopTone(final ToneGenerator toneGenerator) {
|
|
||||||
if (toneGenerator == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
toneGenerator.stopTone();
|
|
||||||
} catch (final RuntimeException e) {
|
|
||||||
Log.w(Config.LOGTAG,"tone has already stopped");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startTone(final int toneType, final int durationMs) {
|
|
||||||
if (this.toneGenerator != null) {
|
|
||||||
this.toneGenerator.release();;
|
|
||||||
|
|
||||||
}
|
|
||||||
final AudioManager audioManager = ContextCompat.getSystemService(context, AudioManager.class);
|
|
||||||
final boolean ringerModeNormal = audioManager == null || audioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL;
|
|
||||||
this.toneGenerator = getToneGenerator(ringerModeNormal);
|
|
||||||
if (toneGenerator != null) {
|
|
||||||
this.toneGenerator.startTone(toneType, durationMs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ToneGenerator getToneGenerator(final boolean ringerModeNormal) {
|
|
||||||
try {
|
|
||||||
// when silent and on Android 12+ use STREAM_MUSIC
|
|
||||||
if (ringerModeNormal || Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
|
||||||
return new ToneGenerator(AudioManager.STREAM_VOICE_CALL,60);
|
|
||||||
} else {
|
|
||||||
return new ToneGenerator(AudioManager.STREAM_MUSIC,100);
|
|
||||||
}
|
|
||||||
} catch (final Exception e) {
|
|
||||||
Log.d(Config.LOGTAG,"could not create tone generator",e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void configureAudioManagerForCall(final Set<Media> media) {
|
|
||||||
if (appRtcAudioManagerHasControl) {
|
|
||||||
Log.d(Config.LOGTAG, ToneManager.class.getName() + ": do not configure audio manager because RTC has control");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
|
||||||
if (audioManager == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final boolean isSpeakerPhone = media.contains(Media.VIDEO);
|
|
||||||
Log.d(Config.LOGTAG, ToneManager.class.getName() + ": putting AudioManager into communication mode. speaker=" + isSpeakerPhone);
|
|
||||||
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
|
|
||||||
audioManager.setSpeakerphoneOn(isSpeakerPhone);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetAudioManager() {
|
|
||||||
if (appRtcAudioManagerHasControl) {
|
|
||||||
Log.d(Config.LOGTAG, ToneManager.class.getName() + ": do not reset audio manager because RTC has control");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
|
||||||
if (audioManager == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Log.d(Config.LOGTAG, ToneManager.class.getName() + ": putting AudioManager back into normal mode");
|
|
||||||
audioManager.setMode(AudioManager.MODE_NORMAL);
|
|
||||||
audioManager.setSpeakerphoneOn(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum ToneState {
|
|
||||||
NULL, RINGING, CONNECTED, BUSY, ENDING_CALL
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,8 +2,6 @@ package eu.siacs.conversations.xmpp.jingle;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.google.common.base.Optional;
|
import com.google.common.base.Optional;
|
||||||
|
@ -15,8 +13,6 @@ import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import com.google.common.util.concurrent.SettableFuture;
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.services.AppRTCAudioManager;
|
|
||||||
import eu.siacs.conversations.services.CallIntegration;
|
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
|
|
||||||
import org.webrtc.AudioSource;
|
import org.webrtc.AudioSource;
|
||||||
|
@ -52,7 +48,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@SuppressWarnings("UnstableApiUsage")
|
|
||||||
public class WebRTCWrapper {
|
public class WebRTCWrapper {
|
||||||
|
|
||||||
private static final String EXTENDED_LOGGING_TAG = WebRTCWrapper.class.getSimpleName();
|
private static final String EXTENDED_LOGGING_TAG = WebRTCWrapper.class.getSimpleName();
|
||||||
|
@ -205,7 +200,6 @@ public class WebRTCWrapper {
|
||||||
};
|
};
|
||||||
@Nullable private PeerConnectionFactory peerConnectionFactory = null;
|
@Nullable private PeerConnectionFactory peerConnectionFactory = null;
|
||||||
@Nullable private PeerConnection peerConnection = null;
|
@Nullable private PeerConnection peerConnection = null;
|
||||||
private ToneManager toneManager = null;
|
|
||||||
private Context context = null;
|
private Context context = null;
|
||||||
private EglBase eglBase = null;
|
private EglBase eglBase = null;
|
||||||
private VideoSourceWrapper videoSourceWrapper;
|
private VideoSourceWrapper videoSourceWrapper;
|
||||||
|
@ -222,8 +216,7 @@ public class WebRTCWrapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setup(final XmppConnectionService service)
|
public void setup(final XmppConnectionService service) throws InitializationException {
|
||||||
throws InitializationException {
|
|
||||||
try {
|
try {
|
||||||
PeerConnectionFactory.initialize(
|
PeerConnectionFactory.initialize(
|
||||||
PeerConnectionFactory.InitializationOptions.builder(service)
|
PeerConnectionFactory.InitializationOptions.builder(service)
|
||||||
|
@ -238,7 +231,6 @@ public class WebRTCWrapper {
|
||||||
throw new InitializationException("Unable to create EGL base", e);
|
throw new InitializationException("Unable to create EGL base", e);
|
||||||
}
|
}
|
||||||
this.context = service;
|
this.context = service;
|
||||||
this.toneManager = service.getJingleConnectionManager().toneManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void initializePeerConnection(
|
synchronized void initializePeerConnection(
|
||||||
|
|
Loading…
Reference in a new issue