private Pair<Long, Long> insertSyncMediaMessage( MasterSecret masterSecret, TextSecureEnvelope envelope, TextSecureMessage message) throws MmsException { MmsDatabase database = DatabaseFactory.getMmsDatabase(context); TextSecureSyncContext syncContext = message.getSyncContext().get(); Recipients recipients = getSyncMessageDestination(message); OutgoingMediaMessage mediaMessage = new OutgoingMediaMessage( context, masterSecret, recipients, message.getAttachments().get(), message.getBody().orNull()); mediaMessage = new OutgoingSecureMediaMessage(mediaMessage); long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients); long messageId = database.insertMessageOutbox( masterSecret, mediaMessage, threadId, false, syncContext.getTimestamp()); database.markAsSent(messageId, "push".getBytes(), 0); database.markAsPush(messageId); return new Pair<>(messageId, threadId); }
private Pair<Long, Long> insertSyncTextMessage( MasterSecret masterSecret, TextSecureEnvelope envelope, TextSecureMessage message, Optional<Long> smsMessageId) { EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context); Recipients recipients = getSyncMessageDestination(message); String body = message.getBody().or(""); OutgoingTextMessage outgoingTextMessage = new OutgoingTextMessage(recipients, body); long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients); long messageId = database.insertMessageOutbox( masterSecret, threadId, outgoingTextMessage, false, message.getSyncContext().get().getTimestamp()); database.markAsSent(messageId); database.markAsPush(messageId); database.markAsSecure(messageId); if (smsMessageId.isPresent()) { database.deleteMessage(smsMessageId.get()); } return new Pair<>(messageId, threadId); }
private void handleUntrustedIdentityMessage( MasterSecret masterSecret, TextSecureEnvelope envelope, Optional<Long> smsMessageId) { try { EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context); Recipients recipients = RecipientFactory.getRecipientsFromString(context, envelope.getSource(), false); long recipientId = recipients.getPrimaryRecipient().getRecipientId(); PreKeyWhisperMessage whisperMessage = new PreKeyWhisperMessage(envelope.getMessage()); IdentityKey identityKey = whisperMessage.getIdentityKey(); String encoded = Base64.encodeBytes(envelope.getMessage()); IncomingTextMessage textMessage = new IncomingTextMessage( envelope.getSource(), envelope.getSourceDevice(), envelope.getTimestamp(), encoded, Optional.<TextSecureGroup>absent()); if (!smsMessageId.isPresent()) { IncomingPreKeyBundleMessage bundleMessage = new IncomingPreKeyBundleMessage(textMessage, encoded); Pair<Long, Long> messageAndThreadId = database.insertMessageInbox(masterSecret, bundleMessage); database.setMismatchedIdentity(messageAndThreadId.first, recipientId, identityKey); MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second); } else { database.updateMessageBody(masterSecret, smsMessageId.get(), encoded); database.markAsPreKeyBundle(smsMessageId.get()); database.setMismatchedIdentity(smsMessageId.get(), recipientId, identityKey); } } catch (InvalidMessageException | InvalidVersionException e) { throw new AssertionError(e); } }
private void handleEndSessionMessage( MasterSecret masterSecret, TextSecureEnvelope envelope, TextSecureMessage message, Optional<Long> smsMessageId) { EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context); IncomingTextMessage incomingTextMessage = new IncomingTextMessage( envelope.getSource(), envelope.getSourceDevice(), message.getTimestamp(), "", Optional.<TextSecureGroup>absent()); long threadId; if (!smsMessageId.isPresent()) { IncomingEndSessionMessage incomingEndSessionMessage = new IncomingEndSessionMessage(incomingTextMessage); Pair<Long, Long> messageAndThreadId = smsDatabase.insertMessageInbox(masterSecret, incomingEndSessionMessage); threadId = messageAndThreadId.second; } else { smsDatabase.markAsEndSession(smsMessageId.get()); threadId = smsDatabase.getThreadIdForMessage(smsMessageId.get()); } SessionStore sessionStore = new TextSecureSessionStore(context, masterSecret); sessionStore.deleteAllSessions(envelope.getSource()); SecurityEvent.broadcastSecurityUpdateEvent(context, threadId); MessageNotifier.updateNotification(context, masterSecret, threadId); }
private void markFailed(long messageId, PduPart part, PartDatabase.PartId partId) { try { PartDatabase database = DatabaseFactory.getPartDatabase(context); database.updateFailedDownloadedPart(messageId, partId, part); } catch (MmsException e) { Log.w(TAG, e); } }
@Override public void onCanceled() { PartDatabase database = DatabaseFactory.getPartDatabase(context); List<PduPart> parts = database.getParts(messageId); for (PduPart part : parts) { markFailed(messageId, part, part.getPartId()); } }
@Override public void onRun(MasterSecret masterSecret) throws NoSuchMessageException { PushDatabase database = DatabaseFactory.getPushDatabase(context); TextSecureEnvelope envelope = database.get(messageId); Optional<Long> optionalSmsMessageId = smsMessageId > 0 ? Optional.of(smsMessageId) : Optional.<Long>absent(); handleMessage(masterSecret, envelope, optionalSmsMessageId); database.delete(messageId); }
private void handleGroupMessage( MasterSecret masterSecret, TextSecureEnvelope envelope, TextSecureMessage message, Optional<Long> smsMessageId) { GroupMessageProcessor.process(context, masterSecret, envelope, message); if (smsMessageId.isPresent()) { DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get()); } }
private void handleLegacyMessage( MasterSecret masterSecret, TextSecureEnvelope envelope, Optional<Long> smsMessageId) { EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context); if (!smsMessageId.isPresent()) { Pair<Long, Long> messageAndThreadId = insertPlaceholder(masterSecret, envelope); smsDatabase.markAsLegacyVersion(messageAndThreadId.first); MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second); } else { smsDatabase.markAsLegacyVersion(smsMessageId.get()); } }
@Override public void onRun(MasterSecret masterSecret) throws IOException { PartDatabase database = DatabaseFactory.getPartDatabase(context); Log.w(TAG, "Downloading push parts for: " + messageId); List<PduPart> parts = database.getParts(messageId); for (PduPart part : parts) { retrievePart(masterSecret, part, messageId); Log.w(TAG, "Got part: " + part.getPartId()); } }
private Pair<Long, Recipients> handleCreatePushGroup( String groupName, byte[] avatar, Set<Recipient> members) throws InvalidNumberException, MmsException { GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(this); byte[] groupId = groupDatabase.allocateGroupId(); Set<String> memberE164Numbers = getE164Numbers(members); memberE164Numbers.add(TextSecurePreferences.getLocalNumber(this)); groupDatabase.create(groupId, groupName, new LinkedList<String>(memberE164Numbers), null, null); groupDatabase.updateAvatar(groupId, avatar); return handlePushOperation(groupId, groupName, avatar, memberE164Numbers); }
private Pair<Long, Recipients> handleUpdatePushGroup( byte[] groupId, String groupName, byte[] avatar, Set<Recipient> members) throws InvalidNumberException, MmsException { GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(this); Set<String> memberE164Numbers = getE164Numbers(members); memberE164Numbers.add(TextSecurePreferences.getLocalNumber(this)); for (String number : memberE164Numbers) Log.w(TAG, "Updating: " + number); groupDatabase.updateMembers(groupId, new LinkedList<String>(memberE164Numbers)); groupDatabase.updateTitle(groupId, groupName); groupDatabase.updateAvatar(groupId, avatar); return handlePushOperation(groupId, groupName, avatar, memberE164Numbers); }
private Pair<Long, Long> insertPlaceholder( MasterSecret masterSecret, TextSecureEnvelope envelope) { EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context); IncomingTextMessage textMessage = new IncomingTextMessage( envelope.getSource(), envelope.getSourceDevice(), envelope.getTimestamp(), "", Optional.<TextSecureGroup>absent()); textMessage = new IncomingEncryptedMessage(textMessage, ""); return database.insertMessageInbox(masterSecret, textMessage); }
// TODO: build correct method logic here private Pair<Long, Long> insertSyncSMPMessage( MasterSecret masterSecret, TextSecureEnvelope envelope, TextSecureSMPMessage message) { EncryptingSMPDatabase database = DatabaseFactory.getEncryptingSMPDatabase(context); String body = message.getBody().isPresent() ? message.getBody().get() : ""; IncomingSMPMessage smpMessage = new IncomingSMPMessage( envelope.getSource(), envelope.getSourceDevice(), message.getTimestamp(), body, message.getGroupInfo()); smpMessage = new IncomingEncryptedSMPSyncMessage(smpMessage, body); return database.insertMessageInbox(masterSecret, smpMessage); }
private Pair<Long, Long> insertStandardMediaMessage( MasterSecret masterSecret, TextSecureEnvelope envelope, TextSecureMessage message) throws MmsException { MmsDatabase database = DatabaseFactory.getMmsDatabase(context); String localNumber = TextSecurePreferences.getLocalNumber(context); IncomingMediaMessage mediaMessage = new IncomingMediaMessage( masterSecret, envelope.getSource(), localNumber, message.getTimestamp(), Optional.fromNullable(envelope.getRelay()), message.getBody(), message.getGroupInfo(), message.getAttachments()); return database.insertSecureDecryptedMessageInbox(masterSecret, mediaMessage, -1); }
@Override protected Void doInBackground(Void... voids) { final GroupDatabase db = DatabaseFactory.getGroupDatabase(GroupCreateActivity.this); final Recipients recipients = db.getGroupMembers(groupId, false); if (recipients != null) { final List<Recipient> recipientList = recipients.getRecipientsList(); if (recipientList != null) { if (existingContacts == null) existingContacts = new HashSet<>(recipientList.size()); existingContacts.addAll(recipientList); } } GroupDatabase.GroupRecord group = db.getGroup(groupId); if (group != null) { existingTitle = group.getTitle(); final byte[] existingAvatar = group.getAvatar(); if (existingAvatar != null) { existingAvatarBmp = BitmapFactory.decodeByteArray(existingAvatar, 0, existingAvatar.length); } } return null; }
private void retrievePart(MasterSecret masterSecret, PduPart part, long messageId) throws IOException { PartDatabase database = DatabaseFactory.getPartDatabase(context); File attachmentFile = null; PartDatabase.PartId partId = part.getPartId(); try { attachmentFile = createTempFile(); TextSecureAttachmentPointer pointer = createAttachmentPointer(masterSecret, part); InputStream attachment = messageReceiver.retrieveAttachment(pointer, attachmentFile); database.updateDownloadedPart(masterSecret, messageId, partId, part, attachment); } catch (InvalidPartException | NonSuccessfulResponseCodeException | InvalidMessageException | MmsException e) { Log.w(TAG, e); markFailed(messageId, part, partId); } finally { if (attachmentFile != null) attachmentFile.delete(); } }
private void handleMediaMessage( MasterSecret masterSecret, TextSecureEnvelope envelope, TextSecureMessage message, Optional<Long> smsMessageId) throws MmsException { Pair<Long, Long> messageAndThreadId; if (message.getSyncContext().isPresent()) { messageAndThreadId = insertSyncMediaMessage(masterSecret, envelope, message); } else { messageAndThreadId = insertStandardMediaMessage(masterSecret, envelope, message); } ApplicationContext.getInstance(context) .getJobManager() .add(new AttachmentDownloadJob(context, messageAndThreadId.first)); if (smsMessageId.isPresent()) { DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get()); } MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second); }
private Pair<Long, Long> insertStandardTextMessage( MasterSecret masterSecret, TextSecureEnvelope envelope, TextSecureMessage message, Optional<Long> smsMessageId) { EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context); String body = message.getBody().isPresent() ? message.getBody().get() : ""; if (smsMessageId.isPresent()) { return database.updateBundleMessageBody(masterSecret, smsMessageId.get(), body); } else { IncomingTextMessage textMessage = new IncomingTextMessage( envelope.getSource(), envelope.getSourceDevice(), message.getTimestamp(), body, message.getGroupInfo()); textMessage = new IncomingEncryptedMessage(textMessage, body); return database.insertMessageInbox(masterSecret, textMessage); } }
private long handleCreateMmsGroup(Set<Recipient> members) { Recipients recipients = RecipientFactory.getRecipientsFor(this, new LinkedList<>(members), false); return DatabaseFactory.getThreadDatabase(this) .getThreadIdFor(recipients, ThreadDatabase.DistributionTypes.CONVERSATION); }