Support for incoming attachments.

1) Refactored MMS layer to use abstracted types.

2) Added support for retrieving attachment IDs.
This commit is contained in:
Moxie Marlinspike
2013-07-18 17:42:45 -07:00
parent 4bb337a3a0
commit 9287d413ac
23 changed files with 501 additions and 193 deletions

View File

@@ -57,7 +57,6 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Trimmer;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.textsecure.push.PushServiceSocket;
import org.whispersystems.textsecure.push.RateLimitException;
import java.io.IOException;
@@ -361,9 +360,6 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
} catch (IOException e) {
Log.w("ApplicationPreferencesActivity", e);
return NETWORK_ERROR;
} catch (RateLimitException e) {
Log.w("ApplicationPreferencesActivity", e);
return NETWORK_ERROR;
}
}
}.execute();

View File

@@ -452,12 +452,12 @@ public class RegistrationProgressActivity extends SherlockActivity {
PushServiceSocket socket = new PushServiceSocket(context, e164number, password);
socket.verifyAccount(code);
return SUCCESS;
} catch (IOException e) {
Log.w("RegistrationProgressActivity", e);
return NETWORK_ERROR;
} catch (RateLimitException e) {
Log.w("RegistrationProgressActivity", e);
return RATE_LIMIT_ERROR;
} catch (IOException e) {
Log.w("RegistrationProgressActivity", e);
return NETWORK_ERROR;
}
}
}.execute();
@@ -539,12 +539,12 @@ public class RegistrationProgressActivity extends SherlockActivity {
socket.createAccount(true);
return SUCCESS;
} catch (IOException e) {
Log.w("RegistrationProgressActivity", e);
return NETWORK_ERROR;
} catch (RateLimitException e) {
Log.w("RegistrationProgressActivity", e);
return RATE_LIMIT_EXCEEDED;
} catch (IOException e) {
Log.w("RegistrationProgressActivity", e);
return NETWORK_ERROR;
}
}
}.execute();

View File

@@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.database.EncryptingSmsDatabase;
import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
import org.thoughtcrime.securesms.mms.TextTransport;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -212,7 +213,7 @@ public class DecryptingQueue {
RetrieveConf plaintextPdu = new RetrieveConf(plaintextGenericPdu.getPduHeaders(),
plaintextGenericPdu.getBody());
Log.w("DecryptingQueue", "Successfully decrypted MMS!");
database.insertSecureDecryptedMessageInbox(masterSecret, plaintextPdu, threadId);
database.insertSecureDecryptedMessageInbox(masterSecret, new IncomingMediaMessage(plaintextPdu), threadId);
database.delete(messageId);
} catch (RecipientFormattingException rfe) {
Log.w("DecryptingQueue", rfe);

View File

@@ -33,6 +33,7 @@ import org.thoughtcrime.securesms.database.model.DisplayRecord;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord;
import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
import org.thoughtcrime.securesms.mms.PartParser;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.mms.TextSlide;
@@ -59,11 +60,9 @@ import ws.com.google.android.mms.InvalidHeaderValueException;
import ws.com.google.android.mms.MmsException;
import ws.com.google.android.mms.pdu.CharacterSets;
import ws.com.google.android.mms.pdu.EncodedStringValue;
import ws.com.google.android.mms.pdu.MultimediaMessagePdu;
import ws.com.google.android.mms.pdu.NotificationInd;
import ws.com.google.android.mms.pdu.PduBody;
import ws.com.google.android.mms.pdu.PduHeaders;
import ws.com.google.android.mms.pdu.RetrieveConf;
import ws.com.google.android.mms.pdu.SendReq;
// XXXX Clean up MMS efficiency:
@@ -177,27 +176,23 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
}
}
private long getThreadIdFor(RetrieveConf retrieved) throws RecipientFormattingException {
private long getThreadIdFor(IncomingMediaMessage retrieved) throws RecipientFormattingException {
try {
PduHeaders headers = retrieved.getPduHeaders();
Set<String> group = new HashSet<String>();
EncodedStringValue encodedFrom = retrieved.getFrom();
EncodedStringValue encodedFrom = headers.getEncodedStringValue(PduHeaders.FROM);
group.add(new String(encodedFrom.getTextString(), CharacterSets.MIMENAME_ISO_8859_1));
EncodedStringValue[] encodedCcList = retrieved.getCc();
EncodedStringValue[] encodedCcList = headers.getEncodedStringValues(PduHeaders.CC);
if (encodedCcList != null) {
for (EncodedStringValue encodedCc : encodedCcList) {
group.add(new String(encodedCc.getTextString(), CharacterSets.MIMENAME_ISO_8859_1));
}
}
StringBuilder sb = new StringBuilder();
for (String recipient : group) {
sb.append(recipient);
sb.append(",");
}
Recipients recipients = RecipientFactory.getRecipientsFromString(context, sb.toString(), false);
String recipientsList = Util.join(group, ",");
Recipients recipients = RecipientFactory.getRecipientsFromString(context, recipientsList, false);
return DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
@@ -280,7 +275,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
ContentValues contentValues = new ContentValues();
contentValues.put(READ, 1);
database.update(TABLE_NAME, contentValues, THREAD_ID + " = ?", new String[] {threadId+""});
database.update(TABLE_NAME, contentValues, THREAD_ID + " = ?", new String[] {threadId + ""});
}
public void setAllMessagesRead() {
@@ -359,7 +354,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
return new Reader(masterSecret, cursor);
}
private Pair<Long, Long> insertMessageInbox(MasterSecret masterSecret, RetrieveConf retrieved,
private Pair<Long, Long> insertMessageInbox(MasterSecret masterSecret, IncomingMediaMessage retrieved,
String contentLocation, long threadId, long mailbox)
throws MmsException
{
@@ -367,11 +362,13 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
ContentValues contentValues = getContentValuesFromHeader(headers);
boolean unread = Util.isDefaultSmsProvider(context) || ((mailbox & Types.SECURE_MESSAGE_BIT) != 0);
if (!org.thoughtcrime.securesms.util.Util.isEmpty(retrieved.getCc())) {
if (threadId == -1 || retrieved.isGroupMessage()) {
try {
threadId = getThreadIdFor(retrieved);
} catch (RecipientFormattingException e) {
Log.w("MmsDatabase", e);
if (threadId == -1)
throw new MmsException(e);
}
}
@@ -382,10 +379,12 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
contentValues.put(DATE_RECEIVED, System.currentTimeMillis() / 1000);
contentValues.put(READ, unread ? 0 : 1);
if (!contentValues.containsKey(DATE_SENT))
if (!contentValues.containsKey(DATE_SENT)) {
contentValues.put(DATE_SENT, contentValues.getAsLong(DATE_RECEIVED));
}
long messageId = insertMediaMessage(masterSecret, retrieved, contentValues);
long messageId = insertMediaMessage(masterSecret, retrieved.getPduHeaders(),
retrieved.getBody(), contentValues);
if (unread) {
DatabaseFactory.getThreadDatabase(context).setUnread(threadId);
@@ -398,7 +397,8 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
return new Pair<Long, Long>(messageId, threadId);
}
public Pair<Long, Long> insertMessageInbox(MasterSecret masterSecret, RetrieveConf retrieved,
public Pair<Long, Long> insertMessageInbox(MasterSecret masterSecret,
IncomingMediaMessage retrieved,
String contentLocation, long threadId)
throws MmsException
{
@@ -406,7 +406,8 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
Types.BASE_INBOX_TYPE | Types.ENCRYPTION_SYMMETRIC_BIT);
}
public Pair<Long, Long> insertSecureMessageInbox(MasterSecret masterSecret, RetrieveConf retrieved,
public Pair<Long, Long> insertSecureMessageInbox(MasterSecret masterSecret,
IncomingMediaMessage retrieved,
String contentLocation, long threadId)
throws MmsException
{
@@ -415,7 +416,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
}
public Pair<Long, Long> insertSecureDecryptedMessageInbox(MasterSecret masterSecret,
RetrieveConf retrieved,
IncomingMediaMessage retrieved,
long threadId)
throws MmsException
{
@@ -425,11 +426,11 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
public Pair<Long, Long> insertMessageInbox(NotificationInd notification) {
try {
SQLiteDatabase db = databaseHelper.getWritableDatabase();
PduHeaders headers = notification.getPduHeaders();
ContentValues contentValues = getContentValuesFromHeader(headers);
long threadId = getThreadIdFor(notification);
SQLiteDatabase db = databaseHelper.getWritableDatabase();
MmsAddressDatabase addressDatabase = DatabaseFactory.getMmsAddressDatabase(context);
long threadId = getThreadIdFor(notification);
PduHeaders headers = notification.getPduHeaders();
ContentValues contentValues = getContentValuesFromHeader(headers);
Log.w("MmsDatabse", "Message received type: " + headers.getOctet(PduHeaders.MESSAGE_TYPE));
@@ -486,21 +487,22 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
contentValues.put(DATE_RECEIVED, contentValues.getAsLong(DATE_SENT));
contentValues.remove(ADDRESS);
long messageId = insertMediaMessage(masterSecret, sendRequest, contentValues);
long messageId = insertMediaMessage(masterSecret, sendRequest.getPduHeaders(),
sendRequest.getBody(), contentValues);
Trimmer.trimThread(context, threadId);
return messageId;
}
private long insertMediaMessage(MasterSecret masterSecret,
MultimediaMessagePdu message,
PduHeaders headers,
PduBody body,
ContentValues contentValues)
throws MmsException
{
SQLiteDatabase db = databaseHelper.getWritableDatabase();
PartDatabase partsDatabase = getPartDatabase(masterSecret);
MmsAddressDatabase addressDatabase = DatabaseFactory.getMmsAddressDatabase(context);
PduBody body = message.getBody();
if (Types.isSymmetricEncryption(contentValues.getAsLong(MESSAGE_BOX))) {
String messageText = PartParser.getMessageText(body);
@@ -515,7 +517,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
long messageId = db.insert(TABLE_NAME, null, contentValues);
addressDatabase.insertAddressesForId(messageId, message.getPduHeaders());
addressDatabase.insertAddressesForId(messageId, headers);
partsDatabase.insertParts(messageId, body);
notifyConversationListeners(contentValues.getAsLong(THREAD_ID));

View File

@@ -10,7 +10,7 @@ import org.thoughtcrime.securesms.service.RegistrationService;
import org.thoughtcrime.securesms.service.SendReceiveService;
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.textsecure.push.IncomingGcmMessage;
import org.whispersystems.textsecure.push.IncomingPushMessage;
import org.whispersystems.textsecure.push.PushServiceSocket;
import org.whispersystems.textsecure.push.RateLimitException;
import org.whispersystems.textsecure.util.Util;
@@ -33,8 +33,6 @@ public class GcmIntentService extends GCMBaseIntentService {
getGcmSocket(context).registerGcmId(registrationId);
} catch (IOException e) {
Log.w("GcmIntentService", e);
} catch (RateLimitException e) {
Log.w("GcmIntentService", e);
}
}
}
@@ -45,22 +43,30 @@ public class GcmIntentService extends GCMBaseIntentService {
getGcmSocket(context).unregisterGcmId();
} catch (IOException ioe) {
Log.w("GcmIntentService", ioe);
} catch (RateLimitException e) {
Log.w("GcmIntentService", e);
}
}
@Override
protected void onMessage(Context context, Intent intent) {
Log.w("GcmIntentService", "Got GCM message!");
String data = intent.getStringExtra("message");
Log.w("GcmIntentService", "GCM message: " + data);
if (Util.isEmpty(data))
return;
IncomingGcmMessage message = new Gson().fromJson(data, IncomingGcmMessage.class);
IncomingPushMessage message = new Gson().fromJson(data, IncomingPushMessage.class);
if (!message.hasAttachments()) handleIncomingTextMessage(context, message);
else handleIncomingMediaMessage(context, message);
}
@Override
protected void onError(Context context, String s) {
Log.w("GcmIntentService", "GCM Error: " + s);
}
private void handleIncomingTextMessage(Context context, IncomingPushMessage message) {
ArrayList<IncomingTextMessage> messages = new ArrayList<IncomingTextMessage>();
messages.add(new IncomingTextMessage(message));
@@ -70,9 +76,11 @@ public class GcmIntentService extends GCMBaseIntentService {
context.startService(receivedIntent);
}
@Override
protected void onError(Context context, String s) {
Log.w("GcmIntentService", "GCM Error: " + s);
private void handleIncomingMediaMessage(Context context, IncomingPushMessage message) {
Intent receivedIntent = new Intent(context, SendReceiveService.class);
receivedIntent.setAction(SendReceiveService.RECEIVE_PUSH_MMS_ACTION);
receivedIntent.putExtra("media_message", message);
context.startService(receivedIntent);
}
private PushServiceSocket getGcmSocket(Context context) {

View File

@@ -0,0 +1,86 @@
package org.thoughtcrime.securesms.mms;
import android.util.Log;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.textsecure.push.IncomingPushMessage;
import org.whispersystems.textsecure.push.PushAttachmentPointer;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import ws.com.google.android.mms.pdu.CharacterSets;
import ws.com.google.android.mms.pdu.EncodedStringValue;
import ws.com.google.android.mms.pdu.PduBody;
import ws.com.google.android.mms.pdu.PduHeaders;
import ws.com.google.android.mms.pdu.PduPart;
import ws.com.google.android.mms.pdu.RetrieveConf;
public class IncomingMediaMessage {
private final PduHeaders headers;
private final PduBody body;
public IncomingMediaMessage(RetrieveConf retreived) {
this.headers = retreived.getPduHeaders();
this.body = retreived.getBody();
}
public IncomingMediaMessage(String localNumber, IncomingPushMessage message, List<File> attachments)
throws IOException
{
this.headers = new PduHeaders();
this.body = new PduBody();
this.headers.setEncodedStringValue(new EncodedStringValue(message.getSource()), PduHeaders.FROM);
this.headers.appendEncodedStringValue(new EncodedStringValue(localNumber), PduHeaders.TO);
for (String destination : message.getDestinations()) {
if (!destination.equals(localNumber)) {
this.headers.appendEncodedStringValue(new EncodedStringValue(destination), PduHeaders.CC);
}
}
this.headers.setLongInteger(message.getTimestampMillis() / 1000, PduHeaders.DATE);
if (message.getMessageText() != null && message.getMessageText().length() > 0) {
PduPart text = new PduPart();
text.setData(message.getMessageText().getBytes());
text.setContentType("text/plain".getBytes(CharacterSets.MIMENAME_ISO_8859_1));
body.addPart(text);
}
Iterator<PushAttachmentPointer> descriptors = message.getAttachments().iterator();
if (attachments != null) {
for (File attachment : attachments) {
PduPart media = new PduPart();
FileInputStream fin = new FileInputStream(attachment);
byte[] data = Util.readFully(fin);
PushAttachmentPointer descriptor = descriptors.next();
Log.w("IncomingMediaMessage", "Adding part: " + descriptor.getContentType() + " with length: " + data.length);
media.setContentType(descriptor.getContentType().getBytes(CharacterSets.MIMENAME_ISO_8859_1));
media.setData(data);
body.addPart(media);
}
}
}
public PduHeaders getPduHeaders() {
return headers;
}
public PduBody getBody() {
return body;
}
public boolean isGroupMessage() {
return !Util.isEmpty(headers.getEncodedStringValues(PduHeaders.CC));
}
}

View File

@@ -29,6 +29,7 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord;
import org.thoughtcrime.securesms.mms.ApnUnavailableException;
import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
import org.thoughtcrime.securesms.mms.MmsDownloadHelper;
import org.thoughtcrime.securesms.mms.MmsRadio;
import org.thoughtcrime.securesms.mms.MmsRadioException;
@@ -177,11 +178,13 @@ public class MmsDownloader {
long messageId, long threadId, RetrieveConf retrieved)
throws MmsException
{
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
IncomingMediaMessage message = new IncomingMediaMessage(retrieved);
Pair<Long, Long> messageAndThreadId;
if (retrieved.getSubject() != null && WirePrefix.isEncryptedMmsSubject(retrieved.getSubject().getString())) {
messageAndThreadId = database.insertSecureMessageInbox(masterSecret, retrieved,
messageAndThreadId = database.insertSecureMessageInbox(masterSecret, message,
contentLocation, threadId);
if (masterSecret != null)
@@ -189,7 +192,7 @@ public class MmsDownloader {
messageAndThreadId.second, retrieved);
} else {
messageAndThreadId = database.insertMessageInbox(masterSecret, retrieved,
messageAndThreadId = database.insertMessageInbox(masterSecret, message,
contentLocation, threadId);
}

View File

@@ -24,8 +24,17 @@ import android.util.Pair;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.textsecure.push.IncomingPushMessage;
import org.whispersystems.textsecure.push.PushServiceSocket;
import org.whispersystems.textsecure.push.RateLimitException;
import java.io.File;
import java.io.IOException;
import java.util.List;
import ws.com.google.android.mms.MmsException;
import ws.com.google.android.mms.pdu.GenericPdu;
import ws.com.google.android.mms.pdu.NotificationInd;
import ws.com.google.android.mms.pdu.PduHeaders;
@@ -39,6 +48,54 @@ public class MmsReceiver {
this.context = context;
}
public void process(MasterSecret masterSecret, Intent intent) {
try {
if (intent.getAction().equals(SendReceiveService.RECEIVE_MMS_ACTION)) {
handleMmsNotification(intent);
} else if (intent.getAction().equals(SendReceiveService.RECEIVE_PUSH_MMS_ACTION)) {
handlePushMedia(masterSecret, intent);
}
} catch (MmsException e) {
Log.w("MmsReceiver", e);
}
}
private void handleMmsNotification(Intent intent) {
byte[] mmsData = intent.getByteArrayExtra("data");
PduParser parser = new PduParser(mmsData);
GenericPdu pdu = parser.parse();
if (pdu.getMessageType() == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) {
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
Pair<Long, Long> messageAndThreadId = database.insertMessageInbox((NotificationInd)pdu);
Log.w("MmsReceiver", "Inserted received MMS notification...");
scheduleDownload((NotificationInd)pdu, messageAndThreadId.first, messageAndThreadId.second);
}
}
private void handlePushMedia(MasterSecret masterSecret, Intent intent) throws MmsException {
IncomingPushMessage pushMessage = intent.getParcelableExtra("media_message");
String localNumber = TextSecurePreferences.getLocalNumber(context);
String password = TextSecurePreferences.getPushServerPassword(context);
PushServiceSocket socket = new PushServiceSocket(context, localNumber, password);
try {
List<File> attachments = socket.retrieveAttachments(pushMessage.getAttachments());
IncomingMediaMessage message = new IncomingMediaMessage(localNumber, pushMessage, attachments);
DatabaseFactory.getMmsDatabase(context).insertMessageInbox(masterSecret, message, "", -1);
} catch (IOException e) {
Log.w("MmsReceiver", e);
try {
IncomingMediaMessage message = new IncomingMediaMessage(localNumber, pushMessage, null);
DatabaseFactory.getMmsDatabase(context).insertMessageInbox(masterSecret, message, "", -1);
} catch (IOException e1) {
throw new MmsException(e1);
}
}
}
private void scheduleDownload(NotificationInd pdu, long messageId, long threadId) {
Intent intent = new Intent(SendReceiveService.DOWNLOAD_MMS_ACTION, null, context, SendReceiveService.class);
intent.putExtra("content_location", new String(pdu.getContentLocation()));
@@ -50,21 +107,4 @@ public class MmsReceiver {
context.startService(intent);
}
public void process(MasterSecret masterSecret, Intent intent) {
byte[] mmsData = intent.getByteArrayExtra("data");
PduParser parser = new PduParser(mmsData);
GenericPdu pdu = parser.parse();
if (pdu.getMessageType() == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) {
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
Pair<Long, Long> messageAndThreadId = database.insertMessageInbox((NotificationInd)pdu);
// long threadId = database.getThreadIdForMessage(messageId);
// MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
scheduleDownload((NotificationInd)pdu, messageAndThreadId.first, messageAndThreadId.second);
Log.w("MmsReceiverService", "Inserted received notification...");
}
}
}

View File

@@ -5,24 +5,23 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
import android.util.Pair;
import com.google.android.gcm.GCMRegistrar;
import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.gcm.GcmIntentService;
import org.thoughtcrime.securesms.gcm.GcmRegistrationTimeoutException;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.textsecure.directory.DirectoryDescriptor;
import org.whispersystems.textsecure.directory.NumberFilter;
import org.whispersystems.textsecure.push.PushServiceSocket;
import org.whispersystems.textsecure.push.RateLimitException;
import org.whispersystems.textsecure.util.Util;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -172,7 +171,8 @@ public class RegistrationService extends Service {
String gcmRegistrationId = waitForGcmRegistrationId();
socket.registerGcmId(gcmRegistrationId);
socket.retrieveDirectory(this);
Pair<DirectoryDescriptor, File> directory = socket.retrieveDirectory();
NumberFilter.getInstance(this).update(directory.first, directory.second);
markAsVerified(number, password);
@@ -190,10 +190,6 @@ public class RegistrationService extends Service {
Log.w("RegistrationService", e);
setState(new RegistrationState(RegistrationState.STATE_GCM_TIMEOUT));
broadcastComplete(false);
} catch (RateLimitException e) {
Log.w("RegistrationService", e);
setState(new RegistrationState(RegistrationState.STATE_NETWORK_ERROR));
broadcastComplete(false);
} finally {
shutdownGcmRegistrationListener();
}
@@ -222,7 +218,8 @@ public class RegistrationService extends Service {
String gcmRegistrationId = waitForGcmRegistrationId();
socket.registerGcmId(gcmRegistrationId);
socket.retrieveDirectory(this);
Pair<DirectoryDescriptor, File> directory = socket.retrieveDirectory();
NumberFilter.getInstance(this).update(directory.first, directory.second);
markAsVerified(number, password);
@@ -244,10 +241,6 @@ public class RegistrationService extends Service {
Log.w("RegistrationService", e);
setState(new RegistrationState(RegistrationState.STATE_GCM_TIMEOUT));
broadcastComplete(false);
} catch (RateLimitException e) {
Log.w("RegistrationService", e);
setState(new RegistrationState(RegistrationState.STATE_NETWORK_ERROR));
broadcastComplete(false);
} finally {
shutdownChallengeListener();
shutdownGcmRegistrationListener();

View File

@@ -51,6 +51,7 @@ public class SendReceiveService extends Service {
public static final String RECEIVE_SMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.RECEIVE_SMS_ACTION";
public static final String SEND_MMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.SEND_MMS_ACTION";
public static final String RECEIVE_MMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.RECEIVE_MMS_ACTION";
public static final String RECEIVE_PUSH_MMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.RECEIVE_PUSH_MMS_ACTION";
public static final String DOWNLOAD_MMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.DOWNLOAD_MMS_ACTION";
public static final String DOWNLOAD_MMS_CONNECTIVITY_ACTION = "org.thoughtcrime.securesms.SendReceiveService.DOWNLOAD_MMS_CONNECTIVITY_ACTION";
public static final String DOWNLOAD_MMS_PENDING_APN_ACTION = "org.thoughtcrime.securesms.SendReceiveService.DOWNLOAD_MMS_PENDING_APN_ACTION";
@@ -92,19 +93,21 @@ public class SendReceiveService extends Service {
public void onStart(Intent intent, int startId) {
if (intent == null) return;
if (intent.getAction().equals(SEND_SMS_ACTION))
String action = intent.getAction();
if (action.equals(SEND_SMS_ACTION))
scheduleSecretRequiredIntent(SEND_SMS, intent);
else if (intent.getAction().equals(RECEIVE_SMS_ACTION))
else if (action.equals(RECEIVE_SMS_ACTION))
scheduleIntent(RECEIVE_SMS, intent);
else if (intent.getAction().equals(SENT_SMS_ACTION))
else if (action.equals(SENT_SMS_ACTION))
scheduleIntent(SEND_SMS, intent);
else if (intent.getAction().equals(DELIVERED_SMS_ACTION))
else if (action.equals(DELIVERED_SMS_ACTION))
scheduleIntent(SEND_SMS, intent);
else if (intent.getAction().equals(SEND_MMS_ACTION))
else if (action.equals(SEND_MMS_ACTION))
scheduleSecretRequiredIntent(SEND_MMS, intent);
else if (intent.getAction().equals(RECEIVE_MMS_ACTION))
else if (action.equals(RECEIVE_MMS_ACTION) || action.equals(RECEIVE_PUSH_MMS_ACTION))
scheduleIntent(RECEIVE_MMS, intent);
else if (intent.getAction().equals(DOWNLOAD_MMS_ACTION))
else if (action.equals(DOWNLOAD_MMS_ACTION))
scheduleSecretRequiredIntent(DOWNLOAD_MMS, intent);
else if (intent.getAction().equals(DOWNLOAD_MMS_PENDING_APN_ACTION))
scheduleSecretRequiredIntent(DOWNLOAD_MMS_PENDING, intent);

View File

@@ -4,7 +4,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.SmsMessage;
import org.whispersystems.textsecure.push.IncomingGcmMessage;
import org.whispersystems.textsecure.push.IncomingPushMessage;
import java.util.List;
@@ -40,7 +40,7 @@ public class IncomingTextMessage implements Parcelable {
this.sentTimestampMillis = message.getTimestampMillis();
}
public IncomingTextMessage(IncomingGcmMessage message) {
public IncomingTextMessage(IncomingPushMessage message) {
this.message = message.getMessageText();
this.sender = message.getSource();
this.protocol = 31337;

View File

@@ -8,7 +8,7 @@ import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
import org.thoughtcrime.securesms.mms.PartParser;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.textsecure.push.PushAttachment;
import org.whispersystems.textsecure.push.PushAttachmentData;
import org.whispersystems.textsecure.push.PushServiceSocket;
import org.whispersystems.textsecure.push.RateLimitException;
import org.whispersystems.textsecure.util.PhoneNumberFormatter;
@@ -52,11 +52,11 @@ public class PushTransport extends BaseTransport {
public void deliver(SendReq message, List<String> destinations) throws IOException {
try {
String localNumber = TextSecurePreferences.getLocalNumber(context);
String password = TextSecurePreferences.getPushServerPassword(context);
PushServiceSocket socket = new PushServiceSocket(context, localNumber, password);
String messageText = PartParser.getMessageText(message.getBody());
List<PushAttachment> attachments = getAttachmentsFromBody(message.getBody());
String localNumber = TextSecurePreferences.getLocalNumber(context);
String password = TextSecurePreferences.getPushServerPassword(context);
PushServiceSocket socket = new PushServiceSocket(context, localNumber, password);
String messageText = PartParser.getMessageText(message.getBody());
List<PushAttachmentData> attachments = getAttachmentsFromBody(message.getBody());
if (attachments.isEmpty()) socket.sendMessage(destinations, messageText);
else socket.sendMessage(destinations, messageText, attachments);
@@ -66,8 +66,8 @@ public class PushTransport extends BaseTransport {
}
}
private List<PushAttachment> getAttachmentsFromBody(PduBody body) {
List<PushAttachment> attachments = new LinkedList<PushAttachment>();
private List<PushAttachmentData> getAttachmentsFromBody(PduBody body) {
List<PushAttachmentData> attachments = new LinkedList<PushAttachmentData>();
for (int i=0;i<body.getPartsNum();i++) {
String contentType = Util.toIsoString(body.getPart(i).getContentType());
@@ -76,7 +76,7 @@ public class PushTransport extends BaseTransport {
ContentType.isAudioType(contentType) ||
ContentType.isVideoType(contentType))
{
attachments.add(new PushAttachment(contentType, body.getPart(i).getData()));
attachments.add(new PushAttachmentData(contentType, body.getPart(i).getData()));
}
}

View File

@@ -29,7 +29,11 @@ import android.provider.Telephony;
import org.thoughtcrime.securesms.mms.MmsRadio;
import org.whispersystems.textsecure.util.PhoneNumberFormatter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -151,6 +155,19 @@ public class Util {
return PhoneNumberFormatter.formatNumber(number, localNumber);
}
public static byte[] readFully(InputStream in) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[4069];
int read;
while ((read = in.read(buffer)) != -1) {
baos.write(buffer, 0, read);
}
in.close();
return baos.toByteArray();
}
public static boolean isDefaultSmsProvider(Context context){
return (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) ||