Detailed changes
@@ -52,6 +52,8 @@ import android.widget.PopupMenu;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
+import com.google.common.base.Optional;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -117,6 +119,7 @@ import eu.siacs.conversations.utils.TimeframeUtils;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.XmppConnection;
import eu.siacs.conversations.xmpp.chatstate.ChatState;
+import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection;
import eu.siacs.conversations.xmpp.jingle.JingleFileTransferConnection;
import eu.siacs.conversations.xmpp.jingle.RtpCapability;
import rocks.xmpp.addr.Jid;
@@ -956,6 +959,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
final MenuItem menuMute = menu.findItem(R.id.action_mute);
final MenuItem menuUnmute = menu.findItem(R.id.action_unmute);
final MenuItem menuCall = menu.findItem(R.id.action_call);
+ final MenuItem menuOngoingCall = menu.findItem(R.id.action_ongoing_call);
final MenuItem menuVideoCall = menu.findItem(R.id.action_video_call);
@@ -965,10 +969,18 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
menuInviteContact.setVisible(conversation.getMucOptions().canInvite());
menuMucDetails.setTitle(conversation.getMucOptions().isPrivateAndNonAnonymous() ? R.string.action_muc_details : R.string.channel_details);
menuCall.setVisible(false);
+ menuOngoingCall.setVisible(false);
} else {
- final RtpCapability.Capability rtpCapability = RtpCapability.check(conversation.getContact());
- menuCall.setVisible(rtpCapability != RtpCapability.Capability.NONE);
- menuVideoCall.setVisible(rtpCapability == RtpCapability.Capability.VIDEO);
+ final Optional<AbstractJingleConnection.Id> ongoingRtpSession = activity.xmppConnectionService.getJingleConnectionManager().getOngoingRtpConnection(conversation.getContact());
+ if (ongoingRtpSession.isPresent()) {
+ menuOngoingCall.setVisible(true);
+ menuCall.setVisible(false);
+ } else {
+ menuOngoingCall.setVisible(false);
+ final RtpCapability.Capability rtpCapability = RtpCapability.check(conversation.getContact());
+ menuCall.setVisible(rtpCapability != RtpCapability.Capability.NONE);
+ menuVideoCall.setVisible(rtpCapability == RtpCapability.Capability.VIDEO);
+ }
menuContactDetails.setVisible(!this.conversation.withSelf());
menuMucDetails.setVisible(false);
final XmppConnectionService service = activity.xmppConnectionService;
@@ -1245,12 +1257,28 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
case R.id.action_video_call:
checkPermissionAndTriggerVideoCall();
break;
+ case R.id.action_ongoing_call:
+ returnToOngoingCall();
+ break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
+ private void returnToOngoingCall() {
+ final Optional<AbstractJingleConnection.Id> ongoingRtpSession = activity.xmppConnectionService.getJingleConnectionManager().getOngoingRtpConnection(conversation.getContact());
+ if (ongoingRtpSession.isPresent()) {
+ final AbstractJingleConnection.Id id = ongoingRtpSession.get();
+ final Intent intent = new Intent(getActivity(), 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);
+ startActivity(intent);
+ }
+
+ }
+
private void checkPermissionAndTriggerAudioCall() {
if (activity.mUseTor || conversation.getAccount().isOnion()) {
Toast.makeText(activity, R.string.disable_tor_to_make_call, Toast.LENGTH_SHORT).show();
@@ -9,11 +9,14 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import com.google.common.base.Optional;
+
import java.util.List;
import eu.siacs.conversations.R;
import eu.siacs.conversations.databinding.ConversationListRowBinding;
import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.entities.Conversational;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.ui.ConversationFragment;
import eu.siacs.conversations.ui.XmppActivity;
@@ -22,6 +25,7 @@ import eu.siacs.conversations.ui.util.StyledAttributes;
import eu.siacs.conversations.utils.EmojiWrapper;
import eu.siacs.conversations.utils.IrregularUnicodeDetector;
import eu.siacs.conversations.utils.UIHelper;
+import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection;
import rocks.xmpp.addr.Jid;
public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapter.ConversationViewHolder> {
@@ -160,21 +164,35 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
}
}
- long muted_till = conversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0);
- if (muted_till == Long.MAX_VALUE) {
- viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
- int ic_notifications_off = activity.getThemeResource(R.attr.icon_notifications_off, R.drawable.ic_notifications_off_black_24dp);
- viewHolder.binding.notificationStatus.setImageResource(ic_notifications_off);
- } else if (muted_till >= System.currentTimeMillis()) {
- viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
- int ic_notifications_paused = activity.getThemeResource(R.attr.icon_notifications_paused, R.drawable.ic_notifications_paused_black_24dp);
- viewHolder.binding.notificationStatus.setImageResource(ic_notifications_paused);
- } else if (conversation.alwaysNotify()) {
- viewHolder.binding.notificationStatus.setVisibility(View.GONE);
+
+ final Optional<AbstractJingleConnection.Id> ongoingCall;
+ if (conversation.getMode() == Conversational.MODE_MULTI) {
+ ongoingCall = Optional.absent();
} else {
+ ongoingCall = activity.xmppConnectionService.getJingleConnectionManager().getOngoingRtpConnection(conversation.getContact());
+ }
+
+ if (ongoingCall.isPresent()) {
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
- int ic_notifications_none = activity.getThemeResource(R.attr.icon_notifications_none, R.drawable.ic_notifications_none_black_24dp);
- viewHolder.binding.notificationStatus.setImageResource(ic_notifications_none);
+ final int ic_ongoing_call = activity.getThemeResource(R.attr.ic_ongoing_call_hint, R.drawable.ic_phone_in_talk_black_18dp);
+ viewHolder.binding.notificationStatus.setImageResource(ic_ongoing_call);
+ } else {
+ final long muted_till = conversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0);
+ if (muted_till == Long.MAX_VALUE) {
+ viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
+ int ic_notifications_off = activity.getThemeResource(R.attr.icon_notifications_off, R.drawable.ic_notifications_off_black_24dp);
+ viewHolder.binding.notificationStatus.setImageResource(ic_notifications_off);
+ } else if (muted_till >= System.currentTimeMillis()) {
+ viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
+ int ic_notifications_paused = activity.getThemeResource(R.attr.icon_notifications_paused, R.drawable.ic_notifications_paused_black_24dp);
+ viewHolder.binding.notificationStatus.setImageResource(ic_notifications_paused);
+ } else if (conversation.alwaysNotify()) {
+ viewHolder.binding.notificationStatus.setVisibility(View.GONE);
+ } else {
+ viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
+ int ic_notifications_none = activity.getThemeResource(R.attr.icon_notifications_none, R.drawable.ic_notifications_none_black_24dp);
+ viewHolder.binding.notificationStatus.setImageResource(ic_notifications_none);
+ }
}
long timestamp;
@@ -1,19 +1,16 @@
package eu.siacs.conversations.xmpp.jingle;
-import android.os.SystemClock;
import android.util.Base64;
import android.util.Log;
-import com.google.common.base.Function;
import com.google.common.base.Objects;
+import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableSet;
-import org.checkerframework.checker.nullness.compatqual.NullableDecl;
-
import java.lang.ref.WeakReference;
import java.security.SecureRandom;
import java.util.Collection;
@@ -108,6 +105,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
return;
}
connections.put(id, connection);
+ mXmppConnectionService.updateConversationUi();
connection.deliverPacket(packet);
} else {
Log.d(Config.LOGTAG, "unable to route jingle packet: " + packet);
@@ -353,6 +351,18 @@ public class JingleConnectionManager extends AbstractConnectionManager {
connection.init(message);
}
+ public Optional<AbstractJingleConnection.Id> getOngoingRtpConnection(final Contact contact) {
+ for(final Map.Entry<AbstractJingleConnection.Id,AbstractJingleConnection> entry : this.connections.entrySet()) {
+ if (entry.getValue() instanceof 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.absent();
+ }
+
void finishConnection(final AbstractJingleConnection connection) {
this.connections.remove(connection.getId());
}
@@ -60,6 +60,12 @@
android:title="@string/send_location" />
</menu>
</item>
+ <item
+ android:id="@+id/action_ongoing_call"
+ android:icon="?attr/icon_ongoing_call"
+ android:orderInCategory="34"
+ android:title="@string/return_to_ongoing_call"
+ app:showAsAction="always" />
<item
android:id="@+id/action_call"
android:icon="?attr/icon_call"
@@ -91,6 +91,8 @@
<attr name="icon_new_attachment" format="reference"/>
<attr name="icon_not_secure" format="reference"/>
<attr name="icon_call" format="reference"/>
+ <attr name="icon_ongoing_call" format="reference"/>
+ <attr name="ic_ongoing_call_hint" format="reference"/>
<attr name="icon_quote" format="reference"/>
<attr name="icon_refresh" format="reference"/>
<attr name="icon_remove" format="reference"/>
@@ -919,6 +919,7 @@
<string name="video_call">Video call</string>
<string name="microphone_unavailable">Your microphone is unavailable</string>
<string name="only_one_call_at_a_time">You can only have one call at a time.</string>
+ <string name="return_to_ongoing_call">Return to ongoing call</string>
<plurals name="view_users">
<item quantity="one">View %1$d Participant</item>
<item quantity="other">View %1$d Participants</item>
@@ -99,6 +99,8 @@
<item type="reference" name="icon_new_attachment">@drawable/ic_attach_file_white_24dp</item>
<item type="reference" name="icon_not_secure">@drawable/ic_lock_open_white_24dp</item>
<item type="reference" name="icon_call">@drawable/ic_call_white_24dp</item>
+ <item type="reference" name="icon_ongoing_call">@drawable/ic_phone_in_talk_white_24dp</item>
+ <item type="reference" name="ic_ongoing_call_hint">@drawable/ic_phone_in_talk_black_18dp</item>
<item type="reference" name="icon_remove">@drawable/ic_delete_black_24dp</item>
<item type="reference" name="icon_search">@drawable/ic_search_white_24dp</item>
<item type="reference" name="icon_secure">@drawable/ic_lock_open_white_24dp</item>
@@ -219,6 +221,8 @@
<item type="reference" name="icon_new_attachment">@drawable/ic_attach_file_white_24dp</item>
<item type="reference" name="icon_not_secure">@drawable/ic_lock_open_white_24dp</item>
<item type="reference" name="icon_call">@drawable/ic_call_white_24dp</item>
+ <item type="reference" name="icon_ongoing_call">@drawable/ic_phone_in_talk_white_24dp</item>
+ <item type="reference" name="ic_ongoing_call_hint">@drawable/ic_phone_in_talk_white_18dp</item>
<item type="reference" name="icon_remove">@drawable/ic_delete_white_24dp</item>
<item type="reference" name="icon_search">@drawable/ic_search_white_24dp</item>
<item type="reference" name="icon_secure">@drawable/ic_lock_open_white_24dp</item>