show status in RtpSessionActivity
This commit is contained in:
parent
f8c0328416
commit
a9a35fb74b
|
@ -143,6 +143,7 @@ import eu.siacs.conversations.xmpp.chatstate.ChatState;
|
|||
import eu.siacs.conversations.xmpp.forms.Data;
|
||||
import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager;
|
||||
import eu.siacs.conversations.xmpp.jingle.OnJinglePacketReceived;
|
||||
import eu.siacs.conversations.xmpp.jingle.RtpEndUserState;
|
||||
import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket;
|
||||
import eu.siacs.conversations.xmpp.mam.MamReference;
|
||||
import eu.siacs.conversations.xmpp.pep.Avatar;
|
||||
|
@ -267,6 +268,7 @@ public class XmppConnectionService extends Service {
|
|||
private final Set<OnUpdateBlocklist> mOnUpdateBlocklist = Collections.newSetFromMap(new WeakHashMap<OnUpdateBlocklist, Boolean>());
|
||||
private final Set<OnMucRosterUpdate> mOnMucRosterUpdate = Collections.newSetFromMap(new WeakHashMap<OnMucRosterUpdate, Boolean>());
|
||||
private final Set<OnKeyStatusUpdated> mOnKeyStatusUpdated = Collections.newSetFromMap(new WeakHashMap<OnKeyStatusUpdated, Boolean>());
|
||||
private final Set<OnJingleRtpConnectionUpdate> onJingleRtpConnectionUpdate = Collections.newSetFromMap(new WeakHashMap<OnJingleRtpConnectionUpdate, Boolean>());
|
||||
|
||||
private final Object LISTENER_LOCK = new Object();
|
||||
|
||||
|
@ -2467,6 +2469,30 @@ public class XmppConnectionService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
public void setOnRtpConnectionUpdateListener(final OnJingleRtpConnectionUpdate listener) {
|
||||
final boolean remainingListeners;
|
||||
synchronized (LISTENER_LOCK) {
|
||||
remainingListeners = checkListeners();
|
||||
if (!this.onJingleRtpConnectionUpdate.add(listener)) {
|
||||
Log.w(Config.LOGTAG, listener.getClass().getName() + " is already registered as OnJingleRtpConnectionUpdate");
|
||||
}
|
||||
}
|
||||
if (remainingListeners) {
|
||||
switchToForeground();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeRtpConnectionUpdateListener(final OnJingleRtpConnectionUpdate listener) {
|
||||
final boolean remainingListeners;
|
||||
synchronized (LISTENER_LOCK) {
|
||||
this.onJingleRtpConnectionUpdate.remove(listener);
|
||||
remainingListeners = checkListeners();
|
||||
}
|
||||
if (remainingListeners) {
|
||||
switchToBackground();
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnMucRosterUpdateListener(OnMucRosterUpdate listener) {
|
||||
final boolean remainingListeners;
|
||||
synchronized (LISTENER_LOCK) {
|
||||
|
@ -2499,6 +2525,7 @@ public class XmppConnectionService extends Service {
|
|||
&& this.mOnMucRosterUpdate.size() == 0
|
||||
&& this.mOnUpdateBlocklist.size() == 0
|
||||
&& this.mOnShowErrorToasts.size() == 0
|
||||
&& this.onJingleRtpConnectionUpdate.size() == 0
|
||||
&& this.mOnKeyStatusUpdated.size() == 0);
|
||||
}
|
||||
|
||||
|
@ -3943,6 +3970,12 @@ public class XmppConnectionService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
public void notifyJingleRtpConnectionUpdate(final Account account, final Jid with, final RtpEndUserState state) {
|
||||
for(OnJingleRtpConnectionUpdate listener : threadSafeList(this.onJingleRtpConnectionUpdate)) {
|
||||
listener.onJingleRtpConnectionUpdate(account, with, state);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateAccountUi() {
|
||||
for (OnAccountUpdate listener : threadSafeList(this.mOnAccountUpdates)) {
|
||||
listener.onAccountUpdate();
|
||||
|
@ -3986,9 +4019,9 @@ public class XmppConnectionService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
public Account findAccountByJid(final Jid accountJid) {
|
||||
for (Account account : this.accounts) {
|
||||
if (account.getJid().asBareJid().equals(accountJid.asBareJid())) {
|
||||
public Account findAccountByJid(final Jid jid) {
|
||||
for (final Account account : this.accounts) {
|
||||
if (account.getJid().asBareJid().equals(jid.asBareJid())) {
|
||||
return account;
|
||||
}
|
||||
}
|
||||
|
@ -4620,6 +4653,10 @@ public class XmppConnectionService extends Service {
|
|||
void onConversationUpdate();
|
||||
}
|
||||
|
||||
public interface OnJingleRtpConnectionUpdate {
|
||||
void onJingleRtpConnectionUpdate(final Account account, final Jid with, final RtpEndUserState state);
|
||||
}
|
||||
|
||||
public interface OnAccountUpdate {
|
||||
void onAccountUpdate();
|
||||
}
|
||||
|
|
|
@ -1,16 +1,31 @@
|
|||
package eu.siacs.conversations.ui;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.databinding.DataBindingUtil;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.databinding.ActivityRtpSessionBinding;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.entities.Contact;
|
||||
import eu.siacs.conversations.services.XmppConnectionService;
|
||||
import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection;
|
||||
import eu.siacs.conversations.xmpp.jingle.JingleRtpConnection;
|
||||
import eu.siacs.conversations.xmpp.jingle.RtpEndUserState;
|
||||
import rocks.xmpp.addr.Jid;
|
||||
|
||||
public class RtpSessionActivity extends XmppActivity {
|
||||
public class RtpSessionActivity extends XmppActivity implements XmppConnectionService.OnJingleRtpConnectionUpdate {
|
||||
|
||||
public static final String EXTRA_WITH = "with";
|
||||
public static final String EXTRA_SESSION_ID = "session_id";
|
||||
|
||||
private WeakReference<JingleRtpConnection> rtpConnectionReference;
|
||||
|
||||
private ActivityRtpSessionBinding binding;
|
||||
|
||||
|
@ -27,11 +42,12 @@ public class RtpSessionActivity extends XmppActivity {
|
|||
}
|
||||
|
||||
private void rejectCall(View view) {
|
||||
|
||||
requireRtpConnection().rejectCall();
|
||||
finish();
|
||||
}
|
||||
|
||||
private void acceptCall(View view) {
|
||||
|
||||
requireRtpConnection().acceptCall();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -41,6 +57,64 @@ public class RtpSessionActivity extends XmppActivity {
|
|||
|
||||
@Override
|
||||
void onBackendConnected() {
|
||||
final Intent intent = getIntent();
|
||||
final Account account = extractAccount(intent);
|
||||
final String with = intent.getStringExtra(EXTRA_WITH);
|
||||
final String sessionId = intent.getStringExtra(EXTRA_SESSION_ID);
|
||||
if (with != null && sessionId != null) {
|
||||
final WeakReference<JingleRtpConnection> reference = xmppConnectionService.getJingleConnectionManager()
|
||||
.findJingleRtpConnection(account, Jid.ofEscaped(with), sessionId);
|
||||
if (reference == null || reference.get() == null) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
this.rtpConnectionReference = reference;
|
||||
binding.with.setText(getWith().getDisplayName());
|
||||
showState(requireRtpConnection().getEndUserState());
|
||||
}
|
||||
}
|
||||
|
||||
private void showState(final RtpEndUserState state) {
|
||||
switch (state) {
|
||||
case INCOMING_CALL:
|
||||
binding.status.setText(R.string.rtp_state_incoming_call);
|
||||
break;
|
||||
case CONNECTING:
|
||||
binding.status.setText(R.string.rtp_state_connecting);
|
||||
break;
|
||||
case CONNECTED:
|
||||
binding.status.setText(R.string.rtp_state_connected);
|
||||
break;
|
||||
case ACCEPTING_CALL:
|
||||
binding.status.setText(R.string.rtp_state_accepting_call);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private Contact getWith() {
|
||||
final AbstractJingleConnection.Id id = requireRtpConnection().getId();
|
||||
final Account account = id.account;
|
||||
return account.getRoster().getContact(id.with);
|
||||
}
|
||||
|
||||
private JingleRtpConnection requireRtpConnection() {
|
||||
final JingleRtpConnection connection = this.rtpConnectionReference != null ? this.rtpConnectionReference.get() : null;
|
||||
if (connection == null) {
|
||||
throw new IllegalStateException("No RTP connection found");
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJingleRtpConnectionUpdate(Account account, Jid with, RtpEndUserState state) {
|
||||
final AbstractJingleConnection.Id id = requireRtpConnection().getId();
|
||||
if (account == id.account && id.with.equals(with)) {
|
||||
runOnUiThread(()->{
|
||||
showState(state);
|
||||
});
|
||||
} else {
|
||||
Log.d(Config.LOGTAG,"received update for other rtp session");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -305,6 +305,9 @@ public abstract class XmppActivity extends ActionBarActivity {
|
|||
if (this instanceof OnKeyStatusUpdated) {
|
||||
this.xmppConnectionService.setOnKeyStatusUpdatedListener((OnKeyStatusUpdated) this);
|
||||
}
|
||||
if (this instanceof XmppConnectionService.OnJingleRtpConnectionUpdate) {
|
||||
this.xmppConnectionService.setOnRtpConnectionUpdateListener((XmppConnectionService.OnJingleRtpConnectionUpdate) this);
|
||||
}
|
||||
}
|
||||
|
||||
protected void unregisterListeners() {
|
||||
|
@ -332,6 +335,9 @@ public abstract class XmppActivity extends ActionBarActivity {
|
|||
if (this instanceof OnKeyStatusUpdated) {
|
||||
this.xmppConnectionService.removeOnNewKeysAvailableListener((OnKeyStatusUpdated) this);
|
||||
}
|
||||
if (this instanceof XmppConnectionService.OnJingleRtpConnectionUpdate) {
|
||||
this.xmppConnectionService.removeRtpConnectionUpdateListener((XmppConnectionService.OnJingleRtpConnectionUpdate) this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -388,13 +394,18 @@ public abstract class XmppActivity extends ActionBarActivity {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressLint("UnsupportedChromeOsCameraSystemFeature")
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
metrics = getResources().getDisplayMetrics();
|
||||
ExceptionHelper.init(getApplicationContext());
|
||||
new EmojiService(this).init();
|
||||
this.isCameraFeatureAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
this.isCameraFeatureAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
|
||||
} else {
|
||||
this.isCameraFeatureAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
|
||||
}
|
||||
this.mTheme = findTheme();
|
||||
setTheme(this.mTheme);
|
||||
|
||||
|
@ -851,7 +862,7 @@ public abstract class XmppActivity extends ActionBarActivity {
|
|||
}
|
||||
|
||||
protected Account extractAccount(Intent intent) {
|
||||
String jid = intent != null ? intent.getStringExtra(EXTRA_ACCOUNT) : null;
|
||||
final String jid = intent != null ? intent.getStringExtra(EXTRA_ACCOUNT) : null;
|
||||
try {
|
||||
return jid != null ? xmppConnectionService.findAccountByJid(Jid.of(jid)) : null;
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.util.Log;
|
|||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
@ -244,6 +245,15 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
|||
}
|
||||
}
|
||||
|
||||
public WeakReference<JingleRtpConnection> findJingleRtpConnection(Account account, Jid with, String sessionId) {
|
||||
final AbstractJingleConnection.Id id = AbstractJingleConnection.Id.of(account, Jid.ofEscaped(with), sessionId);
|
||||
final AbstractJingleConnection connection = connections.get(id);
|
||||
if (connection instanceof JingleRtpConnection) {
|
||||
return new WeakReference<>((JingleRtpConnection) connection);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updateProposedSessionDiscovered(Account account, Jid from, String sessionId, final DeviceDiscoveryState target) {
|
||||
final RtpSessionProposal sessionProposal = new RtpSessionProposal(account,from.asBareJid(),sessionId);
|
||||
synchronized (this.rtpSessionProposals) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.google.common.collect.ImmutableList;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import org.webrtc.IceCandidate;
|
||||
import org.webrtc.PeerConnection;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
|
@ -230,6 +231,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
|||
final Intent intent = new Intent(xmppConnectionService, RtpSessionActivity.class);
|
||||
intent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, id.account.getJid().asBareJid().toEscapedString());
|
||||
intent.putExtra(RtpSessionActivity.EXTRA_WITH, id.with.toEscapedString());
|
||||
intent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, id.sessionId);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
xmppConnectionService.startActivity(intent);
|
||||
}
|
||||
|
@ -293,26 +295,59 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
|||
xmppConnectionService.sendIqPacket(id.account, jinglePacket, null);
|
||||
}
|
||||
|
||||
|
||||
public void pickUpCall() {
|
||||
public RtpEndUserState getEndUserState() {
|
||||
switch (this.state) {
|
||||
case PROPOSED:
|
||||
pickupCallFromProposed();
|
||||
if (isInitiator()) {
|
||||
return RtpEndUserState.RINGING;
|
||||
} else {
|
||||
return RtpEndUserState.INCOMING_CALL;
|
||||
}
|
||||
case PROCEED:
|
||||
if (isInitiator()) {
|
||||
return RtpEndUserState.CONNECTING;
|
||||
} else {
|
||||
return RtpEndUserState.ACCEPTING_CALL;
|
||||
}
|
||||
case SESSION_INITIALIZED:
|
||||
return RtpEndUserState.CONNECTING;
|
||||
case SESSION_ACCEPTED:
|
||||
final PeerConnection.PeerConnectionState state = webRTCWrapper.getState();
|
||||
if (state == PeerConnection.PeerConnectionState.CONNECTED) {
|
||||
return RtpEndUserState.CONNECTED;
|
||||
} else if (state == PeerConnection.PeerConnectionState.NEW || state == PeerConnection.PeerConnectionState.CONNECTING) {
|
||||
return RtpEndUserState.CONNECTING;
|
||||
} else {
|
||||
return RtpEndUserState.FAILED;
|
||||
}
|
||||
}
|
||||
return RtpEndUserState.FAILED;
|
||||
}
|
||||
|
||||
|
||||
public void acceptCall() {
|
||||
switch (this.state) {
|
||||
case PROPOSED:
|
||||
acceptCallFromProposed();
|
||||
break;
|
||||
case SESSION_INITIALIZED:
|
||||
pickupCallFromSessionInitialized();
|
||||
acceptCallFromSessionInitialized();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Can not pick up call from " + this.state);
|
||||
}
|
||||
}
|
||||
|
||||
public void rejectCall() {
|
||||
Log.d(Config.LOGTAG, "todo rejecting call");
|
||||
}
|
||||
|
||||
private void setupWebRTC() {
|
||||
this.webRTCWrapper.setup(this.xmppConnectionService);
|
||||
this.webRTCWrapper.initializePeerConnection();
|
||||
}
|
||||
|
||||
private void pickupCallFromProposed() {
|
||||
private void acceptCallFromProposed() {
|
||||
transitionOrThrow(State.PROCEED);
|
||||
final MessagePacket messagePacket = new MessagePacket();
|
||||
messagePacket.setTo(id.with);
|
||||
|
@ -322,7 +357,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
|||
xmppConnectionService.sendMessagePacket(id.account, messagePacket);
|
||||
}
|
||||
|
||||
private void pickupCallFromSessionInitialized() {
|
||||
private void acceptCallFromSessionInitialized() {
|
||||
|
||||
}
|
||||
|
||||
|
@ -335,6 +370,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
|||
if (validTransitions != null && validTransitions.contains(target)) {
|
||||
this.state = target;
|
||||
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": transitioned into " + target);
|
||||
updateEndUserState();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -353,4 +389,13 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
|||
Log.d(Config.LOGTAG, "sending candidate: " + iceCandidate.toString());
|
||||
sendTransportInfo(iceCandidate.sdpMid, candidate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionChange(PeerConnection.PeerConnectionState newState) {
|
||||
updateEndUserState();
|
||||
}
|
||||
|
||||
private void updateEndUserState() {
|
||||
xmppConnectionService.notifyJingleRtpConnectionUpdate(id.account, id.with, getEndUserState());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package eu.siacs.conversations.xmpp.jingle;
|
||||
|
||||
public enum RtpEndUserState {
|
||||
INCOMING_CALL, //received a 'propose' message
|
||||
CONNECTING, //session-initiate or session-accepted but no webrtc peer connection yet
|
||||
CONNECTED, //session-accepted and webrtc peer connection is connected
|
||||
FINDING_DEVICE, //'propose' has been sent out; no 184 ack yet
|
||||
RINGING, //'propose' has been sent out and it has been 184 acked
|
||||
ACCEPTED_ON_OTHER_DEVICE, //received 'accept' from one of our own devices
|
||||
ACCEPTING_CALL, //'proceed' message has been sent; but no session-initiate has been received
|
||||
FAILED //something went wrong. TODO needs more concrete error states
|
||||
}
|
|
@ -50,7 +50,7 @@ public class WebRTCWrapper {
|
|||
|
||||
@Override
|
||||
public void onConnectionChange(PeerConnection.PeerConnectionState newState) {
|
||||
Log.d(Config.LOGTAG, "onConnectionChange(" + newState + ")");
|
||||
eventCallback.onConnectionChange(newState);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -329,5 +329,6 @@ public class WebRTCWrapper {
|
|||
|
||||
public interface EventCallback {
|
||||
void onIceCandidate(IceCandidate iceCandidate);
|
||||
void onConnectionChange(PeerConnection.PeerConnectionState newState);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -885,6 +885,10 @@
|
|||
<string name="category_about">About</string>
|
||||
<string name="please_enable_an_account">Please enable an account</string>
|
||||
<string name="make_call">Make call</string>
|
||||
<string name="rtp_state_incoming_call">Incoming call</string>
|
||||
<string name="rtp_state_connecting">Connecting</string>
|
||||
<string name="rtp_state_connected">Connected</string>
|
||||
<string name="rtp_state_accepting_call">Accepting call</string>
|
||||
<plurals name="view_users">
|
||||
<item quantity="one">View %1$d Participant</item>
|
||||
<item quantity="other">View %1$d Participants</item>
|
||||
|
|
Loading…
Reference in New Issue