Search in sources :

Example 41 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class MucDetailsContextMenuHelper method removeFromRoom.

private static void removeFromRoom(final User user, XmppActivity activity, XmppConnectionService.OnAffiliationChanged onAffiliationChanged) {
    final Conversation conversation = user.getConversation();
    if (conversation.getMucOptions().membersOnly()) {
        activity.xmppConnectionService.changeAffiliationInConference(conversation, user.getRealJid(), MucOptions.Affiliation.NONE, onAffiliationChanged);
        if (user.getRole() != MucOptions.Role.NONE) {
            activity.xmppConnectionService.changeRoleInConference(conversation, user.getName(), MucOptions.Role.NONE);
        }
    } else {
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setTitle(R.string.ban_from_conference);
        String jid = user.getRealJid().asBareJid().toString();
        SpannableString message = new SpannableString(activity.getString(R.string.removing_from_public_conference, jid));
        int start = message.toString().indexOf(jid);
        if (start >= 0) {
            message.setSpan(new TypefaceSpan("monospace"), start, start + jid.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        builder.setMessage(message);
        builder.setNegativeButton(R.string.cancel, null);
        builder.setPositiveButton(R.string.ban_now, (dialog, which) -> {
            activity.xmppConnectionService.changeAffiliationInConference(conversation, user.getRealJid(), MucOptions.Affiliation.OUTCAST, onAffiliationChanged);
            if (user.getRole() != MucOptions.Role.NONE) {
                activity.xmppConnectionService.changeRoleInConference(conversation, user.getName(), MucOptions.Role.NONE);
            }
        });
        builder.create().show();
    }
}
Also used : AlertDialog(androidx.appcompat.app.AlertDialog) SpannableString(android.text.SpannableString) Conversation(eu.siacs.conversations.entities.Conversation) SpannableString(android.text.SpannableString) TypefaceSpan(android.text.style.TypefaceSpan)

Example 42 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class JingleConnectionManager method writeLogMissedOutgoing.

private void writeLogMissedOutgoing(final Account account, Jid with, final String sessionId, String serverMsgId, long timestamp) {
    final Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, with.asBareJid(), false, false);
    final Message message = new Message(conversation, Message.STATUS_SEND, Message.TYPE_RTP_SESSION, sessionId);
    message.setBody(new RtpSessionStatus(false, 0).toString());
    message.setServerMsgId(serverMsgId);
    message.setTime(timestamp);
    writeMessage(message);
}
Also used : Message(eu.siacs.conversations.entities.Message) RtpSessionStatus(eu.siacs.conversations.entities.RtpSessionStatus) Conversation(eu.siacs.conversations.entities.Conversation)

Example 43 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class JingleConnectionManager method deliverMessage.

public void deliverMessage(final Account account, final Jid to, final Jid from, final Element message, String remoteMsgId, String serverMsgId, long timestamp) {
    Preconditions.checkArgument(Namespace.JINGLE_MESSAGE.equals(message.getNamespace()));
    final String sessionId = message.getAttribute("id");
    if (sessionId == null) {
        return;
    }
    if ("accept".equals(message.getName())) {
        for (AbstractJingleConnection connection : connections.values()) {
            if (connection instanceof JingleRtpConnection) {
                final JingleRtpConnection rtpConnection = (JingleRtpConnection) connection;
                final AbstractJingleConnection.Id id = connection.getId();
                if (id.account == account && id.sessionId.equals(sessionId)) {
                    rtpConnection.deliveryMessage(from, message, serverMsgId, timestamp);
                    return;
                }
            }
        }
        return;
    }
    final boolean fromSelf = from.asBareJid().equals(account.getJid().asBareJid());
    final boolean addressedDirectly = to != null && to.equals(account.getJid());
    final AbstractJingleConnection.Id id;
    if (fromSelf) {
        if (to != null && to.isFullJid()) {
            id = AbstractJingleConnection.Id.of(account, to, sessionId);
        } else {
            return;
        }
    } else {
        id = AbstractJingleConnection.Id.of(account, from, sessionId);
    }
    final AbstractJingleConnection existingJingleConnection = connections.get(id);
    if (existingJingleConnection != null) {
        if (existingJingleConnection instanceof JingleRtpConnection) {
            ((JingleRtpConnection) existingJingleConnection).deliveryMessage(from, message, serverMsgId, timestamp);
        } else {
            Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": " + existingJingleConnection.getClass().getName() + " does not support jingle messages");
        }
        return;
    }
    if (fromSelf) {
        if ("proceed".equals(message.getName())) {
            final Conversation c = mXmppConnectionService.findOrCreateConversation(account, id.with, false, false);
            final Message previousBusy = c.findRtpSession(sessionId, Message.STATUS_RECEIVED);
            if (previousBusy != null) {
                previousBusy.setBody(new RtpSessionStatus(true, 0).toString());
                if (serverMsgId != null) {
                    previousBusy.setServerMsgId(serverMsgId);
                }
                previousBusy.setTime(timestamp);
                mXmppConnectionService.updateMessage(previousBusy, true);
                Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": updated previous busy because call got picked up by another device");
                return;
            }
        }
        // TODO handle reject for cases where we don’t have carbon copies (normally reject is to be sent to own bare jid as well)
        Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": ignore jingle message from self");
        return;
    }
    if ("propose".equals(message.getName())) {
        final Propose propose = Propose.upgrade(message);
        final List<GenericDescription> descriptions = propose.getDescriptions();
        final Collection<RtpDescription> rtpDescriptions = Collections2.transform(Collections2.filter(descriptions, d -> d instanceof RtpDescription), input -> (RtpDescription) input);
        if (rtpDescriptions.size() > 0 && rtpDescriptions.size() == descriptions.size() && isUsingClearNet(account)) {
            final Collection<Media> media = Collections2.transform(rtpDescriptions, RtpDescription::getMedia);
            if (media.contains(Media.UNKNOWN)) {
                Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": encountered unknown media in session proposal. " + propose);
                return;
            }
            final Optional<RtpSessionProposal> matchingSessionProposal = findMatchingSessionProposal(account, id.with, ImmutableSet.copyOf(media));
            if (matchingSessionProposal.isPresent()) {
                final String ourSessionId = matchingSessionProposal.get().sessionId;
                final String theirSessionId = id.sessionId;
                if (ComparisonChain.start().compare(ourSessionId, theirSessionId).compare(account.getJid().toEscapedString(), id.with.toEscapedString()).result() > 0) {
                    Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": our session lost tie break. automatically accepting their session. winning Session=" + theirSessionId);
                    // TODO a retract for this reason should probably include some indication of tie break
                    retractSessionProposal(matchingSessionProposal.get());
                    final JingleRtpConnection rtpConnection = new JingleRtpConnection(this, id, from);
                    this.connections.put(id, rtpConnection);
                    rtpConnection.setProposedMedia(ImmutableSet.copyOf(media));
                    rtpConnection.deliveryMessage(from, message, serverMsgId, timestamp);
                } else {
                    Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": our session won tie break. waiting for other party to accept. winningSession=" + ourSessionId);
                }
                return;
            }
            final boolean stranger = isWithStrangerAndStrangerNotificationsAreOff(account, id.with);
            if (isBusy() || stranger) {
                writeLogMissedIncoming(account, id.with.asBareJid(), id.sessionId, serverMsgId, timestamp);
                if (stranger) {
                    Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": ignoring call proposal from stranger " + id.with);
                    return;
                }
                final int activeDevices = account.activeDevicesWithRtpCapability();
                Log.d(Config.LOGTAG, "active devices with rtp capability: " + activeDevices);
                if (activeDevices == 0) {
                    final MessagePacket reject = mXmppConnectionService.getMessageGenerator().sessionReject(from, sessionId);
                    mXmppConnectionService.sendMessagePacket(account, reject);
                } else {
                    Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": ignoring proposal because busy on this device but there are other devices");
                }
            } else {
                final JingleRtpConnection rtpConnection = new JingleRtpConnection(this, id, from);
                this.connections.put(id, rtpConnection);
                rtpConnection.setProposedMedia(ImmutableSet.copyOf(media));
                rtpConnection.deliveryMessage(from, message, serverMsgId, timestamp);
            }
        } else {
            Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": unable to react to proposed session with " + rtpDescriptions.size() + " rtp descriptions of " + descriptions.size() + " total descriptions");
        }
    } else if (addressedDirectly && "proceed".equals(message.getName())) {
        synchronized (rtpSessionProposals) {
            final RtpSessionProposal proposal = getRtpSessionProposal(account, from.asBareJid(), sessionId);
            if (proposal != null) {
                rtpSessionProposals.remove(proposal);
                final JingleRtpConnection rtpConnection = new JingleRtpConnection(this, id, account.getJid());
                rtpConnection.setProposedMedia(proposal.media);
                this.connections.put(id, rtpConnection);
                rtpConnection.transitionOrThrow(AbstractJingleConnection.State.PROPOSED);
                rtpConnection.deliveryMessage(from, message, serverMsgId, timestamp);
            } else {
                Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": no rtp session proposal found for " + from + " to deliver proceed");
                if (remoteMsgId == null) {
                    return;
                }
                final MessagePacket errorMessage = new MessagePacket();
                errorMessage.setTo(from);
                errorMessage.setId(remoteMsgId);
                errorMessage.setType(MessagePacket.TYPE_ERROR);
                final Element error = errorMessage.addChild("error");
                error.setAttribute("code", "404");
                error.setAttribute("type", "cancel");
                error.addChild("item-not-found", "urn:ietf:params:xml:ns:xmpp-stanzas");
                mXmppConnectionService.sendMessagePacket(account, errorMessage);
            }
        }
    } else if (addressedDirectly && "reject".equals(message.getName())) {
        final RtpSessionProposal proposal = getRtpSessionProposal(account, from.asBareJid(), sessionId);
        synchronized (rtpSessionProposals) {
            if (proposal != null && rtpSessionProposals.remove(proposal) != null) {
                writeLogMissedOutgoing(account, proposal.with, proposal.sessionId, serverMsgId, timestamp);
                toneManager.transition(RtpEndUserState.DECLINED_OR_BUSY, proposal.media);
                mXmppConnectionService.notifyJingleRtpConnectionUpdate(account, proposal.with, proposal.sessionId, RtpEndUserState.DECLINED_OR_BUSY);
            } else {
                Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": no rtp session proposal found for " + from + " to deliver reject");
            }
        }
    } else {
        Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": retrieved out of order jingle message" + message);
    }
}
Also used : Conversational(eu.siacs.conversations.entities.Conversational) Content(eu.siacs.conversations.xmpp.jingle.stanzas.Content) RtpDescription(eu.siacs.conversations.xmpp.jingle.stanzas.RtpDescription) Config(eu.siacs.conversations.Config) ScheduledFuture(java.util.concurrent.ScheduledFuture) IqPacket(eu.siacs.conversations.xmpp.stanzas.IqPacket) Reason(eu.siacs.conversations.xmpp.jingle.stanzas.Reason) HashMap(java.util.HashMap) Collections2(com.google.common.collect.Collections2) Account(eu.siacs.conversations.entities.Account) Element(eu.siacs.conversations.xml.Element) Conversation(eu.siacs.conversations.entities.Conversation) SecureRandom(java.security.SecureRandom) GenericDescription(eu.siacs.conversations.xmpp.jingle.stanzas.GenericDescription) Optional(com.google.common.base.Optional) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) FileTransferDescription(eu.siacs.conversations.xmpp.jingle.stanzas.FileTransferDescription) Objects(com.google.common.base.Objects) WeakReference(java.lang.ref.WeakReference) Log(android.util.Log) XmppConnection(eu.siacs.conversations.xmpp.XmppConnection) MessagePacket(eu.siacs.conversations.xmpp.stanzas.MessagePacket) ImmutableSet(com.google.common.collect.ImmutableSet) Contact(eu.siacs.conversations.entities.Contact) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Propose(eu.siacs.conversations.xmpp.jingle.stanzas.Propose) Set(java.util.Set) JinglePacket(eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket) ComparisonChain(com.google.common.collect.ComparisonChain) Executors(java.util.concurrent.Executors) TimeUnit(java.util.concurrent.TimeUnit) Transferable(eu.siacs.conversations.entities.Transferable) List(java.util.List) Message(eu.siacs.conversations.entities.Message) RtpSessionStatus(eu.siacs.conversations.entities.RtpSessionStatus) XmppConnectionService(eu.siacs.conversations.services.XmppConnectionService) Namespace(eu.siacs.conversations.xml.Namespace) OnIqPacketReceived(eu.siacs.conversations.xmpp.OnIqPacketReceived) Base64(android.util.Base64) Preconditions(com.google.common.base.Preconditions) CacheBuilder(com.google.common.cache.CacheBuilder) Cache(com.google.common.cache.Cache) AbstractConnectionManager(eu.siacs.conversations.services.AbstractConnectionManager) Collections(java.util.Collections) Jid(eu.siacs.conversations.xmpp.Jid) Message(eu.siacs.conversations.entities.Message) Element(eu.siacs.conversations.xml.Element) GenericDescription(eu.siacs.conversations.xmpp.jingle.stanzas.GenericDescription) Conversation(eu.siacs.conversations.entities.Conversation) RtpDescription(eu.siacs.conversations.xmpp.jingle.stanzas.RtpDescription) MessagePacket(eu.siacs.conversations.xmpp.stanzas.MessagePacket) Propose(eu.siacs.conversations.xmpp.jingle.stanzas.Propose) RtpSessionStatus(eu.siacs.conversations.entities.RtpSessionStatus)

Example 44 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class JingleFileTransferConnection method init.

public void init(final Message message) {
    Preconditions.checkArgument(message.isFileOrImage());
    if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) {
        Conversation conversation = (Conversation) message.getConversation();
        conversation.getAccount().getAxolotlService().prepareKeyTransportMessage(conversation, xmppAxolotlMessage -> {
            if (xmppAxolotlMessage != null) {
                init(message, xmppAxolotlMessage);
            } else {
                fail();
            }
        });
    } else {
        init(message, null);
    }
}
Also used : Conversation(eu.siacs.conversations.entities.Conversation)

Example 45 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class ConversationFragment method attachFile.

public void attachFile(final int attachmentChoice, final boolean updateRecentlyUsed) {
    if (attachmentChoice == ATTACHMENT_CHOICE_RECORD_VOICE) {
        if (!hasPermissions(attachmentChoice, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO)) {
            return;
        }
    } else if (attachmentChoice == ATTACHMENT_CHOICE_TAKE_PHOTO || attachmentChoice == ATTACHMENT_CHOICE_RECORD_VIDEO) {
        if (!hasPermissions(attachmentChoice, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA)) {
            return;
        }
    } else if (attachmentChoice != ATTACHMENT_CHOICE_LOCATION) {
        if (!hasPermissions(attachmentChoice, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            return;
        }
    }
    if (updateRecentlyUsed) {
        storeRecentlyUsedQuickAction(attachmentChoice);
    }
    final int encryption = conversation.getNextEncryption();
    final int mode = conversation.getMode();
    if (encryption == Message.ENCRYPTION_PGP) {
        if (activity.hasPgp()) {
            if (mode == Conversation.MODE_SINGLE && conversation.getContact().getPgpKeyId() != 0) {
                activity.xmppConnectionService.getPgpEngine().hasKey(conversation.getContact(), new UiCallback<Contact>() {

                    @Override
                    public void userInputRequired(PendingIntent pi, Contact contact) {
                        startPendingIntent(pi, attachmentChoice);
                    }

                    @Override
                    public void success(Contact contact) {
                        invokeAttachFileIntent(attachmentChoice);
                    }

                    @Override
                    public void error(int error, Contact contact) {
                        activity.replaceToast(getString(error));
                    }
                });
            } else if (mode == Conversation.MODE_MULTI && conversation.getMucOptions().pgpKeysInUse()) {
                if (!conversation.getMucOptions().everybodyHasKeys()) {
                    Toast warning = Toast.makeText(getActivity(), R.string.missing_public_keys, Toast.LENGTH_LONG);
                    warning.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
                    warning.show();
                }
                invokeAttachFileIntent(attachmentChoice);
            } else {
                showNoPGPKeyDialog(false, (dialog, which) -> {
                    conversation.setNextEncryption(Message.ENCRYPTION_NONE);
                    activity.xmppConnectionService.updateConversation(conversation);
                    invokeAttachFileIntent(attachmentChoice);
                });
            }
        } else {
            activity.showInstallPgpDialog();
        }
    } else {
        invokeAttachFileIntent(attachmentChoice);
    }
}
Also used : PendingItem(eu.siacs.conversations.ui.util.PendingItem) Conversational(eu.siacs.conversations.entities.Conversational) Arrays(java.util.Arrays) Bundle(android.os.Bundle) ConversationMenuConfigurator(eu.siacs.conversations.ui.util.ConversationMenuConfigurator) NonNull(androidx.annotation.NonNull) Uri(android.net.Uri) PermissionUtils.getFirstDenied(eu.siacs.conversations.utils.PermissionUtils.getFirstDenied) Manifest(android.Manifest) Optional(com.google.common.base.Optional) Handler(android.os.Handler) MediaStore(android.provider.MediaStore) PopupMenu(android.widget.PopupMenu) StylingHelper(eu.siacs.conversations.utils.StylingHelper) Log(android.util.Log) DataBindingUtil(androidx.databinding.DataBindingUtil) XmppConnection(eu.siacs.conversations.xmpp.XmppConnection) NickValidityChecker(eu.siacs.conversations.utils.NickValidityChecker) Contact(eu.siacs.conversations.entities.Contact) Attachment(eu.siacs.conversations.ui.util.Attachment) Set(java.util.Set) MucOptions(eu.siacs.conversations.entities.MucOptions) FragmentConversationBinding(eu.siacs.conversations.databinding.FragmentConversationBinding) IdRes(androidx.annotation.IdRes) StringRes(androidx.annotation.StringRes) MediaPreviewAdapter(eu.siacs.conversations.ui.adapter.MediaPreviewAdapter) FingerprintStatus(eu.siacs.conversations.crypto.axolotl.FingerprintStatus) FragmentManager(android.app.FragmentManager) Config(eu.siacs.conversations.Config) ReadByMarker(eu.siacs.conversations.entities.ReadByMarker) ContextMenuInfo(android.view.ContextMenu.ContextMenuInfo) SystemClock(android.os.SystemClock) Account(eu.siacs.conversations.entities.Account) SendButtonTool(eu.siacs.conversations.ui.util.SendButtonTool) Editable(android.text.Editable) EditMessage(eu.siacs.conversations.ui.widget.EditMessage) ArrayList(java.util.ArrayList) ListViewUtils(eu.siacs.conversations.ui.util.ListViewUtils) AccountUtils(eu.siacs.conversations.utils.AccountUtils) ChatState(eu.siacs.conversations.xmpp.chatstate.ChatState) TransferablePlaceholder(eu.siacs.conversations.entities.TransferablePlaceholder) JingleFileTransferConnection(eu.siacs.conversations.xmpp.jingle.JingleFileTransferConnection) MenuInflater(android.view.MenuInflater) Toast(android.widget.Toast) Menu(android.view.Menu) MessageAdapter(eu.siacs.conversations.ui.adapter.MessageAdapter) MessageUtils(eu.siacs.conversations.utils.MessageUtils) Fragment(android.app.Fragment) QuickConversationsService(eu.siacs.conversations.services.QuickConversationsService) ActivityResult(eu.siacs.conversations.ui.util.ActivityResult) QuickLoader(eu.siacs.conversations.utils.QuickLoader) AbstractJingleConnection(eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection) RtpCapability(eu.siacs.conversations.xmpp.jingle.RtpCapability) TextUtils(android.text.TextUtils) SoftKeyboardUtils.hideSoftKeyboard(eu.siacs.conversations.ui.util.SoftKeyboardUtils.hideSoftKeyboard) Transferable(eu.siacs.conversations.entities.Transferable) Gravity(android.view.Gravity) XmppConnectionService(eu.siacs.conversations.services.XmppConnectionService) SharedPreferences(android.content.SharedPreferences) User(eu.siacs.conversations.entities.MucOptions.User) DownloadableFile(eu.siacs.conversations.entities.DownloadableFile) SendButtonAction(eu.siacs.conversations.ui.util.SendButtonAction) PackageManager(android.content.pm.PackageManager) GeoHelper(eu.siacs.conversations.utils.GeoHelper) InputConnectionCompat(androidx.core.view.inputmethod.InputConnectionCompat) ShareUtil(eu.siacs.conversations.ui.util.ShareUtil) PendingIntent(android.app.PendingIntent) Blockable(eu.siacs.conversations.entities.Blockable) AdapterContextMenuInfo(android.widget.AdapterView.AdapterContextMenuInfo) MenuDoubleTabUtil(eu.siacs.conversations.ui.util.MenuDoubleTabUtil) JingleConnectionManager(eu.siacs.conversations.xmpp.jingle.JingleConnectionManager) CheckBox(android.widget.CheckBox) View(android.view.View) DateSeparator(eu.siacs.conversations.ui.util.DateSeparator) MucDetailsContextMenuHelper(eu.siacs.conversations.ui.util.MucDetailsContextMenuHelper) AdapterView(android.widget.AdapterView) SendIntentException(android.content.IntentSender.SendIntentException) PreferenceManager(android.preference.PreferenceManager) PresenceSelector(eu.siacs.conversations.ui.util.PresenceSelector) PermissionUtils.writeGranted(eu.siacs.conversations.utils.PermissionUtils.writeGranted) REQUEST_INVITE_TO_CONVERSATION(eu.siacs.conversations.ui.XmppActivity.REQUEST_INVITE_TO_CONVERSATION) ScrollState(eu.siacs.conversations.ui.util.ScrollState) Collection(java.util.Collection) MessageArchiveService(eu.siacs.conversations.services.MessageArchiveService) UUID(java.util.UUID) ViewGroup(android.view.ViewGroup) OnScrollListener(android.widget.AbsListView.OnScrollListener) List(java.util.List) Message(eu.siacs.conversations.entities.Message) OnEditorActionListener(android.widget.TextView.OnEditorActionListener) ListView(android.widget.ListView) NotNull(org.jetbrains.annotations.NotNull) EditorInfo(android.view.inputmethod.EditorInfo) HttpDownloadConnection(eu.siacs.conversations.http.HttpDownloadConnection) Context(android.content.Context) ContextMenu(android.view.ContextMenu) AlertDialog(androidx.appcompat.app.AlertDialog) Patterns(eu.siacs.conversations.utils.Patterns) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Intent(android.content.Intent) FileBackend(eu.siacs.conversations.persistance.FileBackend) MenuItem(android.view.MenuItem) InputMethodManager(android.view.inputmethod.InputMethodManager) Conversation(eu.siacs.conversations.entities.Conversation) HashSet(java.util.HashSet) Compatibility(eu.siacs.conversations.utils.Compatibility) SuppressLint(android.annotation.SuppressLint) MotionEvent(android.view.MotionEvent) Presence(eu.siacs.conversations.entities.Presence) UIHelper(eu.siacs.conversations.utils.UIHelper) AxolotlService(eu.siacs.conversations.crypto.axolotl.AxolotlService) Build(android.os.Build) DialogInterface(android.content.DialogInterface) ViewUtil(eu.siacs.conversations.ui.util.ViewUtil) Iterator(java.util.Iterator) R(eu.siacs.conversations.R) LayoutInflater(android.view.LayoutInflater) Media(eu.siacs.conversations.xmpp.jingle.Media) EXTRA_ACCOUNT(eu.siacs.conversations.ui.XmppActivity.EXTRA_ACCOUNT) AbsListView(android.widget.AbsListView) InputContentInfoCompat(androidx.core.view.inputmethod.InputContentInfoCompat) PermissionUtils.allGranted(eu.siacs.conversations.utils.PermissionUtils.allGranted) Namespace(eu.siacs.conversations.xml.Namespace) EditMessageActionModeCallback(eu.siacs.conversations.ui.util.EditMessageActionModeCallback) TimeFrameUtils(eu.siacs.conversations.utils.TimeFrameUtils) Activity(android.app.Activity) Collections(java.util.Collections) Jid(eu.siacs.conversations.xmpp.Jid) OnClickListener(android.view.View.OnClickListener) OngoingRtpSession(eu.siacs.conversations.xmpp.jingle.OngoingRtpSession) Toast(android.widget.Toast) PendingIntent(android.app.PendingIntent) SuppressLint(android.annotation.SuppressLint) Contact(eu.siacs.conversations.entities.Contact)

Aggregations

Conversation (eu.siacs.conversations.entities.Conversation)110 Account (eu.siacs.conversations.entities.Account)27 Message (eu.siacs.conversations.entities.Message)24 Jid (eu.siacs.conversations.xmpp.Jid)22 Contact (eu.siacs.conversations.entities.Contact)17 MucOptions (eu.siacs.conversations.entities.MucOptions)10 Intent (android.content.Intent)9 Element (eu.siacs.conversations.xml.Element)9 PendingIntent (android.app.PendingIntent)8 XmppAxolotlMessage (eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage)8 MessagePacket (eu.siacs.conversations.xmpp.stanzas.MessagePacket)8 Uri (android.net.Uri)7 Conversational (eu.siacs.conversations.entities.Conversational)7 InvalidJidException (eu.siacs.conversations.xmpp.jid.InvalidJidException)7 SuppressLint (android.annotation.SuppressLint)6 SpannableString (android.text.SpannableString)6 XmppConnection (eu.siacs.conversations.xmpp.XmppConnection)6 Jid (eu.siacs.conversations.xmpp.jid.Jid)6 ArrayList (java.util.ArrayList)6 Fragment (android.app.Fragment)4