mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-19 19:38:45 +00:00
parent
990d858764
commit
2cfc714b64
@ -58,11 +58,10 @@
|
||||
|
||||
<activity android:name=".PromptMmsActivity"
|
||||
android:label="Configure MMS Settings"
|
||||
android:windowSoftInputMode="stateUnchanged"
|
||||
android:windowSoftInputMode="stateUnchanged"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".DeviceProvisioningActivity"
|
||||
android:theme="@style/TextSecure.DialogActivity"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
13
build.gradle
13
build.gradle
@ -66,8 +66,8 @@ dependencies {
|
||||
|
||||
compile 'org.whispersystems:jobmanager:0.11.0'
|
||||
compile 'org.whispersystems:libpastelog:1.0.6'
|
||||
compile 'org.whispersystems:textsecure-android:1.3.0'
|
||||
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
|
||||
compile 'org.whispersystems:textsecure-android:1.5.0'
|
||||
|
||||
androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
|
||||
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
|
||||
@ -86,6 +86,7 @@ dependencyVerification {
|
||||
'me.leolin:ShortcutBadger:3142d017234bfa0cdd69ccded7cc5ea63f13b97574803c8c616c9bbeaad33ad9',
|
||||
'se.emilsjolander:stickylistheaders:89146b46c96fea0e40200474a2625cda10fe94891e4128f53cdb42375091b9b6',
|
||||
'com.google.android.gms:play-services-base:832cb6b3130e871db6a412c4ab585656dbcc5e7948101f190186757785703f75',
|
||||
'com.jpardogo.materialtabstrip:library:c6ef812fba4f74be7dc4a905faa4c2908cba261a94c13d4f96d5e67e4aad4aaa',
|
||||
'org.w3c:smil:085dc40f2bb249651578bfa07499fd08b16ad0886dbe2c4078586a408da62f9b',
|
||||
'org.apache.httpcomponents:httpclient-android:6f56466a9bd0d42934b90bfbfe9977a8b654c058bf44a12bdc2877c4e1f033f1',
|
||||
'com.github.chrisbanes.photoview:library:8b5344e206f125e7ba9d684008f36c4992d03853c57e5814125f88496126e3cc',
|
||||
@ -103,23 +104,23 @@ dependencyVerification {
|
||||
'com.madgag.spongycastle:prov:b8c3fec3a59aac1aa04ccf4dad7179351e54ef7672f53f508151b614c131398a',
|
||||
'org.whispersystems:jobmanager:ea9cb943c4892fb90c1eea1be30efeb85cefca213d52c788419553b58d0ed70d',
|
||||
'org.whispersystems:libpastelog:550d33c565380d90f4c671e7b8ed5f3a6da55a9fda468373177106b2eb5220b2',
|
||||
'org.whispersystems:textsecure-android:df4c1ac9ee8f7cd43c8c07d64b16e31875e04632afc3fe73f2a47292a86c79a1',
|
||||
'com.amulyakhare:com.amulyakhare.textdrawable:54c92b5fba38cfd316a07e5a30528068f45ce8515a6890f1297df4c401af5dcb',
|
||||
'org.whispersystems:textsecure-android:b8001bd3c77fadcf84e0c3b21353f76d6db783bd17b28c5d7296d71198446d4b',
|
||||
'com.nineoldandroids:library:68025a14e3e7673d6ad2f95e4b46d78d7d068343aa99256b686fe59de1b3163a',
|
||||
'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f',
|
||||
'org.whispersystems:textsecure-java:59d7c998c83a0f96bbc84db36719c9be8007bce16ee1ba9748af5610ab429656',
|
||||
'org.whispersystems:axolotl-android:40d3db5004a84749a73f68d2f0d01b2ae35a73c54df96d8c6c6723b96efb6fc0',
|
||||
'org.whispersystems:textsecure-java:b879094961f9ef0c851206223051e8478e6bbba0f039ea9340be20f40384bb20',
|
||||
'org.whispersystems:axolotl-java:6daee739b89d8d7101de6d98f77132fee48495c6ea647d880e77def842f999ea',
|
||||
'org.whispersystems:curve25519-android:3c29a4131a69b0d16baaa3d707678deb39602c3a3ffd75805ce7f9db252e5d0d',
|
||||
'com.googlecode.libphonenumber:libphonenumber:eba17eae81dd622ea89a00a3a8c025b2f25d342e0d9644c5b62e16f15687c3ab',
|
||||
'com.google.protobuf:protobuf-java:e0c1c64575c005601725e7c6a02cebf9e1285e888f756b2a1d73ffa8d725cc74',
|
||||
'com.squareup.okhttp:okhttp:89b7f63e2e5b6c410266abc14f50fe52ea8d2d8a57260829e499b1cd9f0e61af',
|
||||
'com.fasterxml.jackson.core:jackson-databind:835097bcdd11f5bc8a08378c70d4c8054dfa4b911691cc2752063c75534d198d',
|
||||
'org.whispersystems:axolotl-java:6daee739b89d8d7101de6d98f77132fee48495c6ea647d880e77def842f999ea',
|
||||
'org.whispersystems:curve25519-android:3c29a4131a69b0d16baaa3d707678deb39602c3a3ffd75805ce7f9db252e5d0d',
|
||||
'org.whispersystems:curve25519-java:9ccef8f5aba05d9942336f023c589d6278b4f9135bdc34a7bade1f4e7ad65fa3',
|
||||
'com.squareup.okio:okio:5e1098bd3fdee4c3347f5ab815b40ba851e4ab1b348c5e49a5b0362f0ce6e978',
|
||||
'com.fasterxml.jackson.core:jackson-annotations:0ca408c24202a7626ec8b861e99d85eca5e38b73311dd6dd12e3e9deecc3fe94',
|
||||
'com.fasterxml.jackson.core:jackson-core:cbf4604784b4de226262845447a1ad3bb38a6728cebe86562e2c5afada8be2c0',
|
||||
'org.whispersystems:curve25519-java:9ccef8f5aba05d9942336f023c589d6278b4f9135bdc34a7bade1f4e7ad65fa3',
|
||||
'com.android.support:support-v4:1e2e4d35ac7fd30db5ce3bc177b92e4d5af86acef2ef93e9221599d733346f56',
|
||||
'com.android.support:support-annotations:7bc07519aa613b186001160403bcfd68260fa82c61cc7e83adeedc9b862b94ae',
|
||||
]
|
||||
|
@ -61,13 +61,14 @@ public class EncryptingSmsDatabase extends SmsDatabase {
|
||||
}
|
||||
|
||||
public long insertMessageOutbox(MasterSecret masterSecret, long threadId,
|
||||
OutgoingTextMessage message, boolean forceSms)
|
||||
OutgoingTextMessage message, boolean forceSms,
|
||||
long timestamp)
|
||||
{
|
||||
long type = Types.BASE_OUTBOX_TYPE;
|
||||
message = message.withBody(getEncryptedBody(masterSecret, message.getMessageBody()));
|
||||
type |= Types.ENCRYPTION_SYMMETRIC_BIT;
|
||||
|
||||
return insertMessageOutbox(threadId, message, type, forceSms);
|
||||
return insertMessageOutbox(threadId, message, type, forceSms, timestamp);
|
||||
}
|
||||
|
||||
public Pair<Long, Long> insertMessageInbox(MasterSecret masterSecret,
|
||||
@ -100,10 +101,10 @@ public class EncryptingSmsDatabase extends SmsDatabase {
|
||||
return insertMessageInbox(message, type);
|
||||
}
|
||||
|
||||
public void updateBundleMessageBody(MasterSecret masterSecret, long messageId, String body) {
|
||||
public Pair<Long, Long> updateBundleMessageBody(MasterSecret masterSecret, long messageId, String body) {
|
||||
String encryptedBody = getEncryptedBody(masterSecret, body);
|
||||
updateMessageBodyAndType(messageId, encryptedBody, Types.TOTAL_MASK,
|
||||
Types.BASE_INBOX_TYPE | Types.ENCRYPTION_SYMMETRIC_BIT | Types.SECURE_MESSAGE_BIT);
|
||||
return updateMessageBodyAndType(messageId, encryptedBody, Types.TOTAL_MASK,
|
||||
Types.BASE_INBOX_TYPE | Types.ENCRYPTION_SYMMETRIC_BIT | Types.SECURE_MESSAGE_BIT);
|
||||
}
|
||||
|
||||
public void updateMessageBody(MasterSecret masterSecret, long messageId, String body) {
|
||||
|
@ -681,7 +681,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
}
|
||||
|
||||
public long insertMessageOutbox(MasterSecret masterSecret, OutgoingMediaMessage message,
|
||||
long threadId, boolean forceSms)
|
||||
long threadId, boolean forceSms, long timestamp)
|
||||
throws MmsException
|
||||
{
|
||||
long type = Types.BASE_OUTBOX_TYPE | Types.ENCRYPTION_SYMMETRIC_BIT;
|
||||
@ -695,7 +695,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
}
|
||||
|
||||
SendReq sendRequest = new SendReq();
|
||||
sendRequest.setDate(System.currentTimeMillis() / 1000L);
|
||||
sendRequest.setDate(timestamp / 1000L);
|
||||
sendRequest.setBody(message.getPduBody());
|
||||
sendRequest.setContentType(ContentType.MULTIPART_MIXED.getBytes());
|
||||
|
||||
|
@ -303,7 +303,7 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
database.update(TABLE_NAME, contentValues, null, null);
|
||||
}
|
||||
|
||||
protected void updateMessageBodyAndType(long messageId, String body, long maskOff, long maskOn) {
|
||||
protected Pair<Long, Long> updateMessageBodyAndType(long messageId, String body, long maskOff, long maskOn) {
|
||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||
db.execSQL("UPDATE " + TABLE_NAME + " SET " + BODY + " = ?, " +
|
||||
TYPE + " = (" + TYPE + " & " + (Types.TOTAL_MASK - maskOff) + " | " + maskOn + ") " +
|
||||
@ -315,6 +315,8 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
DatabaseFactory.getThreadDatabase(context).update(threadId);
|
||||
notifyConversationListeners(threadId);
|
||||
notifyConversationListListeners();
|
||||
|
||||
return new Pair<>(messageId, threadId);
|
||||
}
|
||||
|
||||
public Pair<Long, Long> copyMessageInbox(long messageId) {
|
||||
@ -421,15 +423,13 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
}
|
||||
|
||||
protected long insertMessageOutbox(long threadId, OutgoingTextMessage message,
|
||||
long type, boolean forceSms)
|
||||
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;
|
||||
|
||||
long date = System.currentTimeMillis();
|
||||
|
||||
ContentValues contentValues = new ContentValues(6);
|
||||
contentValues.put(ADDRESS, PhoneNumberUtils.formatNumber(message.getRecipients().getPrimaryRecipient().getNumber()));
|
||||
contentValues.put(THREAD_ID, threadId);
|
||||
|
@ -46,11 +46,6 @@ public class GroupMessageProcessor {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!message.isSecure()) {
|
||||
Log.w(TAG, "Received insecure group push action! Ignoring...");
|
||||
return;
|
||||
}
|
||||
|
||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||
TextSecureGroup group = message.getGroupInfo().get();
|
||||
byte[] id = group.getGroupId();
|
||||
|
@ -17,6 +17,8 @@ import org.thoughtcrime.securesms.database.PushDatabase;
|
||||
import org.thoughtcrime.securesms.groups.GroupMessageProcessor;
|
||||
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
|
||||
import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage;
|
||||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
@ -25,7 +27,9 @@ import org.thoughtcrime.securesms.sms.IncomingEncryptedMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingEndSessionMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingPreKeyBundleMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.jobqueue.JobParameters;
|
||||
import org.whispersystems.libaxolotl.DuplicateMessageException;
|
||||
@ -45,6 +49,8 @@ import org.whispersystems.textsecure.api.crypto.TextSecureCipher;
|
||||
import org.whispersystems.textsecure.api.messages.TextSecureEnvelope;
|
||||
import org.whispersystems.textsecure.api.messages.TextSecureGroup;
|
||||
import org.whispersystems.textsecure.api.messages.TextSecureMessage;
|
||||
import org.whispersystems.textsecure.api.messages.TextSecureSyncContext;
|
||||
import org.whispersystems.textsecure.api.push.TextSecureAddress;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -81,10 +87,12 @@ public class PushDecryptJob extends MasterSecretJob {
|
||||
|
||||
@Override
|
||||
public void onRun(MasterSecret masterSecret) throws NoSuchMessageException {
|
||||
PushDatabase database = DatabaseFactory.getPushDatabase(context);
|
||||
TextSecureEnvelope envelope = database.get(messageId);
|
||||
PushDatabase database = DatabaseFactory.getPushDatabase(context);
|
||||
TextSecureEnvelope envelope = database.get(messageId);
|
||||
Optional<Long> optionalSmsMessageId = smsMessageId > 0 ? Optional.of(smsMessageId) :
|
||||
Optional.<Long>absent();
|
||||
|
||||
handleMessage(masterSecret, envelope, smsMessageId);
|
||||
handleMessage(masterSecret, envelope, optionalSmsMessageId);
|
||||
database.delete(messageId);
|
||||
}
|
||||
|
||||
@ -98,10 +106,11 @@ public class PushDecryptJob extends MasterSecretJob {
|
||||
|
||||
}
|
||||
|
||||
private void handleMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, long smsMessageId) {
|
||||
private void handleMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, Optional<Long> smsMessageId) {
|
||||
try {
|
||||
AxolotlStore axolotlStore = new TextSecureAxolotlStore(context, masterSecret);
|
||||
TextSecureCipher cipher = new TextSecureCipher(axolotlStore);
|
||||
AxolotlStore axolotlStore = new TextSecureAxolotlStore(context, masterSecret);
|
||||
TextSecureAddress localAddress = new TextSecureAddress(TextSecurePreferences.getLocalNumber(context));
|
||||
TextSecureCipher cipher = new TextSecureCipher(localAddress, axolotlStore);
|
||||
|
||||
TextSecureMessage message = cipher.decrypt(envelope);
|
||||
|
||||
@ -135,7 +144,7 @@ public class PushDecryptJob extends MasterSecretJob {
|
||||
}
|
||||
|
||||
private void handleEndSessionMessage(MasterSecret masterSecret, TextSecureEnvelope envelope,
|
||||
TextSecureMessage message, long smsMessageId)
|
||||
TextSecureMessage message, Optional<Long> smsMessageId)
|
||||
{
|
||||
EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context);
|
||||
IncomingTextMessage incomingTextMessage = new IncomingTextMessage(envelope.getSource(),
|
||||
@ -145,13 +154,13 @@ public class PushDecryptJob extends MasterSecretJob {
|
||||
|
||||
long threadId;
|
||||
|
||||
if (smsMessageId <= 0) {
|
||||
if (!smsMessageId.isPresent()) {
|
||||
IncomingEndSessionMessage incomingEndSessionMessage = new IncomingEndSessionMessage(incomingTextMessage);
|
||||
Pair<Long, Long> messageAndThreadId = smsDatabase.insertMessageInbox(masterSecret, incomingEndSessionMessage);
|
||||
threadId = messageAndThreadId.second;
|
||||
} else {
|
||||
smsDatabase.markAsEndSession(smsMessageId);
|
||||
threadId = smsDatabase.getThreadIdForMessage(smsMessageId);
|
||||
smsDatabase.markAsEndSession(smsMessageId.get());
|
||||
threadId = smsDatabase.getThreadIdForMessage(smsMessageId.get());
|
||||
}
|
||||
|
||||
SessionStore sessionStore = new TextSecureSessionStore(context, masterSecret);
|
||||
@ -161,117 +170,100 @@ public class PushDecryptJob extends MasterSecretJob {
|
||||
MessageNotifier.updateNotification(context, masterSecret, threadId);
|
||||
}
|
||||
|
||||
private void handleGroupMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, TextSecureMessage message, long smsMessageId) {
|
||||
private void handleGroupMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, TextSecureMessage message, Optional<Long> smsMessageId) {
|
||||
GroupMessageProcessor.process(context, masterSecret, envelope, message);
|
||||
|
||||
if (smsMessageId > 0) {
|
||||
DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId);
|
||||
if (smsMessageId.isPresent()) {
|
||||
DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMediaMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, TextSecureMessage message, long smsMessageId)
|
||||
private void handleMediaMessage(MasterSecret masterSecret, TextSecureEnvelope envelope,
|
||||
TextSecureMessage message, Optional<Long> smsMessageId)
|
||||
throws MmsException
|
||||
{
|
||||
String localNumber = TextSecurePreferences.getLocalNumber(context);
|
||||
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
||||
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(masterSecret, envelope.getSource(),
|
||||
localNumber, message.getTimestamp(),
|
||||
Optional.fromNullable(envelope.getRelay()),
|
||||
message.getBody(),
|
||||
message.getGroupInfo(),
|
||||
message.getAttachments());
|
||||
|
||||
Pair<Long, Long> messageAndThreadId;
|
||||
|
||||
if (message.isSecure()) {
|
||||
messageAndThreadId = database.insertSecureDecryptedMessageInbox(masterSecret, mediaMessage, -1);
|
||||
if (message.getSyncContext().isPresent()) {
|
||||
messageAndThreadId = insertSyncMediaMessage(masterSecret, envelope, message);
|
||||
} else {
|
||||
messageAndThreadId = database.insertMessageInbox(masterSecret, mediaMessage, null, -1);
|
||||
messageAndThreadId = insertStandardMediaMessage(masterSecret, envelope, message);
|
||||
}
|
||||
|
||||
ApplicationContext.getInstance(context)
|
||||
.getJobManager()
|
||||
.add(new AttachmentDownloadJob(context, messageAndThreadId.first));
|
||||
|
||||
if (smsMessageId >= 0) {
|
||||
DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId);
|
||||
if (smsMessageId.isPresent()) {
|
||||
DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get());
|
||||
}
|
||||
|
||||
MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
|
||||
}
|
||||
|
||||
private void handleTextMessage(MasterSecret masterSecret, TextSecureEnvelope envelope,
|
||||
TextSecureMessage message, long smsMessageId)
|
||||
TextSecureMessage message, Optional<Long> smsMessageId)
|
||||
{
|
||||
EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
|
||||
String body = message.getBody().isPresent() ? message.getBody().get() : "";
|
||||
Pair<Long, Long> messageAndThreadId;
|
||||
|
||||
if (smsMessageId > 0) {
|
||||
database.updateBundleMessageBody(masterSecret, smsMessageId, body);
|
||||
if (message.getSyncContext().isPresent()) {
|
||||
messageAndThreadId = insertSyncTextMessage(masterSecret, envelope, message, smsMessageId);
|
||||
} else {
|
||||
IncomingTextMessage textMessage = new IncomingTextMessage(envelope.getSource(),
|
||||
envelope.getSourceDevice(),
|
||||
message.getTimestamp(), body,
|
||||
message.getGroupInfo());
|
||||
|
||||
if (message.isSecure()) {
|
||||
textMessage = new IncomingEncryptedMessage(textMessage, body);
|
||||
}
|
||||
|
||||
Pair<Long, Long> messageAndThreadId = database.insertMessageInbox(masterSecret, textMessage);
|
||||
MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
|
||||
messageAndThreadId = insertStandardTextMessage(masterSecret, envelope, message, smsMessageId);
|
||||
}
|
||||
|
||||
MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
|
||||
}
|
||||
|
||||
private void handleInvalidVersionMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, long smsMessageId) {
|
||||
private void handleInvalidVersionMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, Optional<Long> smsMessageId) {
|
||||
EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context);
|
||||
|
||||
if (smsMessageId <= 0) {
|
||||
if (!smsMessageId.isPresent()) {
|
||||
Pair<Long, Long> messageAndThreadId = insertPlaceholder(masterSecret, envelope);
|
||||
smsDatabase.markAsInvalidVersionKeyExchange(messageAndThreadId.first);
|
||||
MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
|
||||
} else {
|
||||
smsDatabase.markAsInvalidVersionKeyExchange(smsMessageId);
|
||||
smsDatabase.markAsInvalidVersionKeyExchange(smsMessageId.get());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleCorruptMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, long smsMessageId) {
|
||||
private void handleCorruptMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, Optional<Long> smsMessageId) {
|
||||
EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context);
|
||||
|
||||
if (smsMessageId <= 0) {
|
||||
if (!smsMessageId.isPresent()) {
|
||||
Pair<Long, Long> messageAndThreadId = insertPlaceholder(masterSecret, envelope);
|
||||
smsDatabase.markAsDecryptFailed(messageAndThreadId.first);
|
||||
MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
|
||||
} else {
|
||||
smsDatabase.markAsDecryptFailed(smsMessageId);
|
||||
smsDatabase.markAsDecryptFailed(smsMessageId.get());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleNoSessionMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, long smsMessageId) {
|
||||
private void handleNoSessionMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, Optional<Long> smsMessageId) {
|
||||
EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context);
|
||||
|
||||
if (smsMessageId <= 0) {
|
||||
if (!smsMessageId.isPresent()) {
|
||||
Pair<Long, Long> messageAndThreadId = insertPlaceholder(masterSecret, envelope);
|
||||
smsDatabase.markAsNoSession(messageAndThreadId.first);
|
||||
MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
|
||||
} else {
|
||||
smsDatabase.markAsNoSession(smsMessageId);
|
||||
smsDatabase.markAsNoSession(smsMessageId.get());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleLegacyMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, long smsMessageId) {
|
||||
private void handleLegacyMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, Optional<Long> smsMessageId) {
|
||||
EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context);
|
||||
|
||||
if (smsMessageId <= 0) {
|
||||
if (!smsMessageId.isPresent()) {
|
||||
Pair<Long, Long> messageAndThreadId = insertPlaceholder(masterSecret, envelope);
|
||||
smsDatabase.markAsLegacyVersion(messageAndThreadId.first);
|
||||
MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
|
||||
} else {
|
||||
smsDatabase.markAsLegacyVersion(smsMessageId);
|
||||
smsDatabase.markAsLegacyVersion(smsMessageId.get());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDuplicateMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, long smsMessageId) {
|
||||
private void handleDuplicateMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, Optional<Long> smsMessageId) {
|
||||
// Let's start ignoring these now
|
||||
// SmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context);
|
||||
//
|
||||
@ -284,7 +276,7 @@ public class PushDecryptJob extends MasterSecretJob {
|
||||
// }
|
||||
}
|
||||
|
||||
private void handleUntrustedIdentityMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, long smsMessageId) {
|
||||
private void handleUntrustedIdentityMessage(MasterSecret masterSecret, TextSecureEnvelope envelope, Optional<Long> smsMessageId) {
|
||||
try {
|
||||
EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
|
||||
Recipients recipients = RecipientFactory.getRecipientsFromString(context, envelope.getSource(), false);
|
||||
@ -296,16 +288,16 @@ public class PushDecryptJob extends MasterSecretJob {
|
||||
envelope.getTimestamp(), encoded,
|
||||
Optional.<TextSecureGroup>absent());
|
||||
|
||||
if (smsMessageId <= 0) {
|
||||
if (!smsMessageId.isPresent()) {
|
||||
IncomingPreKeyBundleMessage bundleMessage = new IncomingPreKeyBundleMessage(textMessage, encoded);
|
||||
Pair<Long, Long> messageAndThreadId = database.insertMessageInbox(masterSecret, bundleMessage);
|
||||
|
||||
database.addMismatchedIdentity(messageAndThreadId.first, recipientId, identityKey);
|
||||
MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
|
||||
} else {
|
||||
database.updateMessageBody(masterSecret, smsMessageId, encoded);
|
||||
database.markAsPreKeyBundle(smsMessageId);
|
||||
database.addMismatchedIdentity(smsMessageId, recipientId, identityKey);
|
||||
database.updateMessageBody(masterSecret, smsMessageId.get(), encoded);
|
||||
database.markAsPreKeyBundle(smsMessageId.get());
|
||||
database.addMismatchedIdentity(smsMessageId.get(), recipientId, identityKey);
|
||||
}
|
||||
} catch (InvalidMessageException | InvalidVersionException e) {
|
||||
throw new AssertionError(e);
|
||||
@ -323,4 +315,98 @@ public class PushDecryptJob extends MasterSecretJob {
|
||||
|
||||
return database.insertMessageInbox(masterSecret, textMessage);
|
||||
}
|
||||
|
||||
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 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 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> 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);
|
||||
}
|
||||
|
||||
private Recipients getSyncMessageDestination(TextSecureMessage message) {
|
||||
if (message.getGroupInfo().isPresent()) {
|
||||
return RecipientFactory.getRecipientsFromString(context, GroupUtil.getEncodedId(message.getGroupInfo().get().getGroupId()), false);
|
||||
} else {
|
||||
return RecipientFactory.getRecipientsFromString(context, message.getSyncContext().get().getDestination(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,18 @@ package org.thoughtcrime.securesms.mms;
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.textsecure.api.messages.TextSecureAttachment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ws.com.google.android.mms.pdu.PduBody;
|
||||
import ws.com.google.android.mms.pdu.PduPart;
|
||||
|
||||
public class OutgoingMediaMessage {
|
||||
|
||||
@ -31,6 +40,14 @@ public class OutgoingMediaMessage {
|
||||
this(context, recipients, slideDeck.toPduBody(), message, distributionType);
|
||||
}
|
||||
|
||||
public OutgoingMediaMessage(Context context, MasterSecret masterSecret,
|
||||
Recipients recipients, List<TextSecureAttachment> attachments,
|
||||
String message)
|
||||
{
|
||||
this(context, recipients, pduBodyFor(masterSecret, attachments), message,
|
||||
ThreadDatabase.DistributionTypes.CONVERSATION);
|
||||
}
|
||||
|
||||
public OutgoingMediaMessage(OutgoingMediaMessage that) {
|
||||
this.recipients = that.getRecipients();
|
||||
this.body = that.body;
|
||||
@ -57,4 +74,24 @@ public class OutgoingMediaMessage {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static PduBody pduBodyFor(MasterSecret masterSecret, List<TextSecureAttachment> attachments) {
|
||||
PduBody body = new PduBody();
|
||||
|
||||
for (TextSecureAttachment attachment : attachments) {
|
||||
if (attachment.isPointer()) {
|
||||
PduPart media = new PduPart();
|
||||
byte[] encryptedKey = new MasterCipher(masterSecret).encryptBytes(attachment.asPointer().getKey());
|
||||
|
||||
media.setContentType(Util.toIsoBytes(attachment.getContentType()));
|
||||
media.setContentLocation(Util.toIsoBytes(String.valueOf(attachment.asPointer().getId())));
|
||||
media.setContentDisposition(Util.toIsoBytes(Base64.encodeBytes(encryptedKey)));
|
||||
media.setPendingPush(true);
|
||||
|
||||
body.addPart(media);
|
||||
}
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public class MessageSender {
|
||||
allocatedThreadId = threadId;
|
||||
}
|
||||
|
||||
long messageId = database.insertMessageOutbox(masterSecret, allocatedThreadId, message, forceSms);
|
||||
long messageId = database.insertMessageOutbox(masterSecret, allocatedThreadId, message, forceSms, System.currentTimeMillis());
|
||||
|
||||
sendTextMessage(context, recipients, forceSms, keyExchange, messageId);
|
||||
|
||||
@ -99,7 +99,7 @@ public class MessageSender {
|
||||
}
|
||||
|
||||
Recipients recipients = message.getRecipients();
|
||||
long messageId = database.insertMessageOutbox(masterSecret, message, allocatedThreadId, forceSms);
|
||||
long messageId = database.insertMessageOutbox(masterSecret, message, allocatedThreadId, forceSms, System.currentTimeMillis());
|
||||
|
||||
sendMediaMessage(context, masterSecret, recipients, forceSms, messageId);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user