mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 01:40:07 +01:00
Fix infinite export loop and improve general error handling.
This commit is contained in:
@@ -65,6 +65,7 @@ import org.thoughtcrime.securesms.video.EncryptedMediaDataSource;
|
||||
import org.whispersystems.signalservice.internal.util.JsonUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@@ -204,7 +205,13 @@ public class AttachmentDatabase extends Database {
|
||||
public @NonNull InputStream getAttachmentStream(AttachmentId attachmentId, long offset)
|
||||
throws IOException
|
||||
{
|
||||
InputStream dataStream = getDataStream(attachmentId, DATA, offset);
|
||||
InputStream dataStream;
|
||||
|
||||
try {
|
||||
dataStream = getDataStream(attachmentId, DATA, offset);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new IOException("No stream for: " + attachmentId, e);
|
||||
}
|
||||
|
||||
if (dataStream == null) throw new IOException("No stream for: " + attachmentId);
|
||||
else return dataStream;
|
||||
@@ -1019,8 +1026,8 @@ public class AttachmentDatabase extends Database {
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@VisibleForTesting
|
||||
protected @Nullable InputStream getDataStream(AttachmentId attachmentId, String dataType, long offset)
|
||||
private @Nullable InputStream getDataStream(AttachmentId attachmentId, String dataType, long offset)
|
||||
throws FileNotFoundException
|
||||
{
|
||||
DataInfo dataInfo = getAttachmentDataFileInfo(attachmentId, dataType);
|
||||
|
||||
@@ -1042,6 +1049,9 @@ public class AttachmentDatabase extends Database {
|
||||
|
||||
return stream;
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.w(TAG, e);
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
return null;
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.thoughtcrime.securesms.database.documents.Document;
|
||||
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
|
||||
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchSet;
|
||||
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
|
||||
import org.thoughtcrime.securesms.database.model.MessageExportStatus;
|
||||
import org.thoughtcrime.securesms.database.model.MessageId;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId;
|
||||
@@ -398,7 +399,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns,
|
||||
}
|
||||
|
||||
public int getUnexportedInsecureMessagesCount(long threadId) {
|
||||
try (Cursor cursor = getWritableDatabase().query(getTableName(), SqlUtil.COUNT, getInsecureMessageClause(threadId) + " AND NOT " + EXPORTED, null, null, null, null)) {
|
||||
try (Cursor cursor = getWritableDatabase().query(getTableName(), SqlUtil.COUNT, getInsecureMessageClause(threadId) + " AND " + EXPORTED + " < ?", SqlUtil.buildArgs(MessageExportStatus.EXPORTED), null, null, null)) {
|
||||
if (cursor.moveToFirst()) {
|
||||
return cursor.getInt(0);
|
||||
}
|
||||
@@ -407,6 +408,19 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the exported status (not state) to the default for clearing errors.
|
||||
*/
|
||||
public void clearInsecureMessageExportedErrorStatus() {
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(EXPORTED, MessageExportStatus.UNEXPORTED.getCode());
|
||||
|
||||
SQLiteDatabaseExtensionsKt.update(getWritableDatabase(), getTableName())
|
||||
.values(values)
|
||||
.where(EXPORTED + " < ?", MessageExportStatus.UNEXPORTED.getCode())
|
||||
.run();
|
||||
}
|
||||
|
||||
public void setReactionsSeen(long threadId, long sinceTimestamp) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
@@ -52,6 +52,7 @@ import org.thoughtcrime.securesms.database.documents.NetworkFailure;
|
||||
import org.thoughtcrime.securesms.database.documents.NetworkFailureSet;
|
||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.Mention;
|
||||
import org.thoughtcrime.securesms.database.model.MessageExportStatus;
|
||||
import org.thoughtcrime.securesms.database.model.MessageId;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord;
|
||||
@@ -205,7 +206,8 @@ public class MmsDatabase extends MessageDatabase {
|
||||
"CREATE INDEX IF NOT EXISTS mms_is_story_index ON " + TABLE_NAME + " (" + STORY_TYPE + ");",
|
||||
"CREATE INDEX IF NOT EXISTS mms_parent_story_id_index ON " + TABLE_NAME + " (" + PARENT_STORY_ID + ");",
|
||||
"CREATE INDEX IF NOT EXISTS mms_thread_story_parent_story_index ON " + TABLE_NAME + " (" + THREAD_ID + ", " + DATE_RECEIVED + "," + STORY_TYPE + "," + PARENT_STORY_ID + ");",
|
||||
"CREATE INDEX IF NOT EXISTS mms_quote_id_quote_author_index ON " + TABLE_NAME + "(" + QUOTE_ID + ", " + QUOTE_AUTHOR + ");"
|
||||
"CREATE INDEX IF NOT EXISTS mms_quote_id_quote_author_index ON " + TABLE_NAME + "(" + QUOTE_ID + ", " + QUOTE_AUTHOR + ");",
|
||||
"CREATE INDEX IF NOT EXISTS mms_exported_index ON " + TABLE_NAME + " (" + EXPORTED + ");"
|
||||
};
|
||||
|
||||
private static final String[] MMS_PROJECTION = new String[] {
|
||||
@@ -2466,13 +2468,13 @@ public class MmsDatabase extends MessageDatabase {
|
||||
beginTransaction();
|
||||
try {
|
||||
List<Long> threadsToUpdate = new LinkedList<>();
|
||||
try (Cursor cursor = getReadableDatabase().query(TABLE_NAME, THREAD_ID_PROJECTION, EXPORTED + " = ?", SqlUtil.buildArgs(1), THREAD_ID, null, null, null)) {
|
||||
try (Cursor cursor = getReadableDatabase().query(TABLE_NAME, THREAD_ID_PROJECTION, EXPORTED + " = ?", SqlUtil.buildArgs(MessageExportStatus.EXPORTED), THREAD_ID, null, null, null)) {
|
||||
while (cursor.moveToNext()) {
|
||||
threadsToUpdate.add(CursorUtil.requireLong(cursor, THREAD_ID));
|
||||
}
|
||||
}
|
||||
|
||||
getWritableDatabase().delete(TABLE_NAME, EXPORTED + " = ?", SqlUtil.buildArgs(1));
|
||||
getWritableDatabase().delete(TABLE_NAME, EXPORTED + " = ?", SqlUtil.buildArgs(MessageExportStatus.EXPORTED));
|
||||
|
||||
for (final long threadId : threadsToUpdate) {
|
||||
SignalDatabase.threads().update(threadId, false);
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.signal.core.util.logging.Log;
|
||||
import org.signal.libsignal.protocol.util.Pair;
|
||||
import org.thoughtcrime.securesms.database.MessageDatabase.MessageUpdate;
|
||||
import org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId;
|
||||
import org.thoughtcrime.securesms.database.model.MessageExportStatus;
|
||||
import org.thoughtcrime.securesms.database.model.MessageId;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.MessageExportState;
|
||||
@@ -671,7 +672,16 @@ public class MmsSmsDatabase extends Database {
|
||||
String table = messageId.isMms() ? MmsDatabase.TABLE_NAME : SmsDatabase.TABLE_NAME;
|
||||
ContentValues contentValues = new ContentValues(1);
|
||||
|
||||
contentValues.put(MmsSmsColumns.EXPORTED, 1);
|
||||
contentValues.put(MmsSmsColumns.EXPORTED, MessageExportStatus.EXPORTED.getCode());
|
||||
|
||||
getWritableDatabase().update(table, contentValues, ID_WHERE, SqlUtil.buildArgs(messageId.getId()));
|
||||
}
|
||||
|
||||
public void markMessageExportFailed(@NonNull MessageId messageId) {
|
||||
String table = messageId.isMms() ? MmsDatabase.TABLE_NAME : SmsDatabase.TABLE_NAME;
|
||||
ContentValues contentValues = new ContentValues(1);
|
||||
|
||||
contentValues.put(MmsSmsColumns.EXPORTED, MessageExportStatus.ERROR.getCode());
|
||||
|
||||
getWritableDatabase().update(table, contentValues, ID_WHERE, SqlUtil.buildArgs(messageId.getId()));
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
|
||||
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchSet;
|
||||
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
|
||||
import org.thoughtcrime.securesms.database.model.GroupCallUpdateDetailsUtil;
|
||||
import org.thoughtcrime.securesms.database.model.MessageExportStatus;
|
||||
import org.thoughtcrime.securesms.database.model.MessageId;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId;
|
||||
@@ -146,7 +147,8 @@ public class SmsDatabase extends MessageDatabase {
|
||||
"CREATE INDEX IF NOT EXISTS sms_date_sent_index ON " + TABLE_NAME + " (" + DATE_SENT + ", " + RECIPIENT_ID + ", " + THREAD_ID + ");",
|
||||
"CREATE INDEX IF NOT EXISTS sms_date_server_index ON " + TABLE_NAME + " (" + DATE_SERVER + ");",
|
||||
"CREATE INDEX IF NOT EXISTS sms_thread_date_index ON " + TABLE_NAME + " (" + THREAD_ID + ", " + DATE_RECEIVED + ");",
|
||||
"CREATE INDEX IF NOT EXISTS sms_reactions_unread_index ON " + TABLE_NAME + " (" + REACTIONS_UNREAD + ");"
|
||||
"CREATE INDEX IF NOT EXISTS sms_reactions_unread_index ON " + TABLE_NAME + " (" + REACTIONS_UNREAD + ");",
|
||||
"CREATE INDEX IF NOT EXISTS sms_exported_index ON " + TABLE_NAME + " (" + EXPORTED + ");"
|
||||
};
|
||||
|
||||
private static final String[] MESSAGE_PROJECTION = new String[] {
|
||||
@@ -924,13 +926,13 @@ public class SmsDatabase extends MessageDatabase {
|
||||
beginTransaction();
|
||||
try {
|
||||
List<Long> threadsToUpdate = new LinkedList<>();
|
||||
try (Cursor cursor = getReadableDatabase().query(TABLE_NAME, THREAD_ID_PROJECTION, EXPORTED + " = ?", SqlUtil.buildArgs(1), THREAD_ID, null, null, null)) {
|
||||
try (Cursor cursor = getReadableDatabase().query(TABLE_NAME, THREAD_ID_PROJECTION, EXPORTED + " = ?", SqlUtil.buildArgs(MessageExportStatus.EXPORTED), THREAD_ID, null, null, null)) {
|
||||
while (cursor.moveToNext()) {
|
||||
threadsToUpdate.add(CursorUtil.requireLong(cursor, THREAD_ID));
|
||||
}
|
||||
}
|
||||
|
||||
getWritableDatabase().delete(TABLE_NAME, EXPORTED + " = ?", SqlUtil.buildArgs(1));
|
||||
getWritableDatabase().delete(TABLE_NAME, EXPORTED + " = ?", SqlUtil.buildArgs(MessageExportStatus.EXPORTED));
|
||||
|
||||
for (final long threadId : threadsToUpdate) {
|
||||
SignalDatabase.threads().update(threadId, false);
|
||||
|
||||
@@ -14,13 +14,14 @@ import org.thoughtcrime.securesms.database.helpers.migration.V156_RecipientUnreg
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V157_RecipeintHiddenMigration
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V158_GroupsLastForceUpdateTimestampMigration
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V159_ThreadUnreadSelfMentionCount
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V160_SmsMmsExportedIndexMigration
|
||||
|
||||
/**
|
||||
* Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness.
|
||||
*/
|
||||
object SignalDatabaseMigrations {
|
||||
|
||||
const val DATABASE_VERSION = 159
|
||||
const val DATABASE_VERSION = 160
|
||||
|
||||
@JvmStatic
|
||||
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
@@ -67,6 +68,10 @@ object SignalDatabaseMigrations {
|
||||
if (oldVersion < 159) {
|
||||
V159_ThreadUnreadSelfMentionCount.migrate(context, db, oldVersion, newVersion)
|
||||
}
|
||||
|
||||
if (oldVersion < 160) {
|
||||
V160_SmsMmsExportedIndexMigration.migrate(context, db, oldVersion, newVersion)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.thoughtcrime.securesms.database.helpers.migration
|
||||
|
||||
import android.app.Application
|
||||
import net.zetetic.database.sqlcipher.SQLiteDatabase
|
||||
|
||||
object V160_SmsMmsExportedIndexMigration : SignalDatabaseMigration {
|
||||
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
db.execSQL("CREATE INDEX IF NOT EXISTS sms_exported_index ON sms (exported)")
|
||||
db.execSQL("CREATE INDEX IF NOT EXISTS mms_exported_index ON mms (exported)")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.thoughtcrime.securesms.database.model
|
||||
|
||||
import org.signal.core.util.DatabaseId
|
||||
import org.signal.core.util.IntSerializer
|
||||
|
||||
/**
|
||||
* Export status for a message.
|
||||
*/
|
||||
enum class MessageExportStatus(val code: Int) : DatabaseId {
|
||||
UNEXPORTED(0),
|
||||
EXPORTED(1),
|
||||
ERROR(-1);
|
||||
|
||||
override fun serialize(): String {
|
||||
return Serializer.serialize(this).toString()
|
||||
}
|
||||
|
||||
companion object Serializer : IntSerializer<MessageExportStatus> {
|
||||
override fun serialize(data: MessageExportStatus): Int {
|
||||
return data.code
|
||||
}
|
||||
|
||||
override fun deserialize(data: Int): MessageExportStatus {
|
||||
return when (data) {
|
||||
UNEXPORTED.code -> UNEXPORTED
|
||||
EXPORTED.code -> EXPORTED
|
||||
ERROR.code -> ERROR
|
||||
else -> throw AssertionError("Unknown message export status: $data")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user