mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-03 07:32:19 +00:00
Support for sealed sender - Part 1
This commit is contained in:
committed by
Greyson Parrelli
parent
b7b9554364
commit
5f31762220
@@ -17,11 +17,12 @@ public class GroupReceiptDatabase extends Database {
|
||||
|
||||
public static final String TABLE_NAME = "group_receipts";
|
||||
|
||||
private static final String ID = "_id";
|
||||
public static final String MMS_ID = "mms_id";
|
||||
private static final String ADDRESS = "address";
|
||||
private static final String STATUS = "status";
|
||||
private static final String TIMESTAMP = "timestamp";
|
||||
private static final String ID = "_id";
|
||||
public static final String MMS_ID = "mms_id";
|
||||
private static final String ADDRESS = "address";
|
||||
private static final String STATUS = "status";
|
||||
private static final String TIMESTAMP = "timestamp";
|
||||
private static final String UNIDENTIFIED = "unidentified";
|
||||
|
||||
public static final int STATUS_UNKNOWN = -1;
|
||||
public static final int STATUS_UNDELIVERED = 0;
|
||||
@@ -29,7 +30,7 @@ public class GroupReceiptDatabase extends Database {
|
||||
public static final int STATUS_READ = 2;
|
||||
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " +
|
||||
MMS_ID + " INTEGER, " + ADDRESS + " TEXT, " + STATUS + " INTEGER, " + TIMESTAMP + " INTEGER);";
|
||||
MMS_ID + " INTEGER, " + ADDRESS + " TEXT, " + STATUS + " INTEGER, " + TIMESTAMP + " INTEGER, " + UNIDENTIFIED + " INTEGER DEFAULT 0);";
|
||||
|
||||
public static final String[] CREATE_INDEXES = {
|
||||
"CREATE INDEX IF NOT EXISTS group_receipt_mms_id_index ON " + TABLE_NAME + " (" + MMS_ID + ");",
|
||||
@@ -63,6 +64,16 @@ public class GroupReceiptDatabase extends Database {
|
||||
new String[] {String.valueOf(mmsId), address.serialize(), String.valueOf(status)});
|
||||
}
|
||||
|
||||
public void setUnidentified(Address address, long mmsId, boolean unidentified) {
|
||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(UNIDENTIFIED, unidentified ? 1 : 0);
|
||||
|
||||
db.update(TABLE_NAME, values, MMS_ID + " = ? AND " + ADDRESS + " = ?",
|
||||
new String[] {String.valueOf(mmsId), address.serialize()});
|
||||
|
||||
}
|
||||
|
||||
public @NonNull List<GroupReceiptInfo> getGroupReceiptInfo(long mmsId) {
|
||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||
List<GroupReceiptInfo> results = new LinkedList<>();
|
||||
@@ -71,7 +82,8 @@ public class GroupReceiptDatabase extends Database {
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
results.add(new GroupReceiptInfo(Address.fromSerialized(cursor.getString(cursor.getColumnIndexOrThrow(ADDRESS))),
|
||||
cursor.getInt(cursor.getColumnIndexOrThrow(STATUS)),
|
||||
cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP))));
|
||||
cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP)),
|
||||
cursor.getInt(cursor.getColumnIndexOrThrow(UNIDENTIFIED)) == 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,11 +104,13 @@ public class GroupReceiptDatabase extends Database {
|
||||
private final Address address;
|
||||
private final int status;
|
||||
private final long timestamp;
|
||||
private final boolean unidentified;
|
||||
|
||||
public GroupReceiptInfo(Address address, int status, long timestamp) {
|
||||
this.address = address;
|
||||
this.status = status;
|
||||
this.timestamp = timestamp;
|
||||
GroupReceiptInfo(Address address, int status, long timestamp, boolean unidentified) {
|
||||
this.address = address;
|
||||
this.status = status;
|
||||
this.timestamp = timestamp;
|
||||
this.unidentified = unidentified;
|
||||
}
|
||||
|
||||
public Address getAddress() {
|
||||
@@ -110,5 +124,9 @@ public class GroupReceiptDatabase extends Database {
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public boolean isUnidentified() {
|
||||
return unidentified;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
@@ -52,6 +51,7 @@ import org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.Quote;
|
||||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||
import org.thoughtcrime.securesms.jobs.TrimThreadJob;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
|
||||
import org.thoughtcrime.securesms.mms.MmsException;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage;
|
||||
@@ -125,7 +125,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
EXPIRE_STARTED + " INTEGER DEFAULT 0, " + NOTIFIED + " INTEGER DEFAULT 0, " +
|
||||
READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + QUOTE_ID + " INTEGER DEFAULT 0, " +
|
||||
QUOTE_AUTHOR + " TEXT, " + QUOTE_BODY + " TEXT, " + QUOTE_ATTACHMENT + " INTEGER DEFAULT -1, " +
|
||||
QUOTE_MISSING + " INTEGER DEFAULT 0, " + SHARED_CONTACTS + " TEXT);";
|
||||
QUOTE_MISSING + " INTEGER DEFAULT 0, " + SHARED_CONTACTS + " TEXT, " + UNIDENTIFIED + " INTEGER DEFAULT 0);";
|
||||
|
||||
public static final String[] CREATE_INDEXS = {
|
||||
"CREATE INDEX IF NOT EXISTS mms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");",
|
||||
@@ -145,7 +145,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
MESSAGE_SIZE, STATUS, TRANSACTION_ID,
|
||||
BODY, PART_COUNT, ADDRESS, ADDRESS_DEVICE_ID,
|
||||
DELIVERY_RECEIPT_COUNT, READ_RECEIPT_COUNT, MISMATCHED_IDENTITIES, NETWORK_FAILURE, SUBSCRIPTION_ID,
|
||||
EXPIRES_IN, EXPIRE_STARTED, NOTIFIED, QUOTE_ID, QUOTE_AUTHOR, QUOTE_BODY, QUOTE_ATTACHMENT, QUOTE_MISSING, SHARED_CONTACTS,
|
||||
EXPIRES_IN, EXPIRE_STARTED, NOTIFIED, QUOTE_ID, QUOTE_AUTHOR, QUOTE_BODY, QUOTE_ATTACHMENT, QUOTE_MISSING, SHARED_CONTACTS, UNIDENTIFIED,
|
||||
"json_group_array(json_object(" +
|
||||
"'" + AttachmentDatabase.ROW_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + ", " +
|
||||
"'" + AttachmentDatabase.UNIQUE_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.UNIQUE_ID + ", " +
|
||||
@@ -403,6 +403,14 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
notifyConversationListeners(threadId);
|
||||
}
|
||||
|
||||
public void markUnidentified(long messageId, boolean unidentified) {
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(UNIDENTIFIED, unidentified ? 1 : 0);
|
||||
|
||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {String.valueOf(messageId)});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markExpireStarted(long messageId) {
|
||||
markExpireStarted(messageId, System.currentTimeMillis());
|
||||
@@ -575,6 +583,8 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
String address = cursor.getString(cursor.getColumnIndexOrThrow(ADDRESS));
|
||||
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID));
|
||||
int distributionType = DatabaseFactory.getThreadDatabase(context).getDistributionType(threadId);
|
||||
String mismatchDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.MISMATCHED_IDENTITIES));
|
||||
String networkDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.NETWORK_FAILURE));
|
||||
|
||||
long quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_ID));
|
||||
String quoteAuthor = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_AUTHOR));
|
||||
@@ -585,20 +595,38 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
Set<Attachment> contactAttachments = new HashSet<>(Stream.of(contacts).map(Contact::getAvatarAttachment).filter(a -> a != null).toList());
|
||||
List<Attachment> attachments = Stream.of(associatedAttachments).filterNot(Attachment::isQuote).filterNot(contactAttachments::contains).map(a -> (Attachment)a).toList();
|
||||
|
||||
Recipient recipient = Recipient.from(context, Address.fromSerialized(address), false);
|
||||
QuoteModel quote = null;
|
||||
Recipient recipient = Recipient.from(context, Address.fromSerialized(address), false);
|
||||
List<NetworkFailure> networkFailures = new LinkedList<>();
|
||||
List<IdentityKeyMismatch> mismatches = new LinkedList<>();
|
||||
QuoteModel quote = null;
|
||||
|
||||
if (quoteId > 0 && (!TextUtils.isEmpty(quoteText) || !quoteAttachments.isEmpty())) {
|
||||
quote = new QuoteModel(quoteId, Address.fromSerialized(quoteAuthor), quoteText, quoteMissing, quoteAttachments);
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(mismatchDocument)) {
|
||||
try {
|
||||
mismatches = JsonUtils.fromJson(mismatchDocument, IdentityKeyMismatchList.class).getList();
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(networkDocument)) {
|
||||
try {
|
||||
networkFailures = JsonUtils.fromJson(networkDocument, NetworkFailureList.class).getList();
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (body != null && (Types.isGroupQuit(outboxType) || Types.isGroupUpdate(outboxType))) {
|
||||
return new OutgoingGroupMediaMessage(recipient, body, attachments, timestamp, 0, quote, contacts);
|
||||
} else if (Types.isExpirationTimerUpdate(outboxType)) {
|
||||
return new OutgoingExpirationUpdateMessage(recipient, timestamp, expiresIn);
|
||||
}
|
||||
|
||||
OutgoingMediaMessage message = new OutgoingMediaMessage(recipient, body, attachments, timestamp, subscriptionId, expiresIn, distributionType, quote, contacts);
|
||||
OutgoingMediaMessage message = new OutgoingMediaMessage(recipient, body, attachments, timestamp, subscriptionId, expiresIn, distributionType, quote, contacts, networkFailures, mismatches);
|
||||
|
||||
if (Types.isSecureType(outboxType)) {
|
||||
return new OutgoingSecureMediaMessage(message);
|
||||
@@ -730,6 +758,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
contentValues.put(SUBSCRIPTION_ID, retrieved.getSubscriptionId());
|
||||
contentValues.put(EXPIRES_IN, retrieved.getExpiresIn());
|
||||
contentValues.put(READ, retrieved.isExpirationUpdate() ? 1 : 0);
|
||||
contentValues.put(UNIDENTIFIED, retrieved.isUnidentified());
|
||||
|
||||
if (!contentValues.containsKey(DATE_SENT)) {
|
||||
contentValues.put(DATE_SENT, contentValues.getAsLong(DATE_RECEIVED));
|
||||
@@ -1181,7 +1210,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
message.getOutgoingQuote().isOriginalMissing(),
|
||||
new SlideDeck(context, message.getOutgoingQuote().getAttachments())) :
|
||||
null,
|
||||
message.getSharedContacts());
|
||||
message.getSharedContacts(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1269,6 +1298,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.SUBSCRIPTION_ID));
|
||||
long expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.EXPIRES_IN));
|
||||
long expireStarted = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.EXPIRE_STARTED));
|
||||
boolean unidentified = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.UNIDENTIFIED)) == 1;
|
||||
|
||||
if (!TextSecurePreferences.isReadReceiptsEnabled(context)) {
|
||||
readReceiptCount = 0;
|
||||
@@ -1287,7 +1317,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
addressDeviceId, dateSent, dateReceived, deliveryReceiptCount,
|
||||
threadId, body, slideDeck, partCount, box, mismatches,
|
||||
networkFailures, subscriptionId, expiresIn, expireStarted,
|
||||
readReceiptCount, quote, contacts);
|
||||
readReceiptCount, quote, contacts, unidentified);
|
||||
}
|
||||
|
||||
private Recipient getRecipientFor(String serialized) {
|
||||
|
||||
@@ -19,6 +19,7 @@ public interface MmsSmsColumns {
|
||||
public static final String EXPIRES_IN = "expires_in";
|
||||
public static final String EXPIRE_STARTED = "expire_started";
|
||||
public static final String NOTIFIED = "notified";
|
||||
public static final String UNIDENTIFIED = "unidentified";
|
||||
|
||||
public static class Types {
|
||||
protected static final long TOTAL_MASK = 0xFFFFFFFF;
|
||||
|
||||
@@ -49,7 +49,9 @@ public class MmsSmsDatabase extends Database {
|
||||
MmsSmsColumns.NORMALIZED_DATE_SENT,
|
||||
MmsSmsColumns.NORMALIZED_DATE_RECEIVED,
|
||||
MmsDatabase.MESSAGE_TYPE, MmsDatabase.MESSAGE_BOX,
|
||||
SmsDatabase.STATUS, MmsDatabase.PART_COUNT,
|
||||
SmsDatabase.STATUS,
|
||||
MmsSmsColumns.UNIDENTIFIED,
|
||||
MmsDatabase.PART_COUNT,
|
||||
MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID,
|
||||
MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY,
|
||||
MmsDatabase.STATUS,
|
||||
@@ -232,6 +234,7 @@ public class MmsSmsDatabase extends Database {
|
||||
MmsDatabase.MESSAGE_BOX, SmsDatabase.STATUS, MmsDatabase.PART_COUNT,
|
||||
MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID,
|
||||
MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, MmsDatabase.STATUS,
|
||||
MmsDatabase.UNIDENTIFIED,
|
||||
MmsSmsColumns.DELIVERY_RECEIPT_COUNT, MmsSmsColumns.READ_RECEIPT_COUNT,
|
||||
MmsSmsColumns.MISMATCHED_IDENTITIES,
|
||||
MmsSmsColumns.SUBSCRIPTION_ID, MmsSmsColumns.EXPIRES_IN, MmsSmsColumns.EXPIRE_STARTED,
|
||||
@@ -256,6 +259,7 @@ public class MmsSmsDatabase extends Database {
|
||||
MmsDatabase.MESSAGE_BOX, SmsDatabase.STATUS, MmsDatabase.PART_COUNT,
|
||||
MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID,
|
||||
MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, MmsDatabase.STATUS,
|
||||
MmsDatabase.UNIDENTIFIED,
|
||||
MmsSmsColumns.DELIVERY_RECEIPT_COUNT, MmsSmsColumns.READ_RECEIPT_COUNT,
|
||||
MmsSmsColumns.MISMATCHED_IDENTITIES,
|
||||
MmsSmsColumns.SUBSCRIPTION_ID, MmsSmsColumns.EXPIRES_IN, MmsSmsColumns.EXPIRE_STARTED,
|
||||
@@ -266,7 +270,8 @@ public class MmsSmsDatabase extends Database {
|
||||
MmsDatabase.QUOTE_BODY,
|
||||
MmsDatabase.QUOTE_MISSING,
|
||||
MmsDatabase.QUOTE_ATTACHMENT,
|
||||
MmsDatabase.SHARED_CONTACTS};
|
||||
MmsDatabase.SHARED_CONTACTS,
|
||||
MmsDatabase.UNIDENTIFIED};
|
||||
|
||||
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
|
||||
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
|
||||
@@ -304,6 +309,7 @@ public class MmsSmsDatabase extends Database {
|
||||
mmsColumnsPresent.add(MmsDatabase.EXPIRY);
|
||||
mmsColumnsPresent.add(MmsDatabase.NOTIFIED);
|
||||
mmsColumnsPresent.add(MmsDatabase.STATUS);
|
||||
mmsColumnsPresent.add(MmsDatabase.UNIDENTIFIED);
|
||||
mmsColumnsPresent.add(MmsDatabase.NETWORK_FAILURE);
|
||||
|
||||
mmsColumnsPresent.add(AttachmentDatabase.ROW_ID);
|
||||
@@ -351,6 +357,7 @@ public class MmsSmsDatabase extends Database {
|
||||
smsColumnsPresent.add(SmsDatabase.DATE_SENT);
|
||||
smsColumnsPresent.add(SmsDatabase.DATE_RECEIVED);
|
||||
smsColumnsPresent.add(SmsDatabase.STATUS);
|
||||
smsColumnsPresent.add(SmsDatabase.UNIDENTIFIED);
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(TRANSPORT, mmsProjection, mmsColumnsPresent, 4, MMS_TRANSPORT, selection, null, MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID, null);
|
||||
|
||||
@@ -20,17 +20,20 @@ public class PushDatabase extends Database {
|
||||
|
||||
private static final String TAG = PushDatabase.class.getSimpleName();
|
||||
|
||||
private static final String TABLE_NAME = "push";
|
||||
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 LEGACY_MSG = "body";
|
||||
public static final String CONTENT = "content";
|
||||
public static final String TIMESTAMP = "timestamp";
|
||||
private static final String TABLE_NAME = "push";
|
||||
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 LEGACY_MSG = "body";
|
||||
public static final String CONTENT = "content";
|
||||
public static final String TIMESTAMP = "timestamp";
|
||||
public static final String SERVER_TIMESTAMP = "server_timestamp";
|
||||
public static final String SERVER_GUID = "server_guid";
|
||||
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " +
|
||||
TYPE + " INTEGER, " + SOURCE + " TEXT, " + DEVICE_ID + " INTEGER, " + LEGACY_MSG + " TEXT, " + CONTENT + " TEXT, " + TIMESTAMP + " INTEGER);";
|
||||
TYPE + " INTEGER, " + SOURCE + " TEXT, " + DEVICE_ID + " INTEGER, " + LEGACY_MSG + " TEXT, " + CONTENT + " TEXT, " + TIMESTAMP + " INTEGER, " +
|
||||
SERVER_TIMESTAMP + " INTEGER DEFAULT 0, " + SERVER_GUID + " TEXT DEFAULT NULL);";
|
||||
|
||||
public PushDatabase(Context context, SQLCipherOpenHelper databaseHelper) {
|
||||
super(context, databaseHelper);
|
||||
@@ -49,6 +52,8 @@ public class PushDatabase extends Database {
|
||||
values.put(LEGACY_MSG, envelope.hasLegacyMessage() ? Base64.encodeBytes(envelope.getLegacyMessage()) : "");
|
||||
values.put(CONTENT, envelope.hasContent() ? Base64.encodeBytes(envelope.getContent()) : "");
|
||||
values.put(TIMESTAMP, envelope.getTimestamp());
|
||||
values.put(SERVER_TIMESTAMP, envelope.getServerTimestamp());
|
||||
values.put(SERVER_GUID, envelope.getUuid());
|
||||
|
||||
return databaseHelper.getWritableDatabase().insert(TABLE_NAME, null, values);
|
||||
}
|
||||
@@ -69,10 +74,11 @@ public class PushDatabase extends Database {
|
||||
return new SignalServiceEnvelope(cursor.getInt(cursor.getColumnIndexOrThrow(TYPE)),
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(SOURCE)),
|
||||
cursor.getInt(cursor.getColumnIndexOrThrow(DEVICE_ID)),
|
||||
"",
|
||||
cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP)),
|
||||
Util.isEmpty(legacyMessage) ? null : Base64.decode(legacyMessage),
|
||||
Util.isEmpty(content) ? null : Base64.decode(content));
|
||||
Util.isEmpty(content) ? null : Base64.decode(content),
|
||||
cursor.getLong(cursor.getColumnIndexOrThrow(SERVER_TIMESTAMP)),
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(SERVER_GUID)));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
@@ -135,16 +141,19 @@ public class PushDatabase extends Database {
|
||||
if (cursor == null || !cursor.moveToNext())
|
||||
return null;
|
||||
|
||||
int type = cursor.getInt(cursor.getColumnIndexOrThrow(TYPE));
|
||||
String source = cursor.getString(cursor.getColumnIndexOrThrow(SOURCE));
|
||||
int deviceId = cursor.getInt(cursor.getColumnIndexOrThrow(DEVICE_ID));
|
||||
String legacyMessage = cursor.getString(cursor.getColumnIndexOrThrow(LEGACY_MSG));
|
||||
String content = cursor.getString(cursor.getColumnIndexOrThrow(CONTENT));
|
||||
long timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP));
|
||||
int type = cursor.getInt(cursor.getColumnIndexOrThrow(TYPE));
|
||||
String source = cursor.getString(cursor.getColumnIndexOrThrow(SOURCE));
|
||||
int deviceId = cursor.getInt(cursor.getColumnIndexOrThrow(DEVICE_ID));
|
||||
String legacyMessage = cursor.getString(cursor.getColumnIndexOrThrow(LEGACY_MSG));
|
||||
String content = cursor.getString(cursor.getColumnIndexOrThrow(CONTENT));
|
||||
long timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP));
|
||||
long serverTimestamp = cursor.getLong(cursor.getColumnIndexOrThrow(SERVER_TIMESTAMP));
|
||||
String serverGuid = cursor.getString(cursor.getColumnIndexOrThrow(SERVER_GUID));
|
||||
|
||||
return new SignalServiceEnvelope(type, source, deviceId, "", timestamp,
|
||||
return new SignalServiceEnvelope(type, source, deviceId, timestamp,
|
||||
legacyMessage != null ? Base64.decode(legacyMessage) : null,
|
||||
content != null ? Base64.decode(content) : null);
|
||||
content != null ? Base64.decode(content) : null,
|
||||
serverTimestamp, serverGuid);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
@@ -14,6 +13,7 @@ import net.sqlcipher.database.SQLiteDatabase;
|
||||
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
@@ -33,34 +33,36 @@ public class RecipientDatabase extends Database {
|
||||
|
||||
private static final String TAG = RecipientDatabase.class.getSimpleName();
|
||||
|
||||
static final String TABLE_NAME = "recipient_preferences";
|
||||
private static final String ID = "_id";
|
||||
static final String ADDRESS = "recipient_ids";
|
||||
private static final String BLOCK = "block";
|
||||
private static final String NOTIFICATION = "notification";
|
||||
private static final String VIBRATE = "vibrate";
|
||||
private static final String MUTE_UNTIL = "mute_until";
|
||||
private static final String COLOR = "color";
|
||||
private static final String SEEN_INVITE_REMINDER = "seen_invite_reminder";
|
||||
private static final String DEFAULT_SUBSCRIPTION_ID = "default_subscription_id";
|
||||
private static final String EXPIRE_MESSAGES = "expire_messages";
|
||||
private static final String REGISTERED = "registered";
|
||||
private static final String PROFILE_KEY = "profile_key";
|
||||
private static final String SYSTEM_DISPLAY_NAME = "system_display_name";
|
||||
private static final String SYSTEM_PHOTO_URI = "system_contact_photo";
|
||||
private static final String SYSTEM_PHONE_LABEL = "system_phone_label";
|
||||
private static final String SYSTEM_CONTACT_URI = "system_contact_uri";
|
||||
private static final String SIGNAL_PROFILE_NAME = "signal_profile_name";
|
||||
private static final String SIGNAL_PROFILE_AVATAR = "signal_profile_avatar";
|
||||
private static final String PROFILE_SHARING = "profile_sharing_approval";
|
||||
private static final String CALL_RINGTONE = "call_ringtone";
|
||||
private static final String CALL_VIBRATE = "call_vibrate";
|
||||
private static final String NOTIFICATION_CHANNEL = "notification_channel";
|
||||
static final String TABLE_NAME = "recipient_preferences";
|
||||
private static final String ID = "_id";
|
||||
static final String ADDRESS = "recipient_ids";
|
||||
private static final String BLOCK = "block";
|
||||
private static final String NOTIFICATION = "notification";
|
||||
private static final String VIBRATE = "vibrate";
|
||||
private static final String MUTE_UNTIL = "mute_until";
|
||||
private static final String COLOR = "color";
|
||||
private static final String SEEN_INVITE_REMINDER = "seen_invite_reminder";
|
||||
private static final String DEFAULT_SUBSCRIPTION_ID = "default_subscription_id";
|
||||
private static final String EXPIRE_MESSAGES = "expire_messages";
|
||||
private static final String REGISTERED = "registered";
|
||||
private static final String PROFILE_KEY = "profile_key";
|
||||
private static final String SYSTEM_DISPLAY_NAME = "system_display_name";
|
||||
private static final String SYSTEM_PHOTO_URI = "system_contact_photo";
|
||||
private static final String SYSTEM_PHONE_LABEL = "system_phone_label";
|
||||
private static final String SYSTEM_CONTACT_URI = "system_contact_uri";
|
||||
private static final String SIGNAL_PROFILE_NAME = "signal_profile_name";
|
||||
private static final String SIGNAL_PROFILE_AVATAR = "signal_profile_avatar";
|
||||
private static final String PROFILE_SHARING = "profile_sharing_approval";
|
||||
private static final String CALL_RINGTONE = "call_ringtone";
|
||||
private static final String CALL_VIBRATE = "call_vibrate";
|
||||
private static final String NOTIFICATION_CHANNEL = "notification_channel";
|
||||
private static final String UNIDENTIFIED_ACCESS_MODE = "unidentified_access_mode";
|
||||
|
||||
private static final String[] RECIPIENT_PROJECTION = new String[] {
|
||||
BLOCK, NOTIFICATION, CALL_RINGTONE, VIBRATE, CALL_VIBRATE, MUTE_UNTIL, COLOR, SEEN_INVITE_REMINDER, DEFAULT_SUBSCRIPTION_ID, EXPIRE_MESSAGES, REGISTERED,
|
||||
PROFILE_KEY, SYSTEM_DISPLAY_NAME, SYSTEM_PHOTO_URI, SYSTEM_PHONE_LABEL, SYSTEM_CONTACT_URI,
|
||||
SIGNAL_PROFILE_NAME, SIGNAL_PROFILE_AVATAR, PROFILE_SHARING, NOTIFICATION_CHANNEL
|
||||
SIGNAL_PROFILE_NAME, SIGNAL_PROFILE_AVATAR, PROFILE_SHARING, NOTIFICATION_CHANNEL,
|
||||
UNIDENTIFIED_ACCESS_MODE
|
||||
};
|
||||
|
||||
static final List<String> TYPED_RECIPIENT_PROJECTION = Stream.of(RECIPIENT_PROJECTION)
|
||||
@@ -103,6 +105,24 @@ public class RecipientDatabase extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
public enum UnidentifiedAccessMode {
|
||||
UNKNOWN(0), DISABLED(1), ENABLED(2), UNRESTRICTED(3);
|
||||
|
||||
private final int mode;
|
||||
|
||||
UnidentifiedAccessMode(int mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
public int getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public static UnidentifiedAccessMode fromMode(int mode) {
|
||||
return values()[mode];
|
||||
}
|
||||
}
|
||||
|
||||
public static final String CREATE_TABLE =
|
||||
"CREATE TABLE " + TABLE_NAME +
|
||||
" (" + ID + " INTEGER PRIMARY KEY, " +
|
||||
@@ -126,7 +146,8 @@ public class RecipientDatabase extends Database {
|
||||
PROFILE_SHARING + " INTEGER DEFAULT 0, " +
|
||||
CALL_RINGTONE + " TEXT DEFAULT NULL, " +
|
||||
CALL_VIBRATE + " INTEGER DEFAULT " + VibrateState.DEFAULT.getId() + ", " +
|
||||
NOTIFICATION_CHANNEL + " TEXT DEFAULT NULL);";
|
||||
NOTIFICATION_CHANNEL + " TEXT DEFAULT NULL, " +
|
||||
UNIDENTIFIED_ACCESS_MODE + " INTEGER DEFAULT 0);";
|
||||
|
||||
public RecipientDatabase(Context context, SQLCipherOpenHelper databaseHelper) {
|
||||
super(context, databaseHelper);
|
||||
@@ -169,29 +190,30 @@ public class RecipientDatabase extends Database {
|
||||
}
|
||||
|
||||
Optional<RecipientSettings> getRecipientSettings(@NonNull Cursor cursor) {
|
||||
boolean blocked = cursor.getInt(cursor.getColumnIndexOrThrow(BLOCK)) == 1;
|
||||
String messageRingtone = cursor.getString(cursor.getColumnIndexOrThrow(NOTIFICATION));
|
||||
String callRingtone = cursor.getString(cursor.getColumnIndexOrThrow(CALL_RINGTONE));
|
||||
int messageVibrateState = cursor.getInt(cursor.getColumnIndexOrThrow(VIBRATE));
|
||||
int callVibrateState = cursor.getInt(cursor.getColumnIndexOrThrow(CALL_VIBRATE));
|
||||
long muteUntil = cursor.getLong(cursor.getColumnIndexOrThrow(MUTE_UNTIL));
|
||||
String serializedColor = cursor.getString(cursor.getColumnIndexOrThrow(COLOR));
|
||||
boolean seenInviteReminder = cursor.getInt(cursor.getColumnIndexOrThrow(SEEN_INVITE_REMINDER)) == 1;
|
||||
int defaultSubscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(DEFAULT_SUBSCRIPTION_ID));
|
||||
int expireMessages = cursor.getInt(cursor.getColumnIndexOrThrow(EXPIRE_MESSAGES));
|
||||
int registeredState = cursor.getInt(cursor.getColumnIndexOrThrow(REGISTERED));
|
||||
String profileKeyString = cursor.getString(cursor.getColumnIndexOrThrow(PROFILE_KEY));
|
||||
String systemDisplayName = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_DISPLAY_NAME));
|
||||
String systemContactPhoto = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_PHOTO_URI));
|
||||
String systemPhoneLabel = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_PHONE_LABEL));
|
||||
String systemContactUri = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_CONTACT_URI));
|
||||
String signalProfileName = cursor.getString(cursor.getColumnIndexOrThrow(SIGNAL_PROFILE_NAME));
|
||||
String signalProfileAvatar = cursor.getString(cursor.getColumnIndexOrThrow(SIGNAL_PROFILE_AVATAR));
|
||||
boolean profileSharing = cursor.getInt(cursor.getColumnIndexOrThrow(PROFILE_SHARING)) == 1;
|
||||
String notificationChannel = cursor.getString(cursor.getColumnIndexOrThrow(NOTIFICATION_CHANNEL));
|
||||
boolean blocked = cursor.getInt(cursor.getColumnIndexOrThrow(BLOCK)) == 1;
|
||||
String messageRingtone = cursor.getString(cursor.getColumnIndexOrThrow(NOTIFICATION));
|
||||
String callRingtone = cursor.getString(cursor.getColumnIndexOrThrow(CALL_RINGTONE));
|
||||
int messageVibrateState = cursor.getInt(cursor.getColumnIndexOrThrow(VIBRATE));
|
||||
int callVibrateState = cursor.getInt(cursor.getColumnIndexOrThrow(CALL_VIBRATE));
|
||||
long muteUntil = cursor.getLong(cursor.getColumnIndexOrThrow(MUTE_UNTIL));
|
||||
String serializedColor = cursor.getString(cursor.getColumnIndexOrThrow(COLOR));
|
||||
boolean seenInviteReminder = cursor.getInt(cursor.getColumnIndexOrThrow(SEEN_INVITE_REMINDER)) == 1;
|
||||
int defaultSubscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(DEFAULT_SUBSCRIPTION_ID));
|
||||
int expireMessages = cursor.getInt(cursor.getColumnIndexOrThrow(EXPIRE_MESSAGES));
|
||||
int registeredState = cursor.getInt(cursor.getColumnIndexOrThrow(REGISTERED));
|
||||
String profileKeyString = cursor.getString(cursor.getColumnIndexOrThrow(PROFILE_KEY));
|
||||
String systemDisplayName = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_DISPLAY_NAME));
|
||||
String systemContactPhoto = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_PHOTO_URI));
|
||||
String systemPhoneLabel = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_PHONE_LABEL));
|
||||
String systemContactUri = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_CONTACT_URI));
|
||||
String signalProfileName = cursor.getString(cursor.getColumnIndexOrThrow(SIGNAL_PROFILE_NAME));
|
||||
String signalProfileAvatar = cursor.getString(cursor.getColumnIndexOrThrow(SIGNAL_PROFILE_AVATAR));
|
||||
boolean profileSharing = cursor.getInt(cursor.getColumnIndexOrThrow(PROFILE_SHARING)) == 1;
|
||||
String notificationChannel = cursor.getString(cursor.getColumnIndexOrThrow(NOTIFICATION_CHANNEL));
|
||||
int unidentifiedAccessMode = cursor.getInt(cursor.getColumnIndexOrThrow(UNIDENTIFIED_ACCESS_MODE));
|
||||
|
||||
MaterialColor color;
|
||||
byte[] profileKey = null;
|
||||
byte[] profileKey = null;
|
||||
|
||||
try {
|
||||
color = serializedColor == null ? null : MaterialColor.fromSerialized(serializedColor);
|
||||
@@ -219,7 +241,7 @@ public class RecipientDatabase extends Database {
|
||||
profileKey, systemDisplayName, systemContactPhoto,
|
||||
systemPhoneLabel, systemContactUri,
|
||||
signalProfileName, signalProfileAvatar, profileSharing,
|
||||
notificationChannel));
|
||||
notificationChannel, UnidentifiedAccessMode.fromMode(unidentifiedAccessMode)));
|
||||
}
|
||||
|
||||
public BulkOperationsHandle resetAllSystemContactInfo() {
|
||||
@@ -309,6 +331,13 @@ public class RecipientDatabase extends Database {
|
||||
recipient.resolve().setExpireMessages(expiration);
|
||||
}
|
||||
|
||||
public void setUnidentifiedAccessMode(@NonNull Recipient recipient, @NonNull UnidentifiedAccessMode unidentifiedAccessMode) {
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(UNIDENTIFIED_ACCESS_MODE, unidentifiedAccessMode.getMode());
|
||||
updateOrInsert(recipient.getAddress(), values);
|
||||
recipient.resolve().setUnidentifiedAccessMode(unidentifiedAccessMode);
|
||||
}
|
||||
|
||||
public void setProfileKey(@NonNull Recipient recipient, @Nullable byte[] profileKey) {
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(PROFILE_KEY, profileKey == null ? null : Base64.encodeBytes(profileKey));
|
||||
@@ -506,26 +535,27 @@ public class RecipientDatabase extends Database {
|
||||
}
|
||||
|
||||
public static class RecipientSettings {
|
||||
private final boolean blocked;
|
||||
private final long muteUntil;
|
||||
private final VibrateState messageVibrateState;
|
||||
private final VibrateState callVibrateState;
|
||||
private final Uri messageRingtone;
|
||||
private final Uri callRingtone;
|
||||
private final MaterialColor color;
|
||||
private final boolean seenInviteReminder;
|
||||
private final int defaultSubscriptionId;
|
||||
private final int expireMessages;
|
||||
private final RegisteredState registered;
|
||||
private final byte[] profileKey;
|
||||
private final String systemDisplayName;
|
||||
private final String systemContactPhoto;
|
||||
private final String systemPhoneLabel;
|
||||
private final String systemContactUri;
|
||||
private final String signalProfileName;
|
||||
private final String signalProfileAvatar;
|
||||
private final boolean profileSharing;
|
||||
private final String notificationChannel;
|
||||
private final boolean blocked;
|
||||
private final long muteUntil;
|
||||
private final VibrateState messageVibrateState;
|
||||
private final VibrateState callVibrateState;
|
||||
private final Uri messageRingtone;
|
||||
private final Uri callRingtone;
|
||||
private final MaterialColor color;
|
||||
private final boolean seenInviteReminder;
|
||||
private final int defaultSubscriptionId;
|
||||
private final int expireMessages;
|
||||
private final RegisteredState registered;
|
||||
private final byte[] profileKey;
|
||||
private final String systemDisplayName;
|
||||
private final String systemContactPhoto;
|
||||
private final String systemPhoneLabel;
|
||||
private final String systemContactUri;
|
||||
private final String signalProfileName;
|
||||
private final String signalProfileAvatar;
|
||||
private final boolean profileSharing;
|
||||
private final String notificationChannel;
|
||||
private final UnidentifiedAccessMode unidentifiedAccessMode;
|
||||
|
||||
RecipientSettings(boolean blocked, long muteUntil,
|
||||
@NonNull VibrateState messageVibrateState,
|
||||
@@ -545,28 +575,30 @@ public class RecipientDatabase extends Database {
|
||||
@Nullable String signalProfileName,
|
||||
@Nullable String signalProfileAvatar,
|
||||
boolean profileSharing,
|
||||
@Nullable String notificationChannel)
|
||||
@Nullable String notificationChannel,
|
||||
@NonNull UnidentifiedAccessMode unidentifiedAccessMode)
|
||||
{
|
||||
this.blocked = blocked;
|
||||
this.muteUntil = muteUntil;
|
||||
this.messageVibrateState = messageVibrateState;
|
||||
this.callVibrateState = callVibrateState;
|
||||
this.messageRingtone = messageRingtone;
|
||||
this.callRingtone = callRingtone;
|
||||
this.color = color;
|
||||
this.seenInviteReminder = seenInviteReminder;
|
||||
this.defaultSubscriptionId = defaultSubscriptionId;
|
||||
this.expireMessages = expireMessages;
|
||||
this.registered = registered;
|
||||
this.profileKey = profileKey;
|
||||
this.systemDisplayName = systemDisplayName;
|
||||
this.systemContactPhoto = systemContactPhoto;
|
||||
this.systemPhoneLabel = systemPhoneLabel;
|
||||
this.systemContactUri = systemContactUri;
|
||||
this.signalProfileName = signalProfileName;
|
||||
this.signalProfileAvatar = signalProfileAvatar;
|
||||
this.profileSharing = profileSharing;
|
||||
this.notificationChannel = notificationChannel;
|
||||
this.blocked = blocked;
|
||||
this.muteUntil = muteUntil;
|
||||
this.messageVibrateState = messageVibrateState;
|
||||
this.callVibrateState = callVibrateState;
|
||||
this.messageRingtone = messageRingtone;
|
||||
this.callRingtone = callRingtone;
|
||||
this.color = color;
|
||||
this.seenInviteReminder = seenInviteReminder;
|
||||
this.defaultSubscriptionId = defaultSubscriptionId;
|
||||
this.expireMessages = expireMessages;
|
||||
this.registered = registered;
|
||||
this.profileKey = profileKey;
|
||||
this.systemDisplayName = systemDisplayName;
|
||||
this.systemContactPhoto = systemContactPhoto;
|
||||
this.systemPhoneLabel = systemPhoneLabel;
|
||||
this.systemContactUri = systemContactUri;
|
||||
this.signalProfileName = signalProfileName;
|
||||
this.signalProfileAvatar = signalProfileAvatar;
|
||||
this.profileSharing = profileSharing;
|
||||
this.notificationChannel = notificationChannel;
|
||||
this.unidentifiedAccessMode = unidentifiedAccessMode;
|
||||
}
|
||||
|
||||
public @Nullable MaterialColor getColor() {
|
||||
@@ -613,7 +645,7 @@ public class RecipientDatabase extends Database {
|
||||
return registered;
|
||||
}
|
||||
|
||||
public byte[] getProfileKey() {
|
||||
public @Nullable byte[] getProfileKey() {
|
||||
return profileKey;
|
||||
}
|
||||
|
||||
@@ -648,6 +680,10 @@ public class RecipientDatabase extends Database {
|
||||
public @Nullable String getNotificationChannel() {
|
||||
return notificationChannel;
|
||||
}
|
||||
|
||||
public @NonNull UnidentifiedAccessMode getUnidentifiedAccessMode() {
|
||||
return unidentifiedAccessMode;
|
||||
}
|
||||
}
|
||||
|
||||
public static class RecipientReader implements Closeable {
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
@@ -38,6 +37,7 @@ import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||
import org.thoughtcrime.securesms.jobs.TrimThreadJob;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.sms.IncomingGroupMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||
@@ -81,7 +81,7 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
DELIVERY_RECEIPT_COUNT + " INTEGER DEFAULT 0," + SUBJECT + " TEXT, " + BODY + " TEXT, " +
|
||||
MISMATCHED_IDENTITIES + " TEXT DEFAULT NULL, " + SERVICE_CENTER + " TEXT, " + SUBSCRIPTION_ID + " INTEGER DEFAULT -1, " +
|
||||
EXPIRES_IN + " INTEGER DEFAULT 0, " + EXPIRE_STARTED + " INTEGER DEFAULT 0, " + NOTIFIED + " DEFAULT 0, " +
|
||||
READ_RECEIPT_COUNT + " INTEGER DEFAULT 0);";
|
||||
READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + UNIDENTIFIED + " INTEGER DEFAULT 0);";
|
||||
|
||||
public static final String[] CREATE_INDEXS = {
|
||||
"CREATE INDEX IF NOT EXISTS sms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");",
|
||||
@@ -99,7 +99,7 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
PROTOCOL, READ, STATUS, TYPE,
|
||||
REPLY_PATH_PRESENT, SUBJECT, BODY, SERVICE_CENTER, DELIVERY_RECEIPT_COUNT,
|
||||
MISMATCHED_IDENTITIES, SUBSCRIPTION_ID, EXPIRES_IN, EXPIRE_STARTED,
|
||||
NOTIFIED, READ_RECEIPT_COUNT
|
||||
NOTIFIED, READ_RECEIPT_COUNT, UNIDENTIFIED
|
||||
};
|
||||
|
||||
private static final EarlyReceiptCache earlyDeliveryReceiptCache = new EarlyReceiptCache();
|
||||
@@ -243,6 +243,14 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
updateTypeBitmask(id, Types.TOTAL_MASK, Types.MISSED_CALL_TYPE);
|
||||
}
|
||||
|
||||
public void markUnidentified(long id, boolean unidentified) {
|
||||
ContentValues contentValues = new ContentValues(1);
|
||||
contentValues.put(UNIDENTIFIED, unidentified ? 1 : 0);
|
||||
|
||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {String.valueOf(id)});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markExpireStarted(long id) {
|
||||
markExpireStarted(id, System.currentTimeMillis());
|
||||
@@ -559,6 +567,7 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
values.put(READ, unread ? 0 : 1);
|
||||
values.put(SUBSCRIPTION_ID, message.getSubscriptionId());
|
||||
values.put(EXPIRES_IN, message.getExpiresIn());
|
||||
values.put(UNIDENTIFIED, message.isUnidentified());
|
||||
|
||||
if (!TextUtils.isEmpty(message.getPseudoSubject()))
|
||||
values.put(SUBJECT, message.getPseudoSubject());
|
||||
@@ -818,7 +827,7 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
0, message.isSecureMessage() ? MmsSmsColumns.Types.getOutgoingEncryptedMessageType() : MmsSmsColumns.Types.getOutgoingSmsMessageType(),
|
||||
threadId, 0, new LinkedList<IdentityKeyMismatch>(),
|
||||
message.getSubscriptionId(), message.getExpiresIn(),
|
||||
System.currentTimeMillis(), 0);
|
||||
System.currentTimeMillis(), 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -858,6 +867,7 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
long expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.EXPIRES_IN));
|
||||
long expireStarted = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.EXPIRE_STARTED));
|
||||
String body = cursor.getString(cursor.getColumnIndexOrThrow(SmsDatabase.BODY));
|
||||
boolean unidentified = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.UNIDENTIFIED)) == 1;
|
||||
|
||||
if (!TextSecurePreferences.isReadReceiptsEnabled(context)) {
|
||||
readReceiptCount = 0;
|
||||
@@ -871,7 +881,7 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
addressDeviceId,
|
||||
dateSent, dateReceived, deliveryReceiptCount, type,
|
||||
threadId, status, mismatches, subscriptionId,
|
||||
expiresIn, expireStarted, readReceiptCount);
|
||||
expiresIn, expireStarted, readReceiptCount, unidentified);
|
||||
}
|
||||
|
||||
private List<IdentityKeyMismatch> getMismatches(String document) {
|
||||
|
||||
@@ -56,8 +56,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
private static final int BAD_IMPORT_CLEANUP = 10;
|
||||
private static final int QUOTE_MISSING = 11;
|
||||
private static final int NOTIFICATION_CHANNELS = 12;
|
||||
private static final int SECRET_SENDER = 13;
|
||||
|
||||
private static final int DATABASE_VERSION = 12;
|
||||
private static final int DATABASE_VERSION = 13;
|
||||
private static final String DATABASE_NAME = "signal.db";
|
||||
|
||||
private final Context context;
|
||||
@@ -284,6 +285,12 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
}
|
||||
}
|
||||
|
||||
if (oldVersion < SECRET_SENDER) {
|
||||
db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN unidentified_access_mode INTEGER DEFAULT 0");
|
||||
db.execSQL("ALTER TABLE push ADD COLUMN server_timestamp INTEGER DEFAULT 0");
|
||||
db.execSQL("ALTER TABLE push ADD COLUMN server_guid TEXT DEFAULT NULL");
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
|
||||
@@ -55,11 +55,12 @@ public class MediaMmsMessageRecord extends MmsMessageRecord {
|
||||
List<IdentityKeyMismatch> mismatches,
|
||||
List<NetworkFailure> failures, int subscriptionId,
|
||||
long expiresIn, long expireStarted, int readReceiptCount,
|
||||
@Nullable Quote quote, @Nullable List<Contact> contacts)
|
||||
@Nullable Quote quote, @Nullable List<Contact> contacts,
|
||||
boolean unidentified)
|
||||
{
|
||||
super(context, id, body, conversationRecipient, individualRecipient, recipientDeviceId, dateSent,
|
||||
dateReceived, threadId, Status.STATUS_NONE, deliveryReceiptCount, mailbox, mismatches, failures,
|
||||
subscriptionId, expiresIn, expireStarted, slideDeck, readReceiptCount, quote, contacts);
|
||||
subscriptionId, expiresIn, expireStarted, slideDeck, readReceiptCount, quote, contacts, unidentified);
|
||||
|
||||
this.context = context.getApplicationContext();
|
||||
this.partCount = partCount;
|
||||
|
||||
@@ -53,6 +53,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
private final int subscriptionId;
|
||||
private final long expiresIn;
|
||||
private final long expireStarted;
|
||||
private final boolean unidentified;
|
||||
|
||||
MessageRecord(Context context, long id, String body, Recipient conversationRecipient,
|
||||
Recipient individualRecipient, int recipientDeviceId,
|
||||
@@ -61,7 +62,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
List<IdentityKeyMismatch> mismatches,
|
||||
List<NetworkFailure> networkFailures,
|
||||
int subscriptionId, long expiresIn, long expireStarted,
|
||||
int readReceiptCount)
|
||||
int readReceiptCount, boolean unidentified)
|
||||
{
|
||||
super(context, body, conversationRecipient, dateSent, dateReceived,
|
||||
threadId, deliveryStatus, deliveryReceiptCount, type, readReceiptCount);
|
||||
@@ -73,6 +74,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
this.subscriptionId = subscriptionId;
|
||||
this.expiresIn = expiresIn;
|
||||
this.expireStarted = expireStarted;
|
||||
this.unidentified = unidentified;
|
||||
}
|
||||
|
||||
public abstract boolean isMms();
|
||||
@@ -242,4 +244,8 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
public long getExpireStarted() {
|
||||
return expireStarted;
|
||||
}
|
||||
|
||||
public boolean isUnidentified() {
|
||||
return unidentified;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,9 +27,9 @@ public abstract class MmsMessageRecord extends MessageRecord {
|
||||
long type, List<IdentityKeyMismatch> mismatches,
|
||||
List<NetworkFailure> networkFailures, int subscriptionId, long expiresIn,
|
||||
long expireStarted, @NonNull SlideDeck slideDeck, int readReceiptCount,
|
||||
@Nullable Quote quote, @NonNull List<Contact> contacts)
|
||||
@Nullable Quote quote, @NonNull List<Contact> contacts, boolean unidentified)
|
||||
{
|
||||
super(context, id, body, conversationRecipient, individualRecipient, recipientDeviceId, dateSent, dateReceived, threadId, deliveryStatus, deliveryReceiptCount, type, mismatches, networkFailures, subscriptionId, expiresIn, expireStarted, readReceiptCount);
|
||||
super(context, id, body, conversationRecipient, individualRecipient, recipientDeviceId, dateSent, dateReceived, threadId, deliveryStatus, deliveryReceiptCount, type, mismatches, networkFailures, subscriptionId, expiresIn, expireStarted, readReceiptCount, unidentified);
|
||||
|
||||
this.slideDeck = slideDeck;
|
||||
this.quote = quote;
|
||||
|
||||
@@ -56,7 +56,7 @@ public class NotificationMmsMessageRecord extends MmsMessageRecord {
|
||||
super(context, id, "", conversationRecipient, individualRecipient, recipientDeviceId,
|
||||
dateSent, dateReceived, threadId, Status.STATUS_NONE, deliveryReceiptCount, mailbox,
|
||||
new LinkedList<IdentityKeyMismatch>(), new LinkedList<NetworkFailure>(), subscriptionId,
|
||||
0, 0, slideDeck, readReceiptCount, null, Collections.emptyList());
|
||||
0, 0, slideDeck, readReceiptCount, null, Collections.emptyList(), false);
|
||||
|
||||
this.contentLocation = contentLocation;
|
||||
this.messageSize = messageSize;
|
||||
|
||||
@@ -47,12 +47,12 @@ public class SmsMessageRecord extends MessageRecord {
|
||||
long type, long threadId,
|
||||
int status, List<IdentityKeyMismatch> mismatches,
|
||||
int subscriptionId, long expiresIn, long expireStarted,
|
||||
int readReceiptCount)
|
||||
int readReceiptCount, boolean unidentified)
|
||||
{
|
||||
super(context, id, body, recipient, individualRecipient, recipientDeviceId,
|
||||
dateSent, dateReceived, threadId, status, deliveryReceiptCount, type,
|
||||
mismatches, new LinkedList<>(), subscriptionId,
|
||||
expiresIn, expireStarted, readReceiptCount);
|
||||
expiresIn, expireStarted, readReceiptCount, unidentified);
|
||||
}
|
||||
|
||||
public long getType() {
|
||||
|
||||
Reference in New Issue
Block a user