mirror of
https://github.com/oxen-io/session-android.git
synced 2025-10-25 00:49:32 +00:00
Support for multi-device.
1) In addition to the Recipient interface, there is now RecipientDevice. A Recipient can have multiple corresponding RecipientDevices. All addressing is done to a Recipient, but crypto sessions and transport delivery are done to RecipientDevice. 2) The Push transport handles the discovery and session setup of additional Recipient devices. 3) Some internal rejiggering of Groups.
This commit is contained in:
@@ -644,6 +644,9 @@ public class DatabaseFactory {
|
||||
if (oldVersion < INTRODUCED_GROUP_DATABASE_VERSION) {
|
||||
db.execSQL("CREATE TABLE groups (_id INTEGER PRIMARY KEY, group_id TEXT, owner TEXT, title TEXT, members TEXT, avatar BLOB, avatar_id INTEGER, avatar_key BLOB, avatar_content_type TEXT, timestamp INTEGER);");
|
||||
db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS group_id_index ON groups (GROUP_ID);");
|
||||
db.execSQL("ALTER TABLE push ADD COLUMN device_id INTEGER DEFAULT 1;");
|
||||
db.execSQL("ALTER TABLE sms ADD COLUMN address_device_id INTEGER DEFAULT 1;");
|
||||
db.execSQL("ALTER TABLE mms ADD COLUMN address_device_id INTEGER DEFAULT 1;");
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
|
||||
@@ -6,11 +6,18 @@ import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.graphics.Bitmap;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.whispersystems.textsecure.util.Hex;
|
||||
import org.whispersystems.textsecure.util.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -28,7 +35,7 @@ public class GroupDatabase extends Database {
|
||||
private static final String AVATAR_ID = "avatar_id";
|
||||
private static final String AVATAR_KEY = "avatar_key";
|
||||
private static final String AVATAR_CONTENT_TYPE = "avatar_content_type";
|
||||
private static final String RELAY = "relay";
|
||||
private static final String AVATAR_RELAY = "avatar_relay";
|
||||
private static final String TIMESTAMP = "timestamp";
|
||||
|
||||
public static final String CREATE_TABLE =
|
||||
@@ -42,6 +49,7 @@ public class GroupDatabase extends Database {
|
||||
AVATAR_ID + " INTEGER, " +
|
||||
AVATAR_KEY + " BLOB, " +
|
||||
AVATAR_CONTENT_TYPE + " TEXT, " +
|
||||
AVATAR_RELAY + " TEXT, " +
|
||||
TIMESTAMP + " INTEGER);";
|
||||
|
||||
public static final String[] CREATE_INDEXS = {
|
||||
@@ -52,19 +60,36 @@ public class GroupDatabase extends Database {
|
||||
super(context, databaseHelper);
|
||||
}
|
||||
|
||||
public Reader getGroup(String groupId) {
|
||||
public Reader getGroup(byte[] groupId) {
|
||||
Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, null, GROUP_ID + " = ?",
|
||||
new String[] {groupId}, null, null, null);
|
||||
new String[] {GroupUtil.getEncodedId(groupId)},
|
||||
null, null, null);
|
||||
|
||||
return new Reader(cursor);
|
||||
}
|
||||
|
||||
public Recipients getGroupMembers(byte[] groupId) {
|
||||
List<String> members = getCurrentMembers(groupId);
|
||||
List<Recipient> recipients = new LinkedList<Recipient>();
|
||||
|
||||
for (String member : members) {
|
||||
try {
|
||||
recipients.addAll(RecipientFactory.getRecipientsFromString(context, member, true)
|
||||
.getRecipientsList());
|
||||
} catch (RecipientFormattingException e) {
|
||||
Log.w("GroupDatabase", e);
|
||||
}
|
||||
}
|
||||
|
||||
return new Recipients(recipients);
|
||||
}
|
||||
|
||||
public void create(byte[] groupId, String owner, String title,
|
||||
List<String> members, AttachmentPointer avatar,
|
||||
String relay)
|
||||
{
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(GROUP_ID, Hex.toString(groupId));
|
||||
contentValues.put(GROUP_ID, GroupUtil.getEncodedId(groupId));
|
||||
contentValues.put(OWNER, owner);
|
||||
contentValues.put(TITLE, title);
|
||||
contentValues.put(MEMBERS, Util.join(members, ","));
|
||||
@@ -75,7 +100,7 @@ public class GroupDatabase extends Database {
|
||||
contentValues.put(AVATAR_CONTENT_TYPE, avatar.getContentType());
|
||||
}
|
||||
|
||||
contentValues.put(RELAY, relay);
|
||||
contentValues.put(AVATAR_RELAY, relay);
|
||||
contentValues.put(TIMESTAMP, System.currentTimeMillis());
|
||||
|
||||
databaseHelper.getWritableDatabase().insert(TABLE_NAME, null, contentValues);
|
||||
@@ -93,14 +118,15 @@ public class GroupDatabase extends Database {
|
||||
|
||||
databaseHelper.getWritableDatabase().update(TABLE_NAME, contentValues,
|
||||
GROUP_ID + " = ? AND " + OWNER + " = ?",
|
||||
new String[] {Hex.toString(groupId), source});
|
||||
new String[] {GroupUtil.getEncodedId(groupId), source});
|
||||
}
|
||||
|
||||
public void updateAvatar(String groupId, Bitmap avatar) {
|
||||
public void updateAvatar(byte[] groupId, Bitmap avatar) {
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(AVATAR, BitmapUtil.toByteArray(avatar));
|
||||
|
||||
databaseHelper.getWritableDatabase().update(TABLE_NAME, contentValues, GROUP_ID + " = ?", new String[] {groupId});
|
||||
databaseHelper.getWritableDatabase().update(TABLE_NAME, contentValues, GROUP_ID + " = ?",
|
||||
new String[] {GroupUtil.getEncodedId(groupId)});
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +198,7 @@ public class GroupDatabase extends Database {
|
||||
cursor.getLong(cursor.getColumnIndexOrThrow(AVATAR_ID)),
|
||||
cursor.getBlob(cursor.getColumnIndexOrThrow(AVATAR_KEY)),
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(AVATAR_CONTENT_TYPE)),
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(RELAY)));
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(AVATAR_RELAY)));
|
||||
}
|
||||
|
||||
public void close() {
|
||||
@@ -206,8 +232,12 @@ public class GroupDatabase extends Database {
|
||||
this.relay = relay;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
public byte[] getId() {
|
||||
try {
|
||||
return GroupUtil.getDecodedId(id);
|
||||
} catch (IOException ioe) {
|
||||
throw new AssertionError(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
|
||||
@@ -67,12 +67,10 @@ public class IdentityDatabase extends Database {
|
||||
}
|
||||
|
||||
public boolean isValidIdentity(MasterSecret masterSecret,
|
||||
Recipient recipient,
|
||||
long recipientId,
|
||||
IdentityKey theirIdentity)
|
||||
{
|
||||
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
||||
String number = recipient.getNumber();
|
||||
long recipientId = DatabaseFactory.getAddressDatabase(context).getCanonicalAddress(number);
|
||||
MasterCipher masterCipher = new MasterCipher(masterSecret);
|
||||
Cursor cursor = null;
|
||||
|
||||
@@ -114,11 +112,9 @@ public class IdentityDatabase extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
public void saveIdentity(MasterSecret masterSecret, Recipient recipient, IdentityKey identityKey)
|
||||
public void saveIdentity(MasterSecret masterSecret, long recipientId, IdentityKey identityKey)
|
||||
{
|
||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||
String number = recipient.getNumber();
|
||||
long recipientId = DatabaseFactory.getAddressDatabase(context).getCanonicalAddress(number);
|
||||
MasterCipher masterCipher = new MasterCipher(masterSecret);
|
||||
String identityKeyString = Base64.encodeBytes(identityKey.serialize());
|
||||
String macString = Base64.encodeBytes(masterCipher.getMacFor(recipientId +
|
||||
|
||||
@@ -109,6 +109,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
READ + " INTEGER DEFAULT 0, " + MESSAGE_ID + " TEXT, " + SUBJECT + " TEXT, " +
|
||||
SUBJECT_CHARSET + " INTEGER, " + BODY + " TEXT, " + PART_COUNT + " INTEGER, " +
|
||||
CONTENT_TYPE + " TEXT, " + CONTENT_LOCATION + " TEXT, " + ADDRESS + " TEXT, " +
|
||||
ADDRESS_DEVICE_ID + " INTEGER, " +
|
||||
EXPIRY + " INTEGER, " + MESSAGE_CLASS + " TEXT, " + MESSAGE_TYPE + " INTEGER, " +
|
||||
MMS_VERSION + " INTEGER, " + MESSAGE_SIZE + " INTEGER, " + PRIORITY + " INTEGER, " +
|
||||
READ_REPORT + " INTEGER, " + REPORT_ALLOWED + " INTEGER, " + RESPONSE_STATUS + " INTEGER, " +
|
||||
@@ -131,7 +132,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
CONTENT_LOCATION, EXPIRY, MESSAGE_CLASS, MESSAGE_TYPE, MMS_VERSION,
|
||||
MESSAGE_SIZE, PRIORITY, REPORT_ALLOWED, STATUS, TRANSACTION_ID, RETRIEVE_STATUS,
|
||||
RETRIEVE_TEXT, RETRIEVE_TEXT_CS, READ_STATUS, CONTENT_CLASS, RESPONSE_TEXT,
|
||||
DELIVERY_TIME, DELIVERY_REPORT, BODY, PART_COUNT, ADDRESS
|
||||
DELIVERY_TIME, DELIVERY_REPORT, BODY, PART_COUNT, ADDRESS, ADDRESS_DEVICE_ID
|
||||
};
|
||||
|
||||
public static final ExecutorService slideResolver = org.thoughtcrime.securesms.util.Util.newSingleThreadedLifoExecutor();
|
||||
@@ -788,6 +789,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.THREAD_ID));
|
||||
long mailbox = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.MESSAGE_BOX));
|
||||
String address = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS));
|
||||
int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS_DEVICE_ID));
|
||||
Recipients recipients = getRecipientsFor(address);
|
||||
|
||||
String contentLocation = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.CONTENT_LOCATION));
|
||||
@@ -807,8 +809,9 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
|
||||
|
||||
return new NotificationMmsMessageRecord(context, id, recipients, recipients.getPrimaryRecipient(),
|
||||
dateSent, dateReceived, threadId, contentLocationBytes,
|
||||
messageSize, expiry, status, transactionIdBytes, mailbox);
|
||||
addressDeviceId, dateSent, dateReceived, threadId,
|
||||
contentLocationBytes, messageSize, expiry, status,
|
||||
transactionIdBytes, mailbox);
|
||||
}
|
||||
|
||||
private MediaMmsMessageRecord getMediaMmsMessageRecord(Cursor cursor) {
|
||||
@@ -818,6 +821,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
long box = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.MESSAGE_BOX));
|
||||
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.THREAD_ID));
|
||||
String address = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS));
|
||||
int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS_DEVICE_ID));
|
||||
DisplayRecord.Body body = getBody(cursor);
|
||||
int partCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.PART_COUNT));
|
||||
Recipients recipients = getRecipientsFor(address);
|
||||
@@ -825,29 +829,26 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
ListenableFutureTask<SlideDeck> slideDeck = getSlideDeck(masterSecret, id);
|
||||
|
||||
return new MediaMmsMessageRecord(context, id, recipients, recipients.getPrimaryRecipient(),
|
||||
dateSent, dateReceived, threadId, body,
|
||||
addressDeviceId, dateSent, dateReceived, threadId, body,
|
||||
slideDeck, partCount, box);
|
||||
}
|
||||
|
||||
private Recipients getRecipientsFor(String address) {
|
||||
try {
|
||||
if (Util.isEmpty(address) || address.equals("insert-address-token")) {
|
||||
return new Recipients(new Recipient("Unknown", "Unknown", null,
|
||||
ContactPhotoFactory.getDefaultContactPhoto(context)));
|
||||
return new Recipients(Recipient.getUnknownRecipient(context));
|
||||
}
|
||||
|
||||
Recipients recipients = RecipientFactory.getRecipientsFromString(context, address, false);
|
||||
|
||||
if (recipients == null || recipients.isEmpty()) {
|
||||
return new Recipients(new Recipient("Unknown", "Unknown", null,
|
||||
ContactPhotoFactory.getDefaultContactPhoto(context)));
|
||||
return new Recipients(Recipient.getUnknownRecipient(context));
|
||||
}
|
||||
|
||||
return recipients;
|
||||
} catch (RecipientFormattingException e) {
|
||||
Log.w("MmsDatabase", e);
|
||||
return new Recipients(new Recipient("Unknown", "Unknown", null,
|
||||
ContactPhotoFactory.getDefaultContactPhoto(context)));
|
||||
return new Recipients(Recipient.getUnknownRecipient(context));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ public interface MmsSmsColumns {
|
||||
public static final String THREAD_ID = "thread_id";
|
||||
public static final String READ = "read";
|
||||
public static final String BODY = "body";
|
||||
public static final String ADDRESS = "address";
|
||||
public static final String ADDRESS = "address";
|
||||
public static final String ADDRESS_DEVICE_ID = "address_device_id";
|
||||
|
||||
|
||||
public static class Types {
|
||||
|
||||
@@ -42,7 +42,7 @@ public class MmsSmsDatabase extends Database {
|
||||
public Cursor getConversation(long threadId) {
|
||||
String[] projection = {MmsSmsColumns.ID, SmsDatabase.BODY, SmsDatabase.TYPE,
|
||||
MmsSmsColumns.THREAD_ID,
|
||||
SmsDatabase.ADDRESS, SmsDatabase.SUBJECT,
|
||||
SmsDatabase.ADDRESS, SmsDatabase.ADDRESS_DEVICE_ID, SmsDatabase.SUBJECT,
|
||||
MmsSmsColumns.NORMALIZED_DATE_SENT,
|
||||
MmsSmsColumns.NORMALIZED_DATE_RECEIVED,
|
||||
MmsDatabase.MESSAGE_TYPE, MmsDatabase.MESSAGE_BOX,
|
||||
@@ -64,7 +64,7 @@ public class MmsSmsDatabase extends Database {
|
||||
public Cursor getConversationSnippet(long threadId) {
|
||||
String[] projection = {MmsSmsColumns.ID, SmsDatabase.BODY, SmsDatabase.TYPE,
|
||||
MmsSmsColumns.THREAD_ID,
|
||||
SmsDatabase.ADDRESS, SmsDatabase.SUBJECT,
|
||||
SmsDatabase.ADDRESS, SmsDatabase.ADDRESS_DEVICE_ID, SmsDatabase.SUBJECT,
|
||||
MmsSmsColumns.NORMALIZED_DATE_SENT,
|
||||
MmsSmsColumns.NORMALIZED_DATE_RECEIVED,
|
||||
MmsDatabase.MESSAGE_TYPE, MmsDatabase.MESSAGE_BOX,
|
||||
@@ -81,7 +81,7 @@ public class MmsSmsDatabase extends Database {
|
||||
|
||||
public Cursor getUnread() {
|
||||
String[] projection = {MmsSmsColumns.ID, SmsDatabase.BODY, SmsDatabase.READ, SmsDatabase.TYPE,
|
||||
SmsDatabase.ADDRESS, SmsDatabase.SUBJECT, MmsSmsColumns.THREAD_ID,
|
||||
SmsDatabase.ADDRESS, SmsDatabase.ADDRESS_DEVICE_ID, SmsDatabase.SUBJECT, MmsSmsColumns.THREAD_ID,
|
||||
SmsDatabase.STATUS,
|
||||
MmsSmsColumns.NORMALIZED_DATE_SENT,
|
||||
MmsSmsColumns.NORMALIZED_DATE_RECEIVED,
|
||||
@@ -108,7 +108,7 @@ public class MmsSmsDatabase extends Database {
|
||||
String[] mmsProjection = {MmsDatabase.DATE_SENT + " * 1000 AS " + MmsSmsColumns.NORMALIZED_DATE_SENT,
|
||||
MmsDatabase.DATE_RECEIVED + " * 1000 AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED,
|
||||
MmsSmsColumns.ID, SmsDatabase.BODY, MmsSmsColumns.READ, MmsSmsColumns.THREAD_ID,
|
||||
SmsDatabase.TYPE, SmsDatabase.ADDRESS, SmsDatabase.SUBJECT, MmsDatabase.MESSAGE_TYPE,
|
||||
SmsDatabase.TYPE, SmsDatabase.ADDRESS, SmsDatabase.ADDRESS_DEVICE_ID, SmsDatabase.SUBJECT, MmsDatabase.MESSAGE_TYPE,
|
||||
MmsDatabase.MESSAGE_BOX, SmsDatabase.STATUS, MmsDatabase.PART_COUNT,
|
||||
MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID,
|
||||
MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, MmsDatabase.STATUS,
|
||||
@@ -117,7 +117,7 @@ public class MmsSmsDatabase extends Database {
|
||||
String[] smsProjection = {SmsDatabase.DATE_SENT + " * 1 AS " + MmsSmsColumns.NORMALIZED_DATE_SENT,
|
||||
SmsDatabase.DATE_RECEIVED + " * 1 AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED,
|
||||
MmsSmsColumns.ID, SmsDatabase.BODY, MmsSmsColumns.READ, MmsSmsColumns.THREAD_ID,
|
||||
SmsDatabase.TYPE, SmsDatabase.ADDRESS, SmsDatabase.SUBJECT, MmsDatabase.MESSAGE_TYPE,
|
||||
SmsDatabase.TYPE, SmsDatabase.ADDRESS, SmsDatabase.ADDRESS_DEVICE_ID, SmsDatabase.SUBJECT, MmsDatabase.MESSAGE_TYPE,
|
||||
MmsDatabase.MESSAGE_BOX, SmsDatabase.STATUS, MmsDatabase.PART_COUNT,
|
||||
MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID,
|
||||
MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, MmsDatabase.STATUS,
|
||||
@@ -139,6 +139,7 @@ public class MmsSmsDatabase extends Database {
|
||||
mmsColumnsPresent.add(MmsSmsColumns.THREAD_ID);
|
||||
mmsColumnsPresent.add(MmsSmsColumns.BODY);
|
||||
mmsColumnsPresent.add(MmsSmsColumns.ADDRESS);
|
||||
mmsColumnsPresent.add(MmsSmsColumns.ADDRESS_DEVICE_ID);
|
||||
mmsColumnsPresent.add(MmsDatabase.MESSAGE_TYPE);
|
||||
mmsColumnsPresent.add(MmsDatabase.MESSAGE_BOX);
|
||||
mmsColumnsPresent.add(MmsDatabase.DATE_SENT);
|
||||
@@ -154,6 +155,7 @@ public class MmsSmsDatabase extends Database {
|
||||
smsColumnsPresent.add(MmsSmsColumns.ID);
|
||||
smsColumnsPresent.add(MmsSmsColumns.BODY);
|
||||
smsColumnsPresent.add(MmsSmsColumns.ADDRESS);
|
||||
smsColumnsPresent.add(MmsSmsColumns.ADDRESS_DEVICE_ID);
|
||||
smsColumnsPresent.add(MmsSmsColumns.READ);
|
||||
smsColumnsPresent.add(MmsSmsColumns.THREAD_ID);
|
||||
smsColumnsPresent.add(SmsDatabase.TYPE);
|
||||
|
||||
@@ -18,11 +18,12 @@ public class PushDatabase extends Database {
|
||||
public static final String ID = "_id";
|
||||
public static final String TYPE = "type";
|
||||
public static final String SOURCE = "source";
|
||||
public static final String DEVICE_ID = "device_id";
|
||||
public static final String BODY = "body";
|
||||
public static final String TIMESTAMP = "timestamp";
|
||||
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " +
|
||||
TYPE + " INTEGER, " + SOURCE + " TEXT, " + BODY + " TEXT, " + TIMESTAMP + " INTEGER);";
|
||||
TYPE + " INTEGER, " + SOURCE + " TEXT, " + DEVICE_ID + " INTEGER, " + BODY + " TEXT, " + TIMESTAMP + " INTEGER);";
|
||||
|
||||
public PushDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
||||
super(context, databaseHelper);
|
||||
@@ -64,10 +65,11 @@ public class PushDatabase extends Database {
|
||||
|
||||
int type = cursor.getInt(cursor.getColumnIndexOrThrow(TYPE));
|
||||
String source = cursor.getString(cursor.getColumnIndexOrThrow(SOURCE));
|
||||
int deviceId = cursor.getInt(cursor.getColumnIndexOrThrow(DEVICE_ID));
|
||||
byte[] body = Base64.decode(cursor.getString(cursor.getColumnIndexOrThrow(BODY)));
|
||||
long timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP));
|
||||
|
||||
return new IncomingPushMessage(type, source, body, timestamp);
|
||||
return new IncomingPushMessage(type, source, deviceId, body, timestamp);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
@@ -63,8 +63,8 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
|
||||
public static final String SERVICE_CENTER = "service_center";
|
||||
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " integer PRIMARY KEY, " +
|
||||
THREAD_ID + " INTEGER, " + ADDRESS + " TEXT, " + PERSON + " INTEGER, " + DATE_RECEIVED + " INTEGER, " +
|
||||
DATE_SENT + " INTEGER, " + PROTOCOL + " INTEGER, " + READ + " INTEGER DEFAULT 0, " +
|
||||
THREAD_ID + " INTEGER, " + ADDRESS + " TEXT, " + ADDRESS_DEVICE_ID + " INTEGER DEFAULT 1, " + PERSON + " INTEGER, " +
|
||||
DATE_RECEIVED + " INTEGER, " + DATE_SENT + " INTEGER, " + PROTOCOL + " INTEGER, " + READ + " INTEGER DEFAULT 0, " +
|
||||
STATUS + " INTEGER DEFAULT -1," + TYPE + " INTEGER, " + REPLY_PATH_PRESENT + " INTEGER, " +
|
||||
SUBJECT + " TEXT, " + BODY + " TEXT, " + SERVICE_CENTER + " TEXT);";
|
||||
|
||||
@@ -76,7 +76,7 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
|
||||
};
|
||||
|
||||
private static final String[] MESSAGE_PROJECTION = new String[] {
|
||||
ID, THREAD_ID, ADDRESS, PERSON,
|
||||
ID, THREAD_ID, ADDRESS, ADDRESS_DEVICE_ID, PERSON,
|
||||
DATE_RECEIVED + " AS " + NORMALIZED_DATE_RECEIVED,
|
||||
DATE_SENT + " AS " + NORMALIZED_DATE_SENT,
|
||||
PROTOCOL, READ, STATUS, TYPE,
|
||||
@@ -257,19 +257,39 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
|
||||
type |= Types.ENCRYPTION_REMOTE_BIT;
|
||||
}
|
||||
|
||||
Recipient recipient = new Recipient(null, message.getSender(), null, null);
|
||||
Recipients recipients = new Recipients(recipient);
|
||||
String groupId = message.getGroupId();
|
||||
Recipients recipients;
|
||||
|
||||
try {
|
||||
recipients = RecipientFactory.getRecipientsFromString(context, message.getSender(), true);
|
||||
} catch (RecipientFormattingException e) {
|
||||
Log.w("SmsDatabase", e);
|
||||
recipients = new Recipients(Recipient.getUnknownRecipient(context));
|
||||
}
|
||||
|
||||
Recipients groupRecipients;
|
||||
|
||||
try {
|
||||
if (message.getGroupId() == null) {
|
||||
groupRecipients = null;
|
||||
} else {
|
||||
groupRecipients = RecipientFactory.getRecipientsFromString(context, message.getGroupId(), true);
|
||||
}
|
||||
} catch (RecipientFormattingException e) {
|
||||
Log.w("SmsDatabase", e);
|
||||
groupRecipients = null;
|
||||
}
|
||||
|
||||
boolean unread = org.thoughtcrime.securesms.util.Util.isDefaultSmsProvider(context) ||
|
||||
message.isSecureMessage() || message.isKeyExchange();
|
||||
|
||||
long threadId;
|
||||
|
||||
if (groupId == null) threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
|
||||
else threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdForGroup(groupId);
|
||||
if (groupRecipients == null) threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
|
||||
else threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipients);
|
||||
|
||||
ContentValues values = new ContentValues(6);
|
||||
values.put(ADDRESS, message.getSender());
|
||||
values.put(ADDRESS_DEVICE_ID, message.getSenderDeviceId());
|
||||
values.put(DATE_RECEIVED, System.currentTimeMillis());
|
||||
values.put(DATE_SENT, message.getSentTimestampMillis());
|
||||
values.put(PROTOCOL, message.getProtocol());
|
||||
@@ -468,6 +488,7 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
|
||||
public SmsMessageRecord getCurrent() {
|
||||
long messageId = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.ID));
|
||||
String address = cursor.getString(cursor.getColumnIndexOrThrow(SmsDatabase.ADDRESS));
|
||||
int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.ADDRESS_DEVICE_ID));
|
||||
long type = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.TYPE));
|
||||
long dateReceived = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.NORMALIZED_DATE_RECEIVED));
|
||||
long dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.NORMALIZED_DATE_SENT));
|
||||
@@ -478,6 +499,7 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
|
||||
|
||||
return new SmsMessageRecord(context, messageId, body, recipients,
|
||||
recipients.getPrimaryRecipient(),
|
||||
addressDeviceId,
|
||||
dateSent, dateReceived, type,
|
||||
threadId, status);
|
||||
}
|
||||
@@ -487,15 +509,13 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
|
||||
Recipients recipients = RecipientFactory.getRecipientsFromString(context, address, false);
|
||||
|
||||
if (recipients == null || recipients.isEmpty()) {
|
||||
return new Recipients(new Recipient("Unknown", "Unknown", null,
|
||||
ContactPhotoFactory.getDefaultContactPhoto(context)));
|
||||
return new Recipients(Recipient.getUnknownRecipient(context));
|
||||
}
|
||||
|
||||
return recipients;
|
||||
} catch (RecipientFormattingException e) {
|
||||
Log.w("EncryptingSmsDatabase", e);
|
||||
return new Recipients(new Recipient("Unknown", "Unknown", null,
|
||||
ContactPhotoFactory.getDefaultContactPhoto(context)));
|
||||
return new Recipients(Recipient.getUnknownRecipient(context));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,13 +70,11 @@ public class ThreadDatabase extends Database {
|
||||
}
|
||||
|
||||
private long[] getRecipientIds(Recipients recipients) {
|
||||
Set<Long> recipientSet = new HashSet<Long>();
|
||||
Set<Long> recipientSet = new HashSet<Long>();
|
||||
List<Recipient> recipientList = recipients.getRecipientsList();
|
||||
|
||||
for (Recipient recipient : recipientList) {
|
||||
// String number = NumberUtil.filterNumber(recipient.getNumber());
|
||||
String number = recipient.getNumber();
|
||||
recipientSet.add(Long.valueOf(DatabaseFactory.getAddressDatabase(context).getCanonicalAddress(number)));
|
||||
recipientSet.add(recipient.getRecipientId());
|
||||
}
|
||||
|
||||
long[] recipientArray = new long[recipientSet.size()];
|
||||
|
||||
@@ -41,12 +41,13 @@ public class MediaMmsMessageRecord extends MessageRecord {
|
||||
private final ListenableFutureTask<SlideDeck> slideDeck;
|
||||
|
||||
public MediaMmsMessageRecord(Context context, long id, Recipients recipients,
|
||||
Recipient individualRecipient, long dateSent, long dateReceived,
|
||||
long threadId, Body body, ListenableFutureTask<SlideDeck> slideDeck,
|
||||
Recipient individualRecipient, int recipientDeviceId,
|
||||
long dateSent, long dateReceived, long threadId, Body body,
|
||||
ListenableFutureTask<SlideDeck> slideDeck,
|
||||
int partCount, long mailbox)
|
||||
{
|
||||
super(context, id, body, recipients, individualRecipient, dateSent, dateReceived,
|
||||
threadId, DELIVERY_STATUS_NONE, mailbox);
|
||||
super(context, id, body, recipients, individualRecipient, recipientDeviceId,
|
||||
dateSent, dateReceived, threadId, DELIVERY_STATUS_NONE, mailbox);
|
||||
|
||||
this.context = context.getApplicationContext();
|
||||
this.partCount = partCount;
|
||||
|
||||
@@ -45,18 +45,20 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
public static final int DELIVERY_STATUS_FAILED = 3;
|
||||
|
||||
private final Recipient individualRecipient;
|
||||
private final long id;
|
||||
private final int deliveryStatus;
|
||||
private final int recipientDeviceId;
|
||||
private final long id;
|
||||
private final int deliveryStatus;
|
||||
|
||||
public MessageRecord(Context context, long id, Body body, Recipients recipients,
|
||||
Recipient individualRecipient,
|
||||
long dateSent, long dateReceived,
|
||||
long threadId, int deliveryStatus,
|
||||
long type)
|
||||
MessageRecord(Context context, long id, Body body, Recipients recipients,
|
||||
Recipient individualRecipient, int recipientDeviceId,
|
||||
long dateSent, long dateReceived,
|
||||
long threadId, int deliveryStatus,
|
||||
long type)
|
||||
{
|
||||
super(context, body, recipients, dateSent, dateReceived, threadId, type);
|
||||
this.id = id;
|
||||
this.individualRecipient = individualRecipient;
|
||||
this.recipientDeviceId = recipientDeviceId;
|
||||
this.deliveryStatus = deliveryStatus;
|
||||
}
|
||||
|
||||
@@ -121,6 +123,10 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
return individualRecipient;
|
||||
}
|
||||
|
||||
public int getRecipientDeviceId() {
|
||||
return recipientDeviceId;
|
||||
}
|
||||
|
||||
public long getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -41,13 +41,13 @@ public class NotificationMmsMessageRecord extends MessageRecord {
|
||||
private final byte[] transactionId;
|
||||
|
||||
public NotificationMmsMessageRecord(Context context, long id, Recipients recipients,
|
||||
Recipient individualRecipient,
|
||||
Recipient individualRecipient, int recipientDeviceId,
|
||||
long dateSent, long dateReceived, long threadId,
|
||||
byte[] contentLocation, long messageSize, long expiry,
|
||||
int status, byte[] transactionId, long mailbox)
|
||||
{
|
||||
super(context, id, new Body("", true), recipients, individualRecipient, dateSent, dateReceived,
|
||||
threadId, DELIVERY_STATUS_NONE, mailbox);
|
||||
super(context, id, new Body("", true), recipients, individualRecipient, recipientDeviceId,
|
||||
dateSent, dateReceived, threadId, DELIVERY_STATUS_NONE, mailbox);
|
||||
|
||||
this.contentLocation = contentLocation;
|
||||
this.messageSize = messageSize;
|
||||
|
||||
@@ -38,12 +38,13 @@ public class SmsMessageRecord extends MessageRecord {
|
||||
public SmsMessageRecord(Context context, long id,
|
||||
Body body, Recipients recipients,
|
||||
Recipient individualRecipient,
|
||||
int recipientDeviceId,
|
||||
long dateSent, long dateReceived,
|
||||
long type, long threadId,
|
||||
int status)
|
||||
{
|
||||
super(context, id, body, recipients, individualRecipient, dateSent, dateReceived,
|
||||
threadId, getGenericDeliveryStatus(status), type);
|
||||
super(context, id, body, recipients, individualRecipient, recipientDeviceId,
|
||||
dateSent, dateReceived, threadId, getGenericDeliveryStatus(status), type);
|
||||
}
|
||||
|
||||
public long getType() {
|
||||
|
||||
Reference in New Issue
Block a user