indicate ongoing call. fixes #3675

This commit is contained in:
Daniel Gultsch 2020-04-27 11:53:31 +02:00
parent 9fbf73d1ea
commit 07911b2094
22 changed files with 89 additions and 20 deletions

View file

@ -52,6 +52,8 @@ import android.widget.PopupMenu;
import android.widget.TextView.OnEditorActionListener; import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast; import android.widget.Toast;
import com.google.common.base.Optional;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -117,6 +119,7 @@ import eu.siacs.conversations.utils.TimeframeUtils;
import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.XmppConnection;
import eu.siacs.conversations.xmpp.chatstate.ChatState; 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.JingleFileTransferConnection;
import eu.siacs.conversations.xmpp.jingle.RtpCapability; import eu.siacs.conversations.xmpp.jingle.RtpCapability;
import rocks.xmpp.addr.Jid; 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 menuMute = menu.findItem(R.id.action_mute);
final MenuItem menuUnmute = menu.findItem(R.id.action_unmute); final MenuItem menuUnmute = menu.findItem(R.id.action_unmute);
final MenuItem menuCall = menu.findItem(R.id.action_call); 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); 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()); menuInviteContact.setVisible(conversation.getMucOptions().canInvite());
menuMucDetails.setTitle(conversation.getMucOptions().isPrivateAndNonAnonymous() ? R.string.action_muc_details : R.string.channel_details); menuMucDetails.setTitle(conversation.getMucOptions().isPrivateAndNonAnonymous() ? R.string.action_muc_details : R.string.channel_details);
menuCall.setVisible(false); menuCall.setVisible(false);
menuOngoingCall.setVisible(false);
} else { } else {
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()); final RtpCapability.Capability rtpCapability = RtpCapability.check(conversation.getContact());
menuCall.setVisible(rtpCapability != RtpCapability.Capability.NONE); menuCall.setVisible(rtpCapability != RtpCapability.Capability.NONE);
menuVideoCall.setVisible(rtpCapability == RtpCapability.Capability.VIDEO); menuVideoCall.setVisible(rtpCapability == RtpCapability.Capability.VIDEO);
}
menuContactDetails.setVisible(!this.conversation.withSelf()); menuContactDetails.setVisible(!this.conversation.withSelf());
menuMucDetails.setVisible(false); menuMucDetails.setVisible(false);
final XmppConnectionService service = activity.xmppConnectionService; final XmppConnectionService service = activity.xmppConnectionService;
@ -1245,12 +1257,28 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
case R.id.action_video_call: case R.id.action_video_call:
checkPermissionAndTriggerVideoCall(); checkPermissionAndTriggerVideoCall();
break; break;
case R.id.action_ongoing_call:
returnToOngoingCall();
break;
default: default:
break; break;
} }
return super.onOptionsItemSelected(item); 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() { private void checkPermissionAndTriggerAudioCall() {
if (activity.mUseTor || conversation.getAccount().isOnion()) { if (activity.mUseTor || conversation.getAccount().isOnion()) {
Toast.makeText(activity, R.string.disable_tor_to_make_call, Toast.LENGTH_SHORT).show(); Toast.makeText(activity, R.string.disable_tor_to_make_call, Toast.LENGTH_SHORT).show();

View file

@ -9,11 +9,14 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.google.common.base.Optional;
import java.util.List; import java.util.List;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
import eu.siacs.conversations.databinding.ConversationListRowBinding; import eu.siacs.conversations.databinding.ConversationListRowBinding;
import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Conversational;
import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.ui.ConversationFragment; import eu.siacs.conversations.ui.ConversationFragment;
import eu.siacs.conversations.ui.XmppActivity; 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.EmojiWrapper;
import eu.siacs.conversations.utils.IrregularUnicodeDetector; import eu.siacs.conversations.utils.IrregularUnicodeDetector;
import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection;
import rocks.xmpp.addr.Jid; import rocks.xmpp.addr.Jid;
public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapter.ConversationViewHolder> { public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapter.ConversationViewHolder> {
@ -160,7 +164,20 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
} }
} }
long muted_till = conversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0);
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);
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) { if (muted_till == Long.MAX_VALUE) {
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE); viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
int ic_notifications_off = activity.getThemeResource(R.attr.icon_notifications_off, R.drawable.ic_notifications_off_black_24dp); int ic_notifications_off = activity.getThemeResource(R.attr.icon_notifications_off, R.drawable.ic_notifications_off_black_24dp);
@ -176,6 +193,7 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
int ic_notifications_none = activity.getThemeResource(R.attr.icon_notifications_none, R.drawable.ic_notifications_none_black_24dp); 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); viewHolder.binding.notificationStatus.setImageResource(ic_notifications_none);
} }
}
long timestamp; long timestamp;
if (draft != null) { if (draft != null) {

View file

@ -1,19 +1,16 @@
package eu.siacs.conversations.xmpp.jingle; package eu.siacs.conversations.xmpp.jingle;
import android.os.SystemClock;
import android.util.Base64; import android.util.Base64;
import android.util.Log; import android.util.Log;
import com.google.common.base.Function;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Collections2; import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Collection; import java.util.Collection;
@ -108,6 +105,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
return; return;
} }
connections.put(id, connection); connections.put(id, connection);
mXmppConnectionService.updateConversationUi();
connection.deliverPacket(packet); connection.deliverPacket(packet);
} else { } else {
Log.d(Config.LOGTAG, "unable to route jingle packet: " + packet); Log.d(Config.LOGTAG, "unable to route jingle packet: " + packet);
@ -353,6 +351,18 @@ public class JingleConnectionManager extends AbstractConnectionManager {
connection.init(message); 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) { void finishConnection(final AbstractJingleConnection connection) {
this.connections.remove(connection.getId()); this.connections.remove(connection.getId());
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 882 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 882 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -60,6 +60,12 @@
android:title="@string/send_location" /> android:title="@string/send_location" />
</menu> </menu>
</item> </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 <item
android:id="@+id/action_call" android:id="@+id/action_call"
android:icon="?attr/icon_call" android:icon="?attr/icon_call"

View file

@ -91,6 +91,8 @@
<attr name="icon_new_attachment" format="reference"/> <attr name="icon_new_attachment" format="reference"/>
<attr name="icon_not_secure" format="reference"/> <attr name="icon_not_secure" format="reference"/>
<attr name="icon_call" 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_quote" format="reference"/>
<attr name="icon_refresh" format="reference"/> <attr name="icon_refresh" format="reference"/>
<attr name="icon_remove" format="reference"/> <attr name="icon_remove" format="reference"/>

View file

@ -919,6 +919,7 @@
<string name="video_call">Video call</string> <string name="video_call">Video call</string>
<string name="microphone_unavailable">Your microphone is unavailable</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="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"> <plurals name="view_users">
<item quantity="one">View %1$d Participant</item> <item quantity="one">View %1$d Participant</item>
<item quantity="other">View %1$d Participants</item> <item quantity="other">View %1$d Participants</item>

View file

@ -99,6 +99,8 @@
<item type="reference" name="icon_new_attachment">@drawable/ic_attach_file_white_24dp</item> <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_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_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_remove">@drawable/ic_delete_black_24dp</item>
<item type="reference" name="icon_search">@drawable/ic_search_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> <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_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_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_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_remove">@drawable/ic_delete_white_24dp</item>
<item type="reference" name="icon_search">@drawable/ic_search_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> <item type="reference" name="icon_secure">@drawable/ic_lock_open_white_24dp</item>