public OutgoingMediaMessage getOutgoingMessage(MasterSecret masterSecret, long messageId) throws MmsException, NoSuchMessageException { MmsAddressDatabase addr = DatabaseFactory.getMmsAddressDatabase(context); AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); Cursor cursor = null; try { cursor = rawQuery(RAW_ID_WHERE, new String[] {String.valueOf(messageId)}); if (cursor != null && cursor.moveToNext()) { long outboxType = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_BOX)); String messageText = cursor.getString(cursor.getColumnIndexOrThrow(BODY)); long timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(NORMALIZED_DATE_SENT)); List<Attachment> attachments = new LinkedList<Attachment>(attachmentDatabase.getAttachmentsForMessage(messageId)); MmsAddresses addresses = addr.getAddressesForId(messageId); List<String> destinations = new LinkedList<>(); String body = getDecryptedBody(masterSecret, messageText, outboxType); destinations.addAll(addresses.getBcc()); destinations.addAll(addresses.getCc()); destinations.addAll(addresses.getTo()); Recipients recipients = RecipientFactory.getRecipientsFromStrings(context, destinations, false); if (body != null && (Types.isGroupQuit(outboxType) || Types.isGroupUpdate(outboxType))) { return new OutgoingGroupMediaMessage(recipients, body, attachments, timestamp); } OutgoingMediaMessage message = new OutgoingMediaMessage( recipients, body, attachments, timestamp, !addresses.getBcc().isEmpty() ? ThreadDatabase.DistributionTypes.BROADCAST : ThreadDatabase.DistributionTypes.DEFAULT); if (Types.isSecureType(outboxType)) { return new OutgoingSecureMediaMessage(message); } return message; } throw new NoSuchMessageException("No record found for id: " + messageId); } catch (IOException e) { throw new MmsException(e); } finally { if (cursor != null) cursor.close(); } }
public long insertMessageOutbox( @NonNull MasterSecretUnion masterSecret, @NonNull OutgoingMediaMessage message, long threadId, boolean forceSms) throws MmsException { long type = Types.BASE_OUTBOX_TYPE; if (masterSecret.getMasterSecret().isPresent()) type |= Types.ENCRYPTION_SYMMETRIC_BIT; else type |= Types.ENCRYPTION_ASYMMETRIC_BIT; if (message.isSecure()) type |= Types.SECURE_MESSAGE_BIT; if (forceSms) type |= Types.MESSAGE_FORCE_SMS_BIT; if (message.isGroup()) { if (((OutgoingGroupMediaMessage) message).isGroupUpdate()) type |= Types.GROUP_UPDATE_BIT; else if (((OutgoingGroupMediaMessage) message).isGroupQuit()) type |= Types.GROUP_QUIT_BIT; } List<String> recipientNumbers = message.getRecipients().toNumberStringList(true); MmsAddresses addresses; if (!message.getRecipients().isSingleRecipient() && message.getDistributionType() == ThreadDatabase.DistributionTypes.BROADCAST) { addresses = MmsAddresses.forBcc(recipientNumbers); } else { addresses = MmsAddresses.forTo(recipientNumbers); } ContentValues contentValues = new ContentValues(); contentValues.put(DATE_SENT, message.getSentTimeMillis()); contentValues.put(MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_SEND_REQ); contentValues.put(MESSAGE_BOX, type); contentValues.put(THREAD_ID, threadId); contentValues.put(READ, 1); contentValues.put(DATE_RECEIVED, System.currentTimeMillis()); contentValues.remove(ADDRESS); long messageId = insertMediaMessage( masterSecret, addresses, message.getBody(), message.getAttachments(), contentValues); jobManager.add(new TrimThreadJob(context, threadId)); return messageId; }
public long copyMessageInbox(MasterSecret masterSecret, long messageId) throws MmsException { try { OutgoingMediaMessage request = getOutgoingMessage(masterSecret, messageId); ContentValues contentValues = new ContentValues(); contentValues.put(ADDRESS, request.getRecipients().getPrimaryRecipient().getNumber()); contentValues.put(DATE_SENT, request.getSentTimeMillis()); contentValues.put( MESSAGE_BOX, Types.BASE_INBOX_TYPE | Types.SECURE_MESSAGE_BIT | Types.ENCRYPTION_SYMMETRIC_BIT); contentValues.put(THREAD_ID, getThreadIdForMessage(messageId)); contentValues.put(READ, 1); contentValues.put(DATE_RECEIVED, contentValues.getAsLong(DATE_SENT)); List<Attachment> attachments = new LinkedList<>(); for (Attachment attachment : request.getAttachments()) { DatabaseAttachment databaseAttachment = (DatabaseAttachment) attachment; attachments.add( new DatabaseAttachment( databaseAttachment.getAttachmentId(), databaseAttachment.getMmsId(), databaseAttachment.hasData(), databaseAttachment.getContentType(), AttachmentDatabase.TRANSFER_PROGRESS_DONE, databaseAttachment.getSize(), databaseAttachment.getLocation(), databaseAttachment.getKey(), databaseAttachment.getRelay())); } return insertMediaMessage( new MasterSecretUnion(masterSecret), MmsAddresses.forTo(request.getRecipients().toNumberStringList(false)), request.getBody(), attachments, contentValues); } catch (NoSuchMessageException e) { throw new MmsException(e); } }
public Pair<Long, Long> insertMessageInbox(@NonNull NotificationInd notification) { SQLiteDatabase db = databaseHelper.getWritableDatabase(); MmsAddressDatabase addressDatabase = DatabaseFactory.getMmsAddressDatabase(context); long threadId = getThreadIdFor(notification); PduHeaders headers = notification.getPduHeaders(); ContentValues contentValues = new ContentValues(); ContentValuesBuilder contentBuilder = new ContentValuesBuilder(contentValues); Log.w(TAG, "Message received type: " + headers.getOctet(PduHeaders.MESSAGE_TYPE)); contentBuilder.add(CONTENT_LOCATION, headers.getTextString(PduHeaders.CONTENT_LOCATION)); contentBuilder.add(DATE_SENT, headers.getLongInteger(PduHeaders.DATE) * 1000L); contentBuilder.add(EXPIRY, headers.getLongInteger(PduHeaders.EXPIRY)); contentBuilder.add(MESSAGE_SIZE, headers.getLongInteger(PduHeaders.MESSAGE_SIZE)); contentBuilder.add(TRANSACTION_ID, headers.getTextString(PduHeaders.TRANSACTION_ID)); contentBuilder.add(MESSAGE_TYPE, headers.getOctet(PduHeaders.MESSAGE_TYPE)); if (headers.getEncodedStringValue(PduHeaders.FROM) != null) { contentBuilder.add(ADDRESS, headers.getEncodedStringValue(PduHeaders.FROM).getTextString()); } else { contentBuilder.add(ADDRESS, null); } contentValues.put(MESSAGE_BOX, Types.BASE_INBOX_TYPE); contentValues.put(THREAD_ID, threadId); contentValues.put(STATUS, Status.DOWNLOAD_INITIALIZED); contentValues.put(DATE_RECEIVED, generatePduCompatTimestamp()); contentValues.put(READ, Util.isDefaultSmsProvider(context) ? 0 : 1); if (!contentValues.containsKey(DATE_SENT)) contentValues.put(DATE_SENT, contentValues.getAsLong(DATE_RECEIVED)); long messageId = db.insert(TABLE_NAME, null, contentValues); addressDatabase.insertAddressesForId( messageId, MmsAddresses.forFrom(Util.toIsoString(notification.getFrom().getTextString()))); return new Pair<>(messageId, threadId); }