show speaker selection during 'ringing'
This commit is contained in:
parent
bff1ac5ebc
commit
bfe2aff7a1
|
@ -63,6 +63,7 @@ import eu.siacs.conversations.xmpp.jingle.ContentAddition;
|
|||
import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager;
|
||||
import eu.siacs.conversations.xmpp.jingle.JingleRtpConnection;
|
||||
import eu.siacs.conversations.xmpp.jingle.Media;
|
||||
import eu.siacs.conversations.xmpp.jingle.OngoingRtpSession;
|
||||
import eu.siacs.conversations.xmpp.jingle.RtpCapability;
|
||||
import eu.siacs.conversations.xmpp.jingle.RtpEndUserState;
|
||||
|
||||
|
@ -117,6 +118,13 @@ public class RtpSessionActivity extends XmppActivity
|
|||
RtpEndUserState.ACCEPTING_CALL,
|
||||
RtpEndUserState.CONNECTING,
|
||||
RtpEndUserState.RECONNECTING);
|
||||
private static final List<RtpEndUserState> STATES_SHOWING_SPEAKER_CONFIGURATION =
|
||||
new ImmutableList.Builder<RtpEndUserState>()
|
||||
.add(RtpEndUserState.FINDING_DEVICE)
|
||||
.add(RtpEndUserState.RINGING)
|
||||
.add(RtpEndUserState.CONNECTING)
|
||||
.addAll(STATES_CONSIDERED_CONNECTED)
|
||||
.build();
|
||||
private static final String PROXIMITY_WAKE_LOCK_TAG = "conversations:in-rtp-session";
|
||||
private static final int REQUEST_ACCEPT_CALL = 0x1111;
|
||||
private static final int REQUEST_ACCEPT_CONTENT = 0x1112;
|
||||
|
@ -139,8 +147,13 @@ public class RtpSessionActivity extends XmppActivity
|
|||
public static Set<Media> actionToMedia(final String action) {
|
||||
if (ACTION_MAKE_VIDEO_CALL.equals(action)) {
|
||||
return ImmutableSet.of(Media.AUDIO, Media.VIDEO);
|
||||
} else {
|
||||
} else if (ACTION_MAKE_VOICE_CALL.equals(action)) {
|
||||
return ImmutableSet.of(Media.AUDIO);
|
||||
} else {
|
||||
Log.w(
|
||||
Config.LOGTAG,
|
||||
"actionToMedia can not get media set from unknown action " + action);
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,14 +287,15 @@ public class RtpSessionActivity extends XmppActivity
|
|||
private void retractSessionProposal() {
|
||||
final Intent intent = getIntent();
|
||||
final String action = intent.getAction();
|
||||
final String lastAction = intent.getStringExtra(EXTRA_LAST_ACTION);
|
||||
final Account account = extractAccount(intent);
|
||||
final Jid with = Jid.ofEscaped(intent.getStringExtra(EXTRA_WITH));
|
||||
final String state = intent.getStringExtra(EXTRA_LAST_REPORTED_STATE);
|
||||
if (!Intent.ACTION_VIEW.equals(action)
|
||||
|| state == null
|
||||
|| !END_CARD.contains(RtpEndUserState.valueOf(state))) {
|
||||
resetIntent(
|
||||
account, with, RtpEndUserState.RETRACTED, actionToMedia(intent.getAction()));
|
||||
final Set<Media> media = actionToMedia(lastAction == null ? action : lastAction);
|
||||
resetIntent(account, with, RtpEndUserState.RETRACTED, media);
|
||||
}
|
||||
xmppConnectionService
|
||||
.getJingleConnectionManager()
|
||||
|
@ -1049,6 +1063,14 @@ public class RtpSessionActivity extends XmppActivity
|
|||
} else {
|
||||
this.binding.inCallActionLeft.setVisibility(View.GONE);
|
||||
}
|
||||
} else if (STATES_SHOWING_SPEAKER_CONFIGURATION.contains(state)
|
||||
&& !isPictureInPicture()
|
||||
&& Media.audioOnly(media)) {
|
||||
final CallIntegration callIntegration = requireCallIntegration();
|
||||
updateInCallButtonConfigurationSpeaker(
|
||||
callIntegration.getSelectedAudioDevice(),
|
||||
callIntegration.getAudioDevices().size());
|
||||
this.binding.inCallActionFarRight.setVisibility(View.GONE);
|
||||
} else {
|
||||
this.binding.inCallActionLeft.setVisibility(View.GONE);
|
||||
this.binding.inCallActionRight.setVisibility(View.GONE);
|
||||
|
@ -1297,17 +1319,13 @@ public class RtpSessionActivity extends XmppActivity
|
|||
}
|
||||
}
|
||||
|
||||
private void switchToEarpiece(View view) {
|
||||
requireRtpConnection()
|
||||
.getCallIntegration()
|
||||
.setAudioDevice(CallIntegration.AudioDevice.EARPIECE);
|
||||
private void switchToEarpiece(final View view) {
|
||||
requireCallIntegration().setAudioDevice(CallIntegration.AudioDevice.EARPIECE);
|
||||
acquireProximityWakeLock();
|
||||
}
|
||||
|
||||
private void switchToSpeaker(View view) {
|
||||
requireRtpConnection()
|
||||
.getCallIntegration()
|
||||
.setAudioDevice(CallIntegration.AudioDevice.SPEAKER_PHONE);
|
||||
private void switchToSpeaker(final View view) {
|
||||
requireCallIntegration().setAudioDevice(CallIntegration.AudioDevice.SPEAKER_PHONE);
|
||||
releaseProximityWakeLock();
|
||||
}
|
||||
|
||||
|
@ -1359,6 +1377,33 @@ public class RtpSessionActivity extends XmppActivity
|
|||
return connection;
|
||||
}
|
||||
|
||||
private CallIntegration requireCallIntegration() {
|
||||
return requireOngoingRtpSession().getCallIntegration();
|
||||
}
|
||||
|
||||
private OngoingRtpSession requireOngoingRtpSession() {
|
||||
final JingleRtpConnection connection =
|
||||
this.rtpConnectionReference != null ? this.rtpConnectionReference.get() : null;
|
||||
if (connection != null) {
|
||||
return connection;
|
||||
}
|
||||
final Intent currentIntent = getIntent();
|
||||
final String withExtra =
|
||||
currentIntent == null ? null : currentIntent.getStringExtra(EXTRA_WITH);
|
||||
final var account = extractAccount(currentIntent);
|
||||
if (withExtra == null) {
|
||||
throw new IllegalStateException("Current intent has no EXTRA_WITH");
|
||||
}
|
||||
final var matching =
|
||||
xmppConnectionService
|
||||
.getJingleConnectionManager()
|
||||
.matchingProposal(account, Jid.of(withExtra));
|
||||
if (matching.isPresent()) {
|
||||
return matching.get();
|
||||
}
|
||||
throw new IllegalStateException("No matching session proposal");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJingleRtpConnectionUpdate(
|
||||
Account account, Jid with, final String sessionId, RtpEndUserState state) {
|
||||
|
@ -1425,16 +1470,23 @@ public class RtpSessionActivity extends XmppActivity
|
|||
+ ", available:"
|
||||
+ availableAudioDevices);
|
||||
try {
|
||||
final RtpEndUserState endUserState = requireRtpConnection().getEndUserState();
|
||||
final Set<Media> media = getMedia();
|
||||
final OngoingRtpSession ongoingRtpSession = requireOngoingRtpSession();
|
||||
final RtpEndUserState endUserState;
|
||||
if (ongoingRtpSession instanceof JingleRtpConnection jingleRtpConnection) {
|
||||
endUserState = jingleRtpConnection.getEndUserState();
|
||||
} else {
|
||||
// for session proposals all end user states are functionally the same
|
||||
endUserState = RtpEndUserState.RINGING;
|
||||
}
|
||||
final Set<Media> media = ongoingRtpSession.getMedia();
|
||||
if (END_CARD.contains(endUserState)) {
|
||||
Log.d(
|
||||
Config.LOGTAG,
|
||||
"onAudioDeviceChanged() nothing to do because end card has been reached");
|
||||
} else {
|
||||
if (Media.audioOnly(media) && endUserState == RtpEndUserState.CONNECTED) {
|
||||
final CallIntegration callIntegration =
|
||||
requireRtpConnection().getCallIntegration();
|
||||
if (Media.audioOnly(media)
|
||||
&& STATES_SHOWING_SPEAKER_CONFIGURATION.contains(endUserState)) {
|
||||
final CallIntegration callIntegration = requireCallIntegration();
|
||||
updateInCallButtonConfigurationSpeaker(
|
||||
callIntegration.getSelectedAudioDevice(),
|
||||
callIntegration.getAudioDevices().size());
|
||||
|
@ -1457,16 +1509,17 @@ public class RtpSessionActivity extends XmppActivity
|
|||
if (withExtra == null) {
|
||||
return;
|
||||
}
|
||||
final Set<Media> media = actionToMedia(currentIntent.getStringExtra(EXTRA_LAST_ACTION));
|
||||
if (Jid.ofEscaped(withExtra).asBareJid().equals(with)) {
|
||||
runOnUiThread(
|
||||
() -> {
|
||||
updateVerifiedShield(false);
|
||||
updateStateDisplay(state);
|
||||
updateButtonConfiguration(state);
|
||||
updateButtonConfiguration(state, media, null);
|
||||
updateIncomingCallScreen(state);
|
||||
invalidateOptionsMenu();
|
||||
});
|
||||
resetIntent(account, with, state, actionToMedia(currentIntent.getAction()));
|
||||
resetIntent(account, with, state, media);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -219,8 +219,7 @@ public abstract class AbstractJingleConnection {
|
|||
if (isTerminated()) {
|
||||
this.jingleConnectionManager.finishConnectionOrThrow(this);
|
||||
} else {
|
||||
throw new AssertionError(
|
||||
String.format("Unable to call finish from %s", this.state));
|
||||
throw new AssertionError(String.format("Unable to call finish from %s", this.state));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,7 +347,7 @@ public abstract class AbstractJingleConnection {
|
|||
return features != null && features.contains(feature);
|
||||
}
|
||||
|
||||
public static class Id implements OngoingRtpSession {
|
||||
public static class Id {
|
||||
public final Account account;
|
||||
public final Jid with;
|
||||
public final String sessionId;
|
||||
|
@ -400,17 +399,14 @@ public abstract class AbstractJingleConnection {
|
|||
return Objects.hashCode(account.getUuid(), with, sessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Jid getWith() {
|
||||
return with;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
|
|
|
@ -601,11 +601,11 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
|||
public Optional<OngoingRtpSession> getOngoingRtpConnection(final Contact contact) {
|
||||
for (final Map.Entry<AbstractJingleConnection.Id, AbstractJingleConnection> entry :
|
||||
this.connections.entrySet()) {
|
||||
if (entry.getValue() instanceof JingleRtpConnection) {
|
||||
if (entry.getValue() instanceof JingleRtpConnection jingleRtpConnection) {
|
||||
final AbstractJingleConnection.Id id = entry.getKey();
|
||||
if (id.account == contact.getAccount()
|
||||
&& id.with.asBareJid().equals(contact.getJid().asBareJid())) {
|
||||
return Optional.of(id);
|
||||
return Optional.of(jingleRtpConnection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -765,9 +765,22 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
|||
mXmppConnectionService.sendMessagePacket(account, messagePacket);
|
||||
}
|
||||
|
||||
public Optional<RtpSessionProposal> matchingProposal(final Account account, final Jid with) {
|
||||
synchronized (this.rtpSessionProposals) {
|
||||
for (final Map.Entry<RtpSessionProposal, DeviceDiscoveryState> entry :
|
||||
this.rtpSessionProposals.entrySet()) {
|
||||
final RtpSessionProposal proposal = entry.getKey();
|
||||
if (proposal.account == account && with.asBareJid().equals(proposal.with)) {
|
||||
return Optional.of(proposal);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
public boolean hasMatchingProposal(final Account account, final Jid with) {
|
||||
synchronized (this.rtpSessionProposals) {
|
||||
for (Map.Entry<RtpSessionProposal, DeviceDiscoveryState> entry :
|
||||
for (final Map.Entry<RtpSessionProposal, DeviceDiscoveryState> entry :
|
||||
this.rtpSessionProposals.entrySet()) {
|
||||
final var state = entry.getValue();
|
||||
final RtpSessionProposal proposal = entry.getKey();
|
||||
|
@ -1102,9 +1115,15 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
|||
return sessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallIntegration getCallIntegration() {
|
||||
return this.callIntegration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Media> getMedia() {
|
||||
return this.media;
|
||||
}
|
||||
}
|
||||
|
||||
public class ProposalStateCallback implements CallIntegration.Callback {
|
||||
|
@ -1126,8 +1145,11 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
|||
|
||||
@Override
|
||||
public void onAudioDeviceChanged(
|
||||
CallIntegration.AudioDevice selectedAudioDevice,
|
||||
Set<CallIntegration.AudioDevice> availableAudioDevices) {}
|
||||
final CallIntegration.AudioDevice selectedAudioDevice,
|
||||
final Set<CallIntegration.AudioDevice> availableAudioDevices) {
|
||||
mXmppConnectionService.notifyJingleRtpConnectionUpdate(
|
||||
selectedAudioDevice, availableAudioDevices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCallIntegrationReject() {}
|
||||
|
|
|
@ -30,6 +30,7 @@ import eu.siacs.conversations.Config;
|
|||
import eu.siacs.conversations.crypto.axolotl.AxolotlService;
|
||||
import eu.siacs.conversations.crypto.axolotl.CryptoFailedException;
|
||||
import eu.siacs.conversations.crypto.axolotl.FingerprintStatus;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.entities.Conversation;
|
||||
import eu.siacs.conversations.entities.Conversational;
|
||||
import eu.siacs.conversations.entities.Message;
|
||||
|
@ -68,7 +69,7 @@ import java.util.concurrent.ScheduledFuture;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class JingleRtpConnection extends AbstractJingleConnection
|
||||
implements WebRTCWrapper.EventCallback, CallIntegration.Callback {
|
||||
implements WebRTCWrapper.EventCallback, CallIntegration.Callback, OngoingRtpSession {
|
||||
|
||||
public static final List<State> STATES_SHOWING_ONGOING_CALL =
|
||||
Arrays.asList(
|
||||
|
@ -2645,6 +2646,7 @@ public class JingleRtpConnection extends AbstractJingleConnection
|
|||
return this.sessionDuration.elapsed(TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallIntegration getCallIntegration() {
|
||||
return this.callIntegration;
|
||||
}
|
||||
|
@ -2870,6 +2872,21 @@ public class JingleRtpConnection extends AbstractJingleConnection
|
|||
return remoteHasFeature(Namespace.SDP_OFFER_ANSWER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account getAccount() {
|
||||
return id.account;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Jid getWith() {
|
||||
return id.with;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSessionId() {
|
||||
return id.sessionId;
|
||||
}
|
||||
|
||||
private interface OnIceServersDiscovered {
|
||||
void onIceServersDiscovered(List<PeerConnection.IceServer> iceServers);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
package eu.siacs.conversations.xmpp.jingle;
|
||||
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.services.CallIntegration;
|
||||
import eu.siacs.conversations.xmpp.Jid;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface OngoingRtpSession {
|
||||
Account getAccount();
|
||||
|
||||
Jid getWith();
|
||||
|
||||
String getSessionId();
|
||||
|
||||
CallIntegration getCallIntegration();
|
||||
|
||||
Set<Media> getMedia();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue