コード例 #1
0
 public void updateMessages() {
   synchronized (this.messageList) {
     if (getView() == null) {
       return;
     }
     final ConversationActivity activity = (ConversationActivity) getActivity();
     if (this.conversation != null) {
       updateSnackBar(this.conversation);
       conversation.populateWithMessages(ConversationFragment.this.messageList);
       for (final Message message : this.messageList) {
         if (message.getEncryption() == Message.ENCRYPTION_PGP
             && (message.getStatus() == Message.STATUS_RECEIVED
                 || message.getStatus() >= Message.STATUS_SEND)
             && message.getTransferable() == null) {
           if (!mEncryptedMessages.contains(message)) {
             mEncryptedMessages.add(message);
           }
         }
       }
       decryptNext();
       updateStatusMessages();
       this.messageListAdapter.notifyDataSetChanged();
       updateChatMsgHint();
       if (!activity.isConversationsOverviewVisable()
           || !activity.isConversationsOverviewHideable()) {
         activity.sendReadMarkerIfNecessary(conversation);
       }
       this.updateSendButton();
     }
   }
 }
コード例 #2
0
 public void findUnsentMessagesWithEncryption(int encryptionType, OnMessageFound onMessageFound) {
   synchronized (this.messages) {
     for (Message message : this.messages) {
       if ((message.getStatus() == Message.STATUS_UNSEND
               || message.getStatus() == Message.STATUS_WAITING)
           && (message.getEncryption() == encryptionType)) {
         onMessageFound.onMessageFound(message);
       }
     }
   }
 }
コード例 #3
0
 private void populateContextMenu(ContextMenu menu) {
   final Message m = this.selectedMessage;
   if (m.getType() != Message.TYPE_STATUS) {
     activity.getMenuInflater().inflate(R.menu.message_context, menu);
     menu.setHeaderTitle(R.string.message_options);
     MenuItem copyText = menu.findItem(R.id.copy_text);
     MenuItem shareWith = menu.findItem(R.id.share_with);
     MenuItem sendAgain = menu.findItem(R.id.send_again);
     MenuItem copyUrl = menu.findItem(R.id.copy_url);
     MenuItem downloadFile = menu.findItem(R.id.download_file);
     MenuItem cancelTransmission = menu.findItem(R.id.cancel_transmission);
     if ((m.getType() == Message.TYPE_TEXT || m.getType() == Message.TYPE_PRIVATE)
         && m.getTransferable() == null
         && !GeoHelper.isGeoUri(m.getBody())
         && m.treatAsDownloadable() != Message.Decision.MUST) {
       copyText.setVisible(true);
     }
     if ((m.getType() != Message.TYPE_TEXT
             && m.getType() != Message.TYPE_PRIVATE
             && m.getTransferable() == null)
         || (GeoHelper.isGeoUri(m.getBody()))) {
       shareWith.setVisible(true);
     }
     if (m.getStatus() == Message.STATUS_SEND_FAILED) {
       sendAgain.setVisible(true);
     }
     if (m.hasFileOnRemoteHost()
         || GeoHelper.isGeoUri(m.getBody())
         || m.treatAsDownloadable() == Message.Decision.MUST) {
       copyUrl.setVisible(true);
     }
     if (m.getType() == Message.TYPE_TEXT
         && m.getTransferable() == null
         && m.treatAsDownloadable() != Message.Decision.NEVER) {
       downloadFile.setVisible(true);
       downloadFile.setTitle(
           activity.getString(
               R.string.download_x_file, UIHelper.getFileDescriptionString(activity, m)));
     }
     if ((m.getTransferable() != null && !(m.getTransferable() instanceof TransferablePlaceholder))
         || (m.isFileOrImage()
             && (m.getStatus() == Message.STATUS_WAITING
                 || m.getStatus() == Message.STATUS_OFFERED))) {
       cancelTransmission.setVisible(true);
     }
   }
 }
コード例 #4
0
 public void findWaitingMessages(OnMessageFound onMessageFound) {
   synchronized (this.messages) {
     for (Message message : this.messages) {
       if (message.getStatus() == Message.STATUS_WAITING) {
         onMessageFound.onMessageFound(message);
       }
     }
   }
 }
コード例 #5
0
 public void findUnsentTextMessages(OnMessageFound onMessageFound) {
   synchronized (this.messages) {
     for (Message message : this.messages) {
       if (message.getType() != Message.TYPE_IMAGE
           && message.getStatus() == Message.STATUS_UNSEND) {
         onMessageFound.onMessageFound(message);
       }
     }
   }
 }
コード例 #6
0
 public Message findSentMessageWithBody(String body) {
   synchronized (this.messages) {
     for (int i = this.messages.size() - 1; i >= 0; --i) {
       Message message = this.messages.get(i);
       if (message.getStatus() == Message.STATUS_UNSEND
           || message.getStatus() == Message.STATUS_SEND) {
         String otherBody;
         if (message.hasFileOnRemoteHost()) {
           otherBody = message.getFileParams().url.toString();
         } else {
           otherBody = message.body;
         }
         if (otherBody != null && otherBody.equals(body)) {
           return message;
         }
       }
     }
     return null;
   }
 }
コード例 #7
0
 public Message findUnsentMessageWithUuid(String uuid) {
   synchronized (this.messages) {
     for (final Message message : this.messages) {
       final int s = message.getStatus();
       if ((s == Message.STATUS_UNSEND || s == Message.STATUS_WAITING)
           && message.getUuid().equals(uuid)) {
         return message;
       }
     }
   }
   return null;
 }
コード例 #8
0
 public Message findSentMessageWithUuidOrRemoteId(String id) {
   synchronized (this.messages) {
     for (Message message : this.messages) {
       if (id.equals(message.getUuid())
           || (message.getStatus() >= Message.STATUS_SEND
               && id.equals(message.getRemoteMsgId()))) {
         return message;
       }
     }
   }
   return null;
 }
コード例 #9
0
ファイル: UIHelper.java プロジェクト: kingslou/Conversations
 public static boolean receivedLocationQuestion(Message message) {
   if (message == null
       || message.getStatus() != Message.STATUS_RECEIVED
       || message.getType() != Message.TYPE_TEXT) {
     return false;
   }
   String body =
       message.getBody() == null
           ? null
           : message.getBody().trim().toLowerCase(Locale.getDefault());
   body = body.replace("?", "").replace("¿", "");
   return LOCATION_QUESTIONS.contains(body);
 }
コード例 #10
0
 public long getLastMessageTransmitted() {
   long last_clear = getLastClearHistory();
   if (last_clear != 0) {
     return last_clear;
   }
   synchronized (this.messages) {
     for (int i = this.messages.size() - 1; i >= 0; --i) {
       Message message = this.messages.get(i);
       if (message.getStatus() == Message.STATUS_RECEIVED || message.isCarbon()) {
         return message.getTimeSent();
       }
     }
   }
   return 0;
 }
コード例 #11
0
 private int getMostRecentlyUsedIncomingEncryption() {
   synchronized (this.messages) {
     for (int i = this.messages.size() - 1; i >= 0; --i) {
       final Message m = this.messages.get(i);
       if (m.getStatus() == Message.STATUS_RECEIVED) {
         final int e = m.getEncryption();
         if (e == Message.ENCRYPTION_DECRYPTED || e == Message.ENCRYPTION_DECRYPTION_FAILED) {
           return Message.ENCRYPTION_PGP;
         } else {
           return e;
         }
       }
     }
   }
   return Message.ENCRYPTION_NONE;
 }
コード例 #12
0
ファイル: UIHelper.java プロジェクト: kingslou/Conversations
 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();
     }
   }
 }
コード例 #13
0
ファイル: UIHelper.java プロジェクト: kingslou/Conversations
 public static Pair<String, Boolean> getMessagePreview(
     final Context context, final Message message) {
   final Transferable d = message.getTransferable();
   if (d != null) {
     switch (d.getStatus()) {
       case Transferable.STATUS_CHECKING:
         return new Pair<>(
             context.getString(R.string.checking_x, getFileDescriptionString(context, message)),
             true);
       case Transferable.STATUS_DOWNLOADING:
         return new Pair<>(
             context.getString(
                 R.string.receiving_x_file,
                 getFileDescriptionString(context, message),
                 d.getProgress()),
             true);
       case Transferable.STATUS_OFFER:
       case Transferable.STATUS_OFFER_CHECK_FILESIZE:
         return new Pair<>(
             context.getString(
                 R.string.x_file_offered_for_download, getFileDescriptionString(context, message)),
             true);
       case Transferable.STATUS_DELETED:
         return new Pair<>(context.getString(R.string.file_deleted), true);
       case Transferable.STATUS_FAILED:
         return new Pair<>(context.getString(R.string.file_transmission_failed), true);
       case Transferable.STATUS_UPLOADING:
         if (message.getStatus() == Message.STATUS_OFFERED) {
           return new Pair<>(
               context.getString(
                   R.string.offering_x_file, getFileDescriptionString(context, message)),
               true);
         } else {
           return new Pair<>(
               context.getString(
                   R.string.sending_x_file, getFileDescriptionString(context, message)),
               true);
         }
       default:
         return new Pair<>("", false);
     }
   } else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
     return new Pair<>(context.getString(R.string.encrypted_message_received), true);
   } else if (message.getType() == Message.TYPE_FILE || message.getType() == Message.TYPE_IMAGE) {
     if (message.getStatus() == Message.STATUS_RECEIVED) {
       return new Pair<>(
           context.getString(R.string.received_x_file, getFileDescriptionString(context, message)),
           true);
     } else {
       return new Pair<>(getFileDescriptionString(context, message), true);
     }
   } else {
     if (message.getBody().startsWith(Message.ME_COMMAND)) {
       return new Pair<>(
           message
               .getBody()
               .replaceAll(
                   "^" + Message.ME_COMMAND, UIHelper.getMessageDisplayName(message) + " "),
           false);
     } else if (GeoHelper.isGeoUri(message.getBody())) {
       if (message.getStatus() == Message.STATUS_RECEIVED) {
         return new Pair<>(context.getString(R.string.received_location), true);
       } else {
         return new Pair<>(context.getString(R.string.location), true);
       }
     } else {
       return new Pair<>(message.getBody().trim(), false);
     }
   }
 }
コード例 #14
0
  @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);
    }
  }