protected long insertMessageOutbox( long threadId, OutgoingTextMessage message, long type, boolean forceSms, long date) { if (message.isKeyExchange()) type |= Types.KEY_EXCHANGE_BIT; else if (message.isSecureMessage()) type |= Types.SECURE_MESSAGE_BIT; else if (message.isEndSession()) type |= Types.END_SESSION_BIT; if (forceSms) type |= Types.MESSAGE_FORCE_SMS_BIT; ContentValues contentValues = new ContentValues(6); contentValues.put( ADDRESS, PhoneNumberUtils.formatNumber(message.getRecipients().getPrimaryRecipient().getNumber())); contentValues.put(THREAD_ID, threadId); contentValues.put(BODY, message.getMessageBody()); contentValues.put(DATE_RECEIVED, System.currentTimeMillis()); contentValues.put(DATE_SENT, date); contentValues.put(READ, 1); contentValues.put(TYPE, type); SQLiteDatabase db = databaseHelper.getWritableDatabase(); long messageId = db.insert(TABLE_NAME, ADDRESS, contentValues); DatabaseFactory.getThreadDatabase(context).update(threadId, true); notifyConversationListeners(threadId); jobManager.add(new TrimThreadJob(context, threadId)); return messageId; }
private OutgoingTextMessage getAsymmetricEncrypt( MasterSecret masterSecret, OutgoingTextMessage message) { Recipient recipient = message.getRecipients().getPrimaryRecipient(); String body = message.getMessageBody(); SmsTransportDetails transportDetails = new SmsTransportDetails(); SessionCipher sessionCipher = SessionCipher.createFor(context, masterSecret, recipient); byte[] paddedPlaintext = transportDetails.getPaddedMessageBody(body.getBytes()); CiphertextMessage ciphertextMessage = sessionCipher.encrypt(paddedPlaintext); String encodedCiphertext = new String(transportDetails.getEncodedMessage(ciphertextMessage.serialize())); if (ciphertextMessage.getType() == CiphertextMessage.PREKEY_WHISPER_TYPE) { message = new OutgoingPrekeyBundleMessage(message, encodedCiphertext); } else { message = message.withBody(encodedCiphertext); } return message; }
private void deliverSecureMessage(SmsMessageRecord message) throws UndeliverableMessageException { MultipartSmsMessageHandler multipartMessageHandler = new MultipartSmsMessageHandler(); OutgoingTextMessage transportMessage = OutgoingTextMessage.from(message); if (message.isSecure()) { transportMessage = getAsymmetricEncrypt(masterSecret, transportMessage); } ArrayList<String> messages = multipartMessageHandler.divideMessage(transportMessage); ArrayList<PendingIntent> sentIntents = constructSentIntents(message.getId(), message.getType(), messages, message.isSecure()); ArrayList<PendingIntent> deliveredIntents = constructDeliveredIntents(message.getId(), message.getType(), messages); Log.w("SmsTransport", "Secure divide into message parts: " + messages.size()); for (int i = 0; i < messages.size(); i++) { // XXX [email protected] 1/7/11 -- There's apparently a bug where for some unknown // recipients // and messages, this will throw an NPE. I have no idea why, so I'm just catching it and // marking // the message as a failure. That way at least it doesn't repeatedly crash every time you // start // the app. // d3sre 12/10/13 -- extended the log file to further analyse the problem try { SmsManager.getDefault() .sendTextMessage( message.getIndividualRecipient().getNumber(), null, messages.get(i), sentIntents.get(i), deliveredIntents == null ? null : deliveredIntents.get(i)); } catch (NullPointerException npe) { Log.w("SmsTransport", npe); Log.w("SmsTransport", "Recipient: " + message.getIndividualRecipient().getNumber()); Log.w("SmsTransport", "Message Total Parts/Current: " + messages.size() + "/" + i); Log.w("SmsTransport", "Message Part Length: " + messages.get(i).getBytes().length); throw new UndeliverableMessageException(npe); } catch (IllegalArgumentException iae) { Log.w("SmsTransport", iae); throw new UndeliverableMessageException(iae); } } }
protected long insertMessageOutbox( long threadId, OutgoingTextMessage message, long type, boolean forceSms, long date) { if (message.isKeyExchange()) type |= Types.KEY_EXCHANGE_BIT; else if (message.isSecureMessage()) type |= Types.SECURE_MESSAGE_BIT; else if (message.isEndSession()) type |= Types.END_SESSION_BIT; if (forceSms) type |= Types.MESSAGE_FORCE_SMS_BIT; String address = message.getRecipients().getPrimaryRecipient().getNumber(); ContentValues contentValues = new ContentValues(6); contentValues.put(ADDRESS, PhoneNumberUtils.formatNumber(address)); contentValues.put(THREAD_ID, threadId); contentValues.put(BODY, message.getMessageBody()); contentValues.put(DATE_RECEIVED, System.currentTimeMillis()); contentValues.put(DATE_SENT, date); contentValues.put(READ, 1); contentValues.put(TYPE, type); contentValues.put(SUBSCRIPTION_ID, message.getSubscriptionId()); contentValues.put(EXPIRES_IN, message.getExpiresIn()); try { contentValues.put( RECEIPT_COUNT, earlyReceiptCache.remove(date, canonicalizeNumber(context, address))); } catch (InvalidNumberException e) { Log.w(TAG, e); } SQLiteDatabase db = databaseHelper.getWritableDatabase(); long messageId = db.insert(TABLE_NAME, ADDRESS, contentValues); DatabaseFactory.getThreadDatabase(context).update(threadId, true); notifyConversationListeners(threadId); jobManager.add(new TrimThreadJob(context, threadId)); return messageId; }