private void drawTile(
     Canvas canvas, MucOptions.User user, int left, int top, int right, int bottom) {
   Contact contact = user.getContact();
   if (contact != null) {
     Uri uri = null;
     if (contact.getProfilePhoto() != null) {
       uri = Uri.parse(contact.getProfilePhoto());
     } else if (contact.getAvatar() != null) {
       uri = mXmppConnectionService.getFileBackend().getAvatarUri(contact.getAvatar());
     }
     if (uri != null) {
       Bitmap bitmap =
           mXmppConnectionService.getFileBackend().cropCenter(uri, bottom - top, right - left);
       if (bitmap != null) {
         drawTile(canvas, bitmap, left, top, right, bottom);
         return;
       }
     }
   }
   String name = user.getName();
   String letter;
   int color;
   if (name.length() > 0) {
     letter = name.substring(0, 1);
     color = this.getColorForName(name);
   } else {
     letter = "X";
     color = PLACEHOLDER_COLOR;
   }
   drawTile(canvas, letter, color, left, top, right, bottom);
 }
 public void switchToContactDetails(Contact contact, String messageFingerprint) {
   Intent intent = new Intent(this, ContactDetailsActivity.class);
   intent.setAction(ContactDetailsActivity.ACTION_VIEW_CONTACT);
   intent.putExtra("account", contact.getAccount().getJid().toBareJid().toString());
   intent.putExtra("contact", contact.getJid().toString());
   intent.putExtra("fingerprint", messageFingerprint);
   startActivity(intent);
 }
 private void fillMap(SQLiteAxolotlStore store) {
   List<Integer> deviceIds = store.getSubDeviceSessions(account.getJid().toBareJid().toString());
   putDevicesForJid(account.getJid().toBareJid().toString(), deviceIds, store);
   for (Contact contact : account.getRoster().getContacts()) {
     Jid bareJid = contact.getJid().toBareJid();
     if (bareJid == null) {
       continue; // FIXME: handle this?
     }
     String address = bareJid.toString();
     deviceIds = store.getSubDeviceSessions(address);
     putDevicesForJid(address, deviceIds, store);
   }
 }
 private void parseEvent(final Element event, final Jid from, final Account account) {
   Element items = event.findChild("items");
   String node = items == null ? null : items.getAttribute("node");
   if ("urn:xmpp:avatar:metadata".equals(node)) {
     Avatar avatar = Avatar.parseMetadata(items);
     if (avatar != null) {
       avatar.owner = from.toBareJid();
       if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
         if (account.getJid().toBareJid().equals(from)) {
           if (account.setAvatar(avatar.getFilename())) {
             mXmppConnectionService.databaseBackend.updateAccount(account);
           }
           mXmppConnectionService.getAvatarService().clear(account);
           mXmppConnectionService.updateConversationUi();
           mXmppConnectionService.updateAccountUi();
         } else {
           Contact contact = account.getRoster().getContact(from);
           contact.setAvatar(avatar);
           mXmppConnectionService.getAvatarService().clear(contact);
           mXmppConnectionService.updateConversationUi();
           mXmppConnectionService.updateRosterUi();
         }
       } else {
         mXmppConnectionService.fetchAvatar(account, avatar);
       }
     }
   } else if ("http://jabber.org/protocol/nick".equals(node)) {
     Element i = items.findChild("item");
     Element nick = i == null ? null : i.findChild("nick", "http://jabber.org/protocol/nick");
     if (nick != null && nick.getContent() != null) {
       Contact contact = account.getRoster().getContact(from);
       contact.setPresenceName(nick.getContent());
       mXmppConnectionService.getAvatarService().clear(account);
       mXmppConnectionService.updateConversationUi();
       mXmppConnectionService.updateAccountUi();
     }
   } else if (AxolotlService.PEP_DEVICE_LIST.equals(node)) {
     Log.d(
         Config.LOGTAG,
         AxolotlService.getLogprefix(account)
             + "Received PEP device list update from "
             + from
             + ", processing...");
     Element item = items.findChild("item");
     Set<Integer> deviceIds = mXmppConnectionService.getIqParser().deviceIds(item);
     AxolotlService axolotlService = account.getAxolotlService();
     axolotlService.registerDevices(from, deviceIds);
     mXmppConnectionService.updateAccountUi();
   }
 }
 private String key(Contact contact, int size) {
   synchronized (this.sizes) {
     if (!this.sizes.contains(size)) {
       this.sizes.add(size);
     }
   }
   return PREFIX_CONTACT
       + "_"
       + contact.getAccount().getJid()
       + "_"
       + contact.getJid()
       + "_"
       + String.valueOf(size);
 }
 private void updateSnackBar(final Conversation conversation) {
   final Account account = conversation.getAccount();
   final Contact contact = conversation.getContact();
   final int mode = conversation.getMode();
   if (conversation.isBlocked()) {
     showSnackbar(R.string.contact_blocked, R.string.unblock, this.mUnblockClickListener);
   } else if (!contact.showInRoster()
       && contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
     showSnackbar(R.string.contact_added_you, R.string.add_back, this.mAddBackClickListener);
   } else if (mode == Conversation.MODE_MULTI
       && !conversation.getMucOptions().online()
       && account.getStatus() == Account.State.ONLINE) {
     switch (conversation.getMucOptions().getError()) {
       case MucOptions.ERROR_NICK_IN_USE:
         showSnackbar(R.string.nick_in_use, R.string.edit, clickToMuc);
         break;
       case MucOptions.ERROR_UNKNOWN:
         showSnackbar(R.string.conference_not_found, R.string.leave, leaveMuc);
         break;
       case MucOptions.ERROR_PASSWORD_REQUIRED:
         showSnackbar(
             R.string.conference_requires_password, R.string.enter_password, enterPassword);
         break;
       case MucOptions.ERROR_BANNED:
         showSnackbar(R.string.conference_banned, R.string.leave, leaveMuc);
         break;
       case MucOptions.ERROR_MEMBERS_ONLY:
         showSnackbar(R.string.conference_members_only, R.string.leave, leaveMuc);
         break;
       case MucOptions.KICKED_FROM_ROOM:
         showSnackbar(R.string.conference_kicked, R.string.join, joinMuc);
         break;
       default:
         break;
     }
   } else if (askForPassphraseIntent != null) {
     showSnackbar(R.string.openpgp_messages_found, R.string.decrypt, clickToDecryptListener);
   } else if (mode == Conversation.MODE_SINGLE && conversation.smpRequested()) {
     showSnackbar(R.string.smp_requested, R.string.verify, this.mAnswerSmpClickListener);
   } else if (mode == Conversation.MODE_SINGLE
       && conversation.hasValidOtrSession()
       && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED)
       && (!conversation.isOtrFingerprintVerified())) {
     showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, clickToVerify);
   } else if (conversation.isMuted()) {
     showSnackbar(R.string.notifications_disabled, R.string.enable, this.mUnmuteClickListener);
   } else {
     hideSnackbar();
   }
 }
  public boolean isContactAxolotlCapable(Contact contact) {

    Jid jid = contact.getJid().toBareJid();
    AxolotlAddress address = new AxolotlAddress(jid.toString(), 0);
    return sessions.hasAny(address)
        || (deviceIds.containsKey(jid) && !deviceIds.get(jid).isEmpty());
  }
  @Nullable
  private XmppAxolotlMessage buildHeader(Contact contact) {
    final XmppAxolotlMessage axolotlMessage =
        new XmppAxolotlMessage(contact.getJid().toBareJid(), getOwnDeviceId());

    Set<XmppAxolotlSession> contactSessions = findSessionsforContact(contact);
    Set<XmppAxolotlSession> ownSessions = findOwnSessions();
    if (contactSessions.isEmpty()) {
      return null;
    }
    Log.d(
        Config.LOGTAG,
        AxolotlService.getLogprefix(account) + "Building axolotl foreign keyElements...");
    for (XmppAxolotlSession session : contactSessions) {
      Log.v(
          Config.LOGTAG,
          AxolotlService.getLogprefix(account) + session.getRemoteAddress().toString());
      axolotlMessage.addDevice(session);
    }
    Log.d(
        Config.LOGTAG,
        AxolotlService.getLogprefix(account) + "Building axolotl own keyElements...");
    for (XmppAxolotlSession session : ownSessions) {
      Log.v(
          Config.LOGTAG,
          AxolotlService.getLogprefix(account) + session.getRemoteAddress().toString());
      axolotlMessage.addDevice(session);
    }

    return axolotlMessage;
  }
 public Bitmap get(Contact contact, int size) {
   final String KEY = key(contact, size);
   Bitmap avatar = this.mXmppConnectionService.getBitmapCache().get(KEY);
   if (avatar != null) {
     return avatar;
   }
   if (contact.getProfilePhoto() != null) {
     avatar =
         mXmppConnectionService
             .getFileBackend()
             .cropCenterSquare(Uri.parse(contact.getProfilePhoto()), size);
   }
   if (avatar == null && contact.getAvatar() != null) {
     avatar = mXmppConnectionService.getFileBackend().getAvatar(contact.getAvatar(), size);
   }
   if (avatar == null) {
     avatar = get(contact.getDisplayName(), size);
   }
   this.mXmppConnectionService.getBitmapCache().put(KEY, avatar);
   return avatar;
 }
Beispiel #10
0
 public static String getMessageDisplayName(final Message message) {
   if (message.getStatus() == Message.STATUS_RECEIVED) {
     final Contact contact = message.getContact();
     if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
       if (contact != null) {
         return contact.getDisplayName();
       } else {
         return getDisplayedMucCounterpart(message.getCounterpart());
       }
     } else {
       return contact != null ? contact.getDisplayName() : "";
     }
   } else {
     if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
       return getDisplayedMucCounterpart(message.getConversation().getJid());
     } else {
       final Jid jid = message.getConversation().getAccount().getJid();
       return jid.hasLocalpart() ? jid.getLocalpart() : jid.toDomainJid().toString();
     }
   }
 }
  protected void showAddToRosterDialog(final Contact contact) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(contact.getJid().toString());
    builder.setMessage(getString(R.string.not_in_roster));
    builder.setNegativeButton(getString(R.string.cancel), null);
    builder.setPositiveButton(
        getString(R.string.add_contact),
        new DialogInterface.OnClickListener() {

          @Override
          public void onClick(DialogInterface dialog, int which) {
            final Jid jid = contact.getJid();
            Account account = contact.getAccount();
            Contact contact = account.getRoster().getContact(jid);
            xmppConnectionService.createContact(contact);
          }
        });
    builder.create().show();
  }
  private void showAskForPresenceDialog(final Contact contact) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(contact.getJid().toString());
    builder.setMessage(R.string.request_presence_updates);
    builder.setNegativeButton(R.string.cancel, null);
    builder.setPositiveButton(
        R.string.request_now,
        new DialogInterface.OnClickListener() {

          @Override
          public void onClick(DialogInterface dialog, int which) {
            if (xmppConnectionServiceBound) {
              xmppConnectionService.sendPresencePacket(
                  contact.getAccount(),
                  xmppConnectionService.getPresenceGenerator().requestPresenceUpdatesFrom(contact));
            }
          }
        });
    builder.create().show();
  }
  public void parseContactPresence(final PresencePacket packet, final Account account) {
    final PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator();
    final Jid from = packet.getFrom();
    if (from == null) {
      return;
    }
    final String type = packet.getAttribute("type");
    final Contact contact = account.getRoster().getContact(from);
    if (type == null) {
      final String resource = from.isBareJid() ? "" : from.getResourcepart();
      contact.setPresenceName(packet.findChildContent("nick", "http://jabber.org/protocol/nick"));
      Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update"));
      if (avatar != null && !contact.isSelf()) {
        avatar.owner = from.toBareJid();
        if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
          if (contact.setAvatar(avatar)) {
            mXmppConnectionService.getAvatarService().clear(contact);
            mXmppConnectionService.updateConversationUi();
            mXmppConnectionService.updateRosterUi();
          }
        } else {
          mXmppConnectionService.fetchAvatar(account, avatar);
        }
      }
      int sizeBefore = contact.getPresences().size();

      final Element show = packet.findChild("show");
      final Element caps = packet.findChild("c", "http://jabber.org/protocol/caps");
      final Presence presence = Presence.parse(show, caps);
      contact.updatePresence(resource, presence);
      if (presence.hasCaps() && Config.REQUEST_DISCO) {
        mXmppConnectionService.fetchCaps(account, from, presence);
      }

      PgpEngine pgp = mXmppConnectionService.getPgpEngine();
      Element x = packet.findChild("x", "jabber:x:signed");
      if (pgp != null && x != null) {
        Element status = packet.findChild("status");
        String msg = status != null ? status.getContent() : "";
        contact.setPgpKeyId(pgp.fetchKeyId(account, msg, x.getContent()));
      }
      boolean online = sizeBefore < contact.getPresences().size();
      updateLastseen(packet, account, false);
      mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, online);
    } else if (type.equals("unavailable")) {
      if (from.isBareJid()) {
        contact.clearPresences();
      } else {
        contact.removePresence(from.getResourcepart());
      }
      mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, false);
    } else if (type.equals("subscribe")) {
      if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
        mXmppConnectionService.sendPresencePacket(
            account, mPresenceGenerator.sendPresenceUpdatesTo(contact));
      } else {
        contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST);
        final Conversation conversation =
            mXmppConnectionService.findOrCreateConversation(
                account, contact.getJid().toBareJid(), false);
        final String statusMessage = packet.findChildContent("status");
        if (statusMessage != null
            && !statusMessage.isEmpty()
            && conversation.countMessages() == 0) {
          conversation.add(
              new Message(
                  conversation, statusMessage, Message.ENCRYPTION_NONE, Message.STATUS_RECEIVED));
        }
      }
    }
    mXmppConnectionService.updateRosterUi();
  }
  private void populateView() {
    mAccountJid.setText(getString(R.string.using_account, conversation.getAccount().getJid()));
    mYourPhoto.setImageBitmap(avatarService().get(conversation.getAccount(), getPixel(48)));
    setTitle(conversation.getName());
    mFullJid.setText(conversation.getContactJid().split("/", 2)[0]);
    mYourNick.setText(conversation.getMucOptions().getActualNick());
    mRoleAffiliaton = (TextView) findViewById(R.id.muc_role);
    if (conversation.getMucOptions().online()) {
      mMoreDetails.setVisibility(View.VISIBLE);
      User self = conversation.getMucOptions().getSelf();
      switch (self.getAffiliation()) {
        case User.AFFILIATION_ADMIN:
          mRoleAffiliaton.setText(
              getReadableRole(self.getRole()) + " (" + getString(R.string.admin) + ")");
          break;
        case User.AFFILIATION_OWNER:
          mRoleAffiliaton.setText(
              getReadableRole(self.getRole()) + " (" + getString(R.string.owner) + ")");
          break;
        default:
          mRoleAffiliaton.setText(getReadableRole(self.getRole()));
          break;
      }
    }
    this.users.clear();
    this.users.addAll(conversation.getMucOptions().getUsers());
    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    membersView.removeAllViews();
    for (final User user : conversation.getMucOptions().getUsers()) {
      View view = inflater.inflate(R.layout.contact, membersView, false);
      TextView name = (TextView) view.findViewById(R.id.contact_display_name);
      TextView key = (TextView) view.findViewById(R.id.key);
      TextView role = (TextView) view.findViewById(R.id.contact_jid);
      if (user.getPgpKeyId() != 0) {
        key.setVisibility(View.VISIBLE);
        key.setOnClickListener(
            new OnClickListener() {

              @Override
              public void onClick(View v) {
                viewPgpKey(user);
              }
            });
        key.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId()));
      }
      Bitmap bm;
      Contact contact = user.getContact();
      if (contact != null) {
        bm = avatarService().get(contact, getPixel(48));
        name.setText(contact.getDisplayName());
        role.setText(user.getName() + " \u2022 " + getReadableRole(user.getRole()));
      } else {
        bm = avatarService().get(user.getName(), getPixel(48));
        name.setText(user.getName());
        role.setText(getReadableRole(user.getRole()));
      }
      ImageView iv = (ImageView) view.findViewById(R.id.contact_photo);
      iv.setImageBitmap(bm);
      membersView.addView(view);
    }
  }
  @Override
  public void onMessagePacketReceived(Account account, MessagePacket original) {
    if (handleErrorMessage(account, original)) {
      return;
    }
    final MessagePacket packet;
    Long timestamp = null;
    final boolean isForwarded;
    boolean isCarbon = false;
    String serverMsgId = null;
    final Element fin = original.findChild("fin", "urn:xmpp:mam:0");
    if (fin != null) {
      mXmppConnectionService.getMessageArchiveService().processFin(fin, original.getFrom());
      return;
    }
    final Element result = original.findChild("result", "urn:xmpp:mam:0");
    final MessageArchiveService.Query query =
        result == null
            ? null
            : mXmppConnectionService
                .getMessageArchiveService()
                .findQuery(result.getAttribute("queryid"));
    if (query != null && query.validFrom(original.getFrom())) {
      Pair<MessagePacket, Long> f = original.getForwardedMessagePacket("result", "urn:xmpp:mam:0");
      if (f == null) {
        return;
      }
      timestamp = f.second;
      packet = f.first;
      isForwarded = true;
      serverMsgId = result.getAttribute("id");
      query.incrementTotalCount();
    } else if (query != null) {
      Log.d(
          Config.LOGTAG,
          account.getJid().toBareJid() + ": received mam result from invalid sender");
      return;
    } else if (original.fromServer(account)) {
      Pair<MessagePacket, Long> f;
      f = original.getForwardedMessagePacket("received", "urn:xmpp:carbons:2");
      f = f == null ? original.getForwardedMessagePacket("sent", "urn:xmpp:carbons:2") : f;
      packet = f != null ? f.first : original;
      if (handleErrorMessage(account, packet)) {
        return;
      }
      timestamp = f != null ? f.second : null;
      isCarbon = f != null;
      isForwarded = isCarbon;
    } else {
      packet = original;
      isForwarded = false;
    }

    if (timestamp == null) {
      timestamp = AbstractParser.getTimestamp(packet, System.currentTimeMillis());
    }
    final String body = packet.getBody();
    final Element mucUserElement = packet.findChild("x", "http://jabber.org/protocol/muc#user");
    final String pgpEncrypted = packet.findChildContent("x", "jabber:x:encrypted");
    final Element axolotlEncrypted =
        packet.findChild(XmppAxolotlMessage.CONTAINERTAG, AxolotlService.PEP_PREFIX);
    int status;
    final Jid counterpart;
    final Jid to = packet.getTo();
    final Jid from = packet.getFrom();
    final String remoteMsgId = packet.getId();

    if (from == null || to == null) {
      Log.d(Config.LOGTAG, "no to or from in: " + packet.toString());
      return;
    }

    boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT;
    boolean isProperlyAddressed = !to.isBareJid() || account.countPresences() == 1;
    boolean isMucStatusMessage =
        from.isBareJid() && mucUserElement != null && mucUserElement.hasChild("status");
    if (packet.fromAccount(account)) {
      status = Message.STATUS_SEND;
      counterpart = to;
    } else {
      status = Message.STATUS_RECEIVED;
      counterpart = from;
    }

    Invite invite = extractInvite(packet);
    if (invite != null && invite.execute(account)) {
      return;
    }

    if (extractChatState(mXmppConnectionService.find(account, counterpart.toBareJid()), packet)) {
      mXmppConnectionService.updateConversationUi();
    }

    if ((body != null || pgpEncrypted != null || axolotlEncrypted != null) && !isMucStatusMessage) {
      Conversation conversation =
          mXmppConnectionService.findOrCreateConversation(
              account, counterpart.toBareJid(), isTypeGroupChat, query);
      if (isTypeGroupChat) {
        if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) {
          status = Message.STATUS_SEND_RECEIVED;
          if (mXmppConnectionService.markMessage(conversation, remoteMsgId, status)) {
            return;
          } else if (remoteMsgId == null || Config.IGNORE_ID_REWRITE_IN_MUC) {
            Message message = conversation.findSentMessageWithBody(packet.getBody());
            if (message != null) {
              mXmppConnectionService.markMessage(message, status);
              return;
            }
          }
        } else {
          status = Message.STATUS_RECEIVED;
        }
      }
      Message message;
      if (body != null && body.startsWith("?OTR")) {
        if (!isForwarded && !isTypeGroupChat && isProperlyAddressed) {
          message = parseOtrChat(body, from, remoteMsgId, conversation);
          if (message == null) {
            return;
          }
        } else {
          message = new Message(conversation, body, Message.ENCRYPTION_NONE, status);
        }
      } else if (pgpEncrypted != null) {
        message = parsePGPChat(conversation, pgpEncrypted, status);
      } else if (axolotlEncrypted != null) {
        message = parseAxolotlChat(axolotlEncrypted, from, remoteMsgId, conversation, status);
        if (message == null) {
          return;
        }
      } else {
        message = new Message(conversation, body, Message.ENCRYPTION_NONE, status);
      }

      if (serverMsgId == null) {
        serverMsgId =
            extractStanzaId(
                packet, isTypeGroupChat ? conversation.getJid().toBareJid() : account.getServer());
      }

      message.setCounterpart(counterpart);
      message.setRemoteMsgId(remoteMsgId);
      message.setServerMsgId(serverMsgId);
      message.setCarbon(isCarbon);
      message.setTime(timestamp);
      message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0");
      if (conversation.getMode() == Conversation.MODE_MULTI) {
        Jid trueCounterpart =
            conversation.getMucOptions().getTrueCounterpart(counterpart.getResourcepart());
        message.setTrueCounterpart(trueCounterpart);
        if (trueCounterpart != null) {
          updateLastseen(packet, account, trueCounterpart, false);
        }
        if (!isTypeGroupChat) {
          message.setType(Message.TYPE_PRIVATE);
        }
      }
      updateLastseen(packet, account, true);
      boolean checkForDuplicates =
          query != null
              || (isTypeGroupChat && packet.hasChild("delay", "urn:xmpp:delay"))
              || message.getType() == Message.TYPE_PRIVATE;
      if (checkForDuplicates && conversation.hasDuplicateMessage(message)) {
        Log.d(
            Config.LOGTAG,
            "skipping duplicate message from "
                + message.getCounterpart().toString()
                + " "
                + message.getBody());
        return;
      }

      conversation.add(message);

      if (query == null || query.getWith() == null) { // either no mam or catchup
        if (status == Message.STATUS_SEND || status == Message.STATUS_SEND_RECEIVED) {
          mXmppConnectionService.markRead(conversation);
          if (query == null) {
            account.activateGracePeriod();
          }
        } else {
          message.markUnread();
        }
      }

      if (query != null) {
        query.incrementMessageCount();
      } else {
        mXmppConnectionService.updateConversationUi();
      }

      if (mXmppConnectionService.confirmMessages()
          && remoteMsgId != null
          && !isForwarded
          && !isTypeGroupChat) {
        ArrayList<String> receiptsNamespaces = new ArrayList<>();
        if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) {
          receiptsNamespaces.add("urn:xmpp:chat-markers:0");
        }
        if (packet.hasChild("request", "urn:xmpp:receipts")) {
          receiptsNamespaces.add("urn:xmpp:receipts");
        }
        if (receiptsNamespaces.size() > 0) {
          MessagePacket receipt =
              mXmppConnectionService
                  .getMessageGenerator()
                  .received(account, packet, receiptsNamespaces, packet.getType());
          mXmppConnectionService.sendMessagePacket(account, receipt);
        }
      }

      if (message.getStatus() == Message.STATUS_RECEIVED
          && conversation.getOtrSession() != null
          && !conversation
              .getOtrSession()
              .getSessionID()
              .getUserID()
              .equals(message.getCounterpart().getResourcepart())) {
        conversation.endOtrIfNeeded();
      }

      if (message.getEncryption() == Message.ENCRYPTION_NONE
          || mXmppConnectionService.saveEncryptedMessages()) {
        mXmppConnectionService.databaseBackend.createMessage(message);
      }
      final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager();
      if (message.trusted()
          && message.treatAsDownloadable() != Message.Decision.NEVER
          && manager.getAutoAcceptFileSize() > 0) {
        manager.createNewDownloadConnection(message);
      } else if (!message.isRead()) {
        if (query == null) {
          mXmppConnectionService.getNotificationService().push(message);
        } else if (query.getWith() == null) { // mam catchup
          mXmppConnectionService.getNotificationService().pushFromBacklog(message);
        }
      }
    } else { // no body
      if (isTypeGroupChat) {
        Conversation conversation = mXmppConnectionService.find(account, from.toBareJid());
        if (packet.hasChild("subject")) {
          if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) {
            conversation.setHasMessagesLeftOnServer(conversation.countMessages() > 0);
            String subject = packet.findChildContent("subject");
            conversation.getMucOptions().setSubject(subject);
            final Bookmark bookmark = conversation.getBookmark();
            if (bookmark != null && bookmark.getBookmarkName() == null) {
              if (bookmark.setBookmarkName(subject)) {
                mXmppConnectionService.pushBookmarks(account);
              }
            }
            mXmppConnectionService.updateConversationUi();
            return;
          }
        }

        if (conversation != null && isMucStatusMessage) {
          for (Element child : mucUserElement.getChildren()) {
            if (child.getName().equals("status")
                && MucOptions.STATUS_CODE_ROOM_CONFIG_CHANGED.equals(child.getAttribute("code"))) {
              mXmppConnectionService.fetchConferenceConfiguration(conversation);
            }
          }
        }
      }
    }

    Element received = packet.findChild("received", "urn:xmpp:chat-markers:0");
    if (received == null) {
      received = packet.findChild("received", "urn:xmpp:receipts");
    }
    if (received != null && !packet.fromAccount(account)) {
      mXmppConnectionService.markMessage(
          account, from.toBareJid(), received.getAttribute("id"), Message.STATUS_SEND_RECEIVED);
    }
    Element displayed = packet.findChild("displayed", "urn:xmpp:chat-markers:0");
    if (displayed != null) {
      if (packet.fromAccount(account)) {
        Conversation conversation = mXmppConnectionService.find(account, counterpart.toBareJid());
        if (conversation != null) {
          mXmppConnectionService.markRead(conversation);
        }
      } else {
        updateLastseen(packet, account, true);
        final Message displayedMessage =
            mXmppConnectionService.markMessage(
                account,
                from.toBareJid(),
                displayed.getAttribute("id"),
                Message.STATUS_SEND_DISPLAYED);
        Message message = displayedMessage == null ? null : displayedMessage.prev();
        while (message != null
            && message.getStatus() == Message.STATUS_SEND_RECEIVED
            && message.getTimeSent() < displayedMessage.getTimeSent()) {
          mXmppConnectionService.markMessage(message, Message.STATUS_SEND_DISPLAYED);
          message = message.prev();
        }
      }
    }

    Element event = packet.findChild("event", "http://jabber.org/protocol/pubsub#event");
    if (event != null) {
      parseEvent(event, from, account);
    }

    String nick = packet.findChildContent("nick", "http://jabber.org/protocol/nick");
    if (nick != null) {
      Contact contact = account.getRoster().getContact(from);
      contact.setPresenceName(nick);
    }
  }
 private boolean hasAny(Contact contact) {
   AxolotlAddress contactAddress = getAddressForJid(contact.getJid());
   return sessions.hasAny(contactAddress);
 }
 private Set<XmppAxolotlSession> findSessionsforContact(Contact contact) {
   AxolotlAddress contactAddress = getAddressForJid(contact.getJid());
   Set<XmppAxolotlSession> sessions = new HashSet<>(this.sessions.getAll(contactAddress).values());
   return sessions;
 }
 public long getNumTrustedKeys(Contact contact) {
   return axolotlStore.getContactNumTrustedKeys(contact.getJid().toBareJid().toString());
 }
 public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust, Contact contact) {
   return axolotlStore.getContactKeysWithTrust(contact.getJid().toBareJid().toString(), trust);
 }
  public void selectPresence(final Conversation conversation, final OnPresenceSelected listener) {
    final Contact contact = conversation.getContact();
    if (conversation.hasValidOtrSession()) {
      SessionID id = conversation.getOtrSession().getSessionID();
      Jid jid;
      try {
        jid = Jid.fromString(id.getAccountID() + "/" + id.getUserID());
      } catch (InvalidJidException e) {
        jid = null;
      }
      conversation.setNextCounterpart(jid);
      listener.onPresenceSelected();
    } else if (!contact.showInRoster()) {
      showAddToRosterDialog(conversation);
    } else {
      Presences presences = contact.getPresences();
      if (presences.size() == 0) {
        if (!contact.getOption(Contact.Options.TO)
            && !contact.getOption(Contact.Options.ASKING)
            && contact.getAccount().getStatus() == Account.State.ONLINE) {
          showAskForPresenceDialog(contact);
        } else if (!contact.getOption(Contact.Options.TO)
            || !contact.getOption(Contact.Options.FROM)) {
          warnMutalPresenceSubscription(conversation, listener);
        } else {
          conversation.setNextCounterpart(null);
          listener.onPresenceSelected();
        }
      } else if (presences.size() == 1) {
        String presence = presences.asStringArray()[0];
        try {
          conversation.setNextCounterpart(
              Jid.fromParts(
                  contact.getJid().getLocalpart(), contact.getJid().getDomainpart(), presence));
        } catch (InvalidJidException e) {
          conversation.setNextCounterpart(null);
        }
        listener.onPresenceSelected();
      } else {
        final StringBuilder presence = new StringBuilder();
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(getString(R.string.choose_presence));
        final String[] presencesArray = presences.asStringArray();
        int preselectedPresence = 0;
        for (int i = 0; i < presencesArray.length; ++i) {
          if (presencesArray[i].equals(contact.lastseen.presence)) {
            preselectedPresence = i;
            break;
          }
        }
        presence.append(presencesArray[preselectedPresence]);
        builder.setSingleChoiceItems(
            presencesArray,
            preselectedPresence,
            new DialogInterface.OnClickListener() {

              @Override
              public void onClick(DialogInterface dialog, int which) {
                presence.delete(0, presence.length());
                presence.append(presencesArray[which]);
              }
            });
        builder.setNegativeButton(R.string.cancel, null);
        builder.setPositiveButton(
            R.string.ok,
            new OnClickListener() {

              @Override
              public void onClick(DialogInterface dialog, int which) {
                try {
                  conversation.setNextCounterpart(
                      Jid.fromParts(
                          contact.getJid().getLocalpart(),
                          contact.getJid().getDomainpart(),
                          presence.toString()));
                } catch (InvalidJidException e) {
                  conversation.setNextCounterpart(null);
                }
                listener.onPresenceSelected();
              }
            });
        builder.create().show();
      }
    }
  }
  protected void sendPgpMessage(final Message message) {
    final ConversationActivity activity = (ConversationActivity) getActivity();
    final XmppConnectionService xmppService = activity.xmppConnectionService;
    final Contact contact = message.getConversation().getContact();
    if (activity.hasPgp()) {
      if (conversation.getMode() == Conversation.MODE_SINGLE) {
        if (contact.getPgpKeyId() != 0) {
          xmppService
              .getPgpEngine()
              .hasKey(
                  contact,
                  new UiCallback<Contact>() {

                    @Override
                    public void userInputRequried(PendingIntent pi, Contact contact) {
                      activity.runIntent(pi, ConversationActivity.REQUEST_ENCRYPT_MESSAGE);
                    }

                    @Override
                    public void success(Contact contact) {
                      messageSent();
                      activity.encryptTextMessage(message);
                    }

                    @Override
                    public void error(int error, Contact contact) {}
                  });

        } else {
          showNoPGPKeyDialog(
              false,
              new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                  conversation.setNextEncryption(Message.ENCRYPTION_NONE);
                  xmppService.databaseBackend.updateConversation(conversation);
                  message.setEncryption(Message.ENCRYPTION_NONE);
                  xmppService.sendMessage(message);
                  messageSent();
                }
              });
        }
      } else {
        if (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();
          }
          activity.encryptTextMessage(message);
          messageSent();
        } else {
          showNoPGPKeyDialog(
              true,
              new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                  conversation.setNextEncryption(Message.ENCRYPTION_NONE);
                  message.setEncryption(Message.ENCRYPTION_NONE);
                  xmppService.databaseBackend.updateConversation(conversation);
                  xmppService.sendMessage(message);
                  messageSent();
                }
              });
        }
      }
    } else {
      activity.showInstallPgpDialog();
    }
  }