diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5951f44968..a4e6bf6d61 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -332,11 +332,6 @@
android:theme="@style/Signal.DayNight.NoActionBar"
android:windowSoftInputMode="adjustResize"/>
-
-
-
{
initializeLogging();
diff --git a/app/src/main/java/org/thoughtcrime/securesms/DatabaseMigrationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/DatabaseMigrationActivity.java
deleted file mode 100644
index 06cd92f665..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/DatabaseMigrationActivity.java
+++ /dev/null
@@ -1,201 +0,0 @@
-package org.thoughtcrime.securesms;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Parcelable;
-import android.view.View;
-import android.widget.Button;
-import android.widget.LinearLayout;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import org.thoughtcrime.securesms.database.SmsMigrator.ProgressDescription;
-import org.thoughtcrime.securesms.service.ApplicationMigrationService;
-import org.thoughtcrime.securesms.service.ApplicationMigrationService.ImportState;
-
-public class DatabaseMigrationActivity extends PassphraseRequiredActivity {
-
- private final ImportServiceConnection serviceConnection = new ImportServiceConnection();
- private final ImportStateHandler importStateHandler = new ImportStateHandler();
- private final BroadcastReceiver completedReceiver = new NullReceiver();
-
- private LinearLayout promptLayout;
- private LinearLayout progressLayout;
- private Button skipButton;
- private Button importButton;
- private ProgressBar progress;
- private TextView progressLabel;
-
- private ApplicationMigrationService importService;
- private boolean isVisible = false;
-
- @Override
- protected void onCreate(Bundle bundle, boolean ready) {
- setContentView(R.layout.database_migration_activity);
-
- initializeResources();
- initializeServiceBinding();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- isVisible = true;
- registerForCompletedNotification();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- isVisible = false;
- unregisterForCompletedNotification();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- shutdownServiceBinding();
- }
-
- @Override
- public void onBackPressed() {
-
- }
-
- private void initializeServiceBinding() {
- Intent intent = new Intent(this, ApplicationMigrationService.class);
- bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
- }
-
- private void initializeResources() {
- this.promptLayout = (LinearLayout)findViewById(R.id.prompt_layout);
- this.progressLayout = (LinearLayout)findViewById(R.id.progress_layout);
- this.skipButton = (Button) findViewById(R.id.skip_button);
- this.importButton = (Button) findViewById(R.id.import_button);
- this.progress = (ProgressBar) findViewById(R.id.import_progress);
- this.progressLabel = (TextView) findViewById(R.id.import_status);
-
- this.progressLayout.setVisibility(View.GONE);
- this.promptLayout.setVisibility(View.GONE);
-
- this.importButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(DatabaseMigrationActivity.this, ApplicationMigrationService.class);
- intent.setAction(ApplicationMigrationService.MIGRATE_DATABASE);
- intent.putExtra("master_secret", (Parcelable)getIntent().getParcelableExtra("master_secret"));
- startService(intent);
-
- promptLayout.setVisibility(View.GONE);
- progressLayout.setVisibility(View.VISIBLE);
- }
- });
-
- this.skipButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- ApplicationMigrationService.setDatabaseImported(DatabaseMigrationActivity.this);
- handleImportComplete();
- }
- });
- }
-
- private void registerForCompletedNotification() {
- IntentFilter filter = new IntentFilter();
- filter.addAction(ApplicationMigrationService.COMPLETED_ACTION);
- filter.setPriority(1000);
-
- registerReceiver(completedReceiver, filter);
- }
-
- private void unregisterForCompletedNotification() {
- unregisterReceiver(completedReceiver);
- }
-
- private void shutdownServiceBinding() {
- unbindService(serviceConnection);
- }
-
- private void handleStateIdle() {
- this.promptLayout.setVisibility(View.VISIBLE);
- this.progressLayout.setVisibility(View.GONE);
- }
-
- private void handleStateProgress(ProgressDescription update) {
- this.promptLayout.setVisibility(View.GONE);
- this.progressLayout.setVisibility(View.VISIBLE);
- this.progressLabel.setText(update.primaryComplete + "/" + update.primaryTotal);
-
- double max = this.progress.getMax();
- double primaryTotal = update.primaryTotal;
- double primaryComplete = update.primaryComplete;
- double secondaryTotal = update.secondaryTotal;
- double secondaryComplete = update.secondaryComplete;
-
- this.progress.setProgress((int)Math.round((primaryComplete / primaryTotal) * max));
- this.progress.setSecondaryProgress((int)Math.round((secondaryComplete / secondaryTotal) * max));
- }
-
- private void handleImportComplete() {
- if (isVisible) {
- if (getIntent().hasExtra("next_intent")) {
- startActivity((Intent)getIntent().getParcelableExtra("next_intent"));
- } else {
- // TODO [greyson] Navigation
- startActivity(MainActivity.clearTop(this));
- }
- }
-
- finish();
- }
-
- private class ImportStateHandler extends Handler {
-
- public ImportStateHandler() {
- super(Looper.getMainLooper());
- }
-
- @Override
- public void handleMessage(Message message) {
- switch (message.what) {
- case ImportState.STATE_IDLE: handleStateIdle(); break;
- case ImportState.STATE_MIGRATING_IN_PROGRESS: handleStateProgress((ProgressDescription)message.obj); break;
- case ImportState.STATE_MIGRATING_COMPLETE: handleImportComplete(); break;
- }
- }
- }
-
- private class ImportServiceConnection implements ServiceConnection {
- @Override
- public void onServiceConnected(ComponentName className, IBinder service) {
- importService = ((ApplicationMigrationService.ApplicationMigrationBinder)service).getService();
- importService.setImportStateHandler(importStateHandler);
-
- ImportState state = importService.getState();
- importStateHandler.obtainMessage(state.state, state.progress).sendToTarget();
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- importService.setImportStateHandler(null);
- }
- }
-
- private static class NullReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- abortBroadcast();
- }
- }
-
-
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/SystemSmsImportReminder.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/SystemSmsImportReminder.java
deleted file mode 100644
index c99bf05b28..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/SystemSmsImportReminder.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.thoughtcrime.securesms.components.reminder;
-
-import android.content.Context;
-import android.content.Intent;
-import android.view.View;
-import android.view.View.OnClickListener;
-
-import org.thoughtcrime.securesms.DatabaseMigrationActivity;
-import org.thoughtcrime.securesms.MainActivity;
-import org.thoughtcrime.securesms.R;
-import org.thoughtcrime.securesms.service.ApplicationMigrationService;
-
-public class SystemSmsImportReminder extends Reminder {
-
- public SystemSmsImportReminder(final Context context) {
- super(context.getString(R.string.reminder_header_sms_import_title),
- context.getString(R.string.reminder_header_sms_import_text));
-
- final OnClickListener okListener = v -> {
- Intent intent = new Intent(context, ApplicationMigrationService.class);
- intent.setAction(ApplicationMigrationService.MIGRATE_DATABASE);
- context.startService(intent);
-
- // TODO [greyson] Navigation
- Intent nextIntent = MainActivity.clearTop(context);
- Intent activityIntent = new Intent(context, DatabaseMigrationActivity.class);
- activityIntent.putExtra("next_intent", nextIntent);
- context.startActivity(activityIntent);
- };
- final OnClickListener cancelListener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- ApplicationMigrationService.setDatabaseImported(context);
- }
- };
- setOkListener(okListener);
- setDismissListener(cancelListener);
- }
-
- public static boolean isEligible(Context context) {
- return !ApplicationMigrationService.isDatabaseImported(context);
- }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/GroupTable.java b/app/src/main/java/org/thoughtcrime/securesms/database/GroupTable.java
index 78c162718b..5be2b06403 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupTable.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupTable.java
@@ -137,7 +137,7 @@ public class GroupTable extends DatabaseTable implements RecipientIdDatabaseRefe
TIMESTAMP, ACTIVE, MMS, V2_MASTER_KEY, V2_REVISION, V2_DECRYPTED_GROUP, LAST_FORCE_UPDATE_TIMESTAMP
};
- static final List TYPED_GROUP_PROJECTION = Stream.of(GROUP_PROJECTION).map(columnName -> TABLE_NAME + "." + columnName).toList();
+ static final List TYPED_GROUP_PROJECTION = Stream.of(GROUP_PROJECTION).filterNot(it -> it.equals(RECIPIENT_ID)).map(columnName -> TABLE_NAME + "." + columnName).toList();
public GroupTable(Context context, SignalDatabase databaseHelper) {
super(context, databaseHelper);
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.java b/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.java
index 23502f8aad..e5323428ba 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.java
@@ -48,7 +48,7 @@ public class MediaTable extends DatabaseTable {
+ AttachmentTable.TABLE_NAME + "." + AttachmentTable.CAPTION + ", "
+ AttachmentTable.TABLE_NAME + "." + AttachmentTable.NAME + ", "
+ AttachmentTable.TABLE_NAME + "." + AttachmentTable.UPLOAD_TIMESTAMP + ", "
- + MmsTable.TABLE_NAME + "." + MmsTable.MESSAGE_BOX + ", "
+ + MmsTable.TABLE_NAME + "." + MmsTable.TYPE + ", "
+ MmsTable.TABLE_NAME + "." + MmsTable.DATE_SENT + ", "
+ MmsTable.TABLE_NAME + "." + MmsTable.DATE_RECEIVED + ", "
+ MmsTable.TABLE_NAME + "." + MmsTable.DATE_SERVER + ", "
@@ -67,7 +67,7 @@ public class MediaTable extends DatabaseTable {
+ AttachmentTable.DATA + " IS NOT NULL AND "
+ "(" + AttachmentTable.QUOTE + " = 0 OR (" + AttachmentTable.QUOTE + " = 1 AND " + AttachmentTable.DATA_HASH + " IS NULL)) AND "
+ AttachmentTable.STICKER_PACK_ID + " IS NULL AND "
- + MmsTable.RECIPIENT_ID + " > 0 AND "
+ + MmsTable.TABLE_NAME + "." + MmsTable.RECIPIENT_ID + " > 0 AND "
+ THREAD_RECIPIENT_ID + " > 0";
private static final String UNIQUE_MEDIA_QUERY = "SELECT "
@@ -194,11 +194,11 @@ public class MediaTable extends DatabaseTable {
List attachments = attachmentDatabase.getAttachments(cursor);
RecipientId recipientId = RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.RECIPIENT_ID)));
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.THREAD_ID));
- boolean outgoing = MessageTable.Types.isOutgoingMessageType(cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.MESSAGE_BOX)));
+ boolean outgoing = MessageTable.Types.isOutgoingMessageType(cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.TYPE)));
long date;
- if (MmsTable.Types.isPushType(cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.MESSAGE_BOX)))) {
+ if (MmsTable.Types.isPushType(cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.TYPE)))) {
date = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.DATE_SENT));
} else {
date = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.DATE_RECEIVED));
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.java b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.java
index 1088305ba2..46310a1a01 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.java
@@ -197,7 +197,6 @@ public abstract class MessageTable extends DatabaseTable implements MmsSmsColumn
public abstract void endTransaction(SQLiteDatabase database);
public abstract void setTransactionSuccessful();
public abstract void endTransaction();
- public abstract SQLiteStatement createInsertStatement(SQLiteDatabase database);
public abstract void ensureMigration();
@@ -233,7 +232,7 @@ public abstract class MessageTable extends DatabaseTable implements MmsSmsColumn
final @NonNull String getOutgoingTypeClause() {
List segments = new ArrayList<>(Types.OUTGOING_MESSAGE_TYPES.length);
for (long outgoingMessageType : Types.OUTGOING_MESSAGE_TYPES) {
- segments.add("(" + getTypeField() + " & " + Types.BASE_TYPE_MASK + " = " + outgoingMessageType + ")");
+ segments.add("(" + getTableName() + "." + getTypeField() + " & " + Types.BASE_TYPE_MASK + " = " + outgoingMessageType + ")");
}
return Util.join(segments, " OR ");
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsColumns.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsColumns.java
index a80fd6ee6f..5dbd4d0a5c 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsColumns.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsColumns.java
@@ -4,21 +4,21 @@ package org.thoughtcrime.securesms.database;
public interface MmsSmsColumns {
public static final String ID = "_id";
- public static final String NORMALIZED_DATE_SENT = "date_sent";
- public static final String NORMALIZED_DATE_RECEIVED = "date_received";
- public static final String NORMALIZED_TYPE = "type";
+ public static final String DATE_SENT = "date_sent";
+ public static final String DATE_RECEIVED = "date_received";
+ public static final String TYPE = "type";
public static final String DATE_SERVER = "date_server";
public static final String THREAD_ID = "thread_id";
public static final String READ = "read";
public static final String BODY = "body";
- public static final String RECIPIENT_ID = "address";
- public static final String ADDRESS_DEVICE_ID = "address_device_id";
+ public static final String RECIPIENT_ID = "recipient_id";
+ public static final String RECIPIENT_DEVICE_ID = "recipient_device_id";
public static final String DELIVERY_RECEIPT_COUNT = "delivery_receipt_count";
public static final String READ_RECEIPT_COUNT = "read_receipt_count";
public static final String VIEWED_RECEIPT_COUNT = "viewed_receipt_count";
public static final String MISMATCHED_IDENTITIES = "mismatched_identities";
public static final String UNIQUE_ROW_ID = "unique_row_id";
- public static final String SUBSCRIPTION_ID = "subscription_id";
+ public static final String SMS_SUBSCRIPTION_ID = "subscription_id";
public static final String EXPIRES_IN = "expires_in";
public static final String EXPIRE_STARTED = "expire_started";
public static final String NOTIFIED = "notified";
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsTable.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsTable.java
index 6b92fec9bf..0551909f20 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsTable.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsTable.java
@@ -70,30 +70,27 @@ public class MmsSmsTable extends DatabaseTable {
private static final String[] PROJECTION = { MmsSmsColumns.ID,
MmsSmsColumns.UNIQUE_ROW_ID,
- SmsTable.BODY,
- SmsTable.TYPE,
+ MmsSmsColumns.BODY,
+ MmsSmsColumns.TYPE,
MmsSmsColumns.THREAD_ID,
SmsTable.RECIPIENT_ID,
- SmsTable.ADDRESS_DEVICE_ID,
- SmsTable.SUBJECT,
- MmsSmsColumns.NORMALIZED_DATE_SENT,
- MmsSmsColumns.NORMALIZED_DATE_RECEIVED,
+ SmsTable.RECIPIENT_DEVICE_ID,
+ MmsSmsColumns.DATE_SENT,
+ MmsSmsColumns.DATE_RECEIVED,
MmsSmsColumns.DATE_SERVER,
- MmsTable.MESSAGE_TYPE,
- MmsTable.MESSAGE_BOX,
- SmsTable.STATUS,
+ MmsTable.MMS_MESSAGE_TYPE,
+ SmsTable.SMS_STATUS,
MmsSmsColumns.UNIDENTIFIED,
- MmsTable.PART_COUNT,
- MmsTable.CONTENT_LOCATION,
- MmsTable.TRANSACTION_ID,
- MmsTable.MESSAGE_SIZE,
- MmsTable.EXPIRY,
- MmsTable.STATUS,
+ MmsTable.MMS_CONTENT_LOCATION,
+ MmsTable.MMS_TRANSACTION_ID,
+ MmsTable.MMS_MESSAGE_SIZE,
+ MmsTable.MMS_EXPIRY,
+ MmsTable.MMS_STATUS,
MmsSmsColumns.DELIVERY_RECEIPT_COUNT,
MmsSmsColumns.READ_RECEIPT_COUNT,
MmsSmsColumns.MISMATCHED_IDENTITIES,
- MmsTable.NETWORK_FAILURE,
- MmsSmsColumns.SUBSCRIPTION_ID,
+ MmsTable.NETWORK_FAILURES,
+ MmsSmsColumns.SMS_SUBSCRIPTION_ID,
MmsSmsColumns.EXPIRES_IN,
MmsSmsColumns.EXPIRE_STARTED,
MmsSmsColumns.NOTIFIED,
@@ -103,7 +100,6 @@ public class MmsSmsTable extends DatabaseTable {
MmsTable.QUOTE_AUTHOR,
MmsTable.QUOTE_BODY,
MmsTable.QUOTE_MISSING,
- MmsTable.QUOTE_ATTACHMENT,
MmsTable.QUOTE_TYPE,
MmsTable.QUOTE_MENTIONS,
MmsTable.SHARED_CONTACTS,
@@ -121,12 +117,12 @@ public class MmsSmsTable extends DatabaseTable {
MmsTable.STORY_TYPE,
MmsTable.PARENT_STORY_ID};
- private static final String SNIPPET_QUERY = "SELECT " + MmsSmsColumns.ID + ", 0 AS " + TRANSPORT + ", " + SmsTable.TYPE + " AS " + MmsSmsColumns.NORMALIZED_TYPE + ", " + SmsTable.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " FROM " + SmsTable.TABLE_NAME + " " +
- "WHERE " + MmsSmsColumns.THREAD_ID + " = ? AND " + SmsTable.TYPE + " NOT IN (" + SmsTable.Types.PROFILE_CHANGE_TYPE + ", " + SmsTable.Types.GV1_MIGRATION_TYPE + ", " + SmsTable.Types.CHANGE_NUMBER_TYPE + ", " + SmsTable.Types.BOOST_REQUEST_TYPE + ", " + SmsTable.Types.SMS_EXPORT_TYPE + ") AND " + SmsTable.TYPE + " & " + GROUP_V2_LEAVE_BITS + " != " + GROUP_V2_LEAVE_BITS + " " +
+ private static final String SNIPPET_QUERY = "SELECT " + MmsSmsColumns.ID + ", 0 AS " + TRANSPORT + ", " + MmsSmsColumns.TYPE + ", " + MmsSmsColumns.DATE_RECEIVED + " FROM " + SmsTable.TABLE_NAME + " " +
+ "WHERE " + MmsSmsColumns.THREAD_ID + " = ? AND " + MmsSmsColumns.TYPE + " NOT IN (" + SmsTable.Types.PROFILE_CHANGE_TYPE + ", " + SmsTable.Types.GV1_MIGRATION_TYPE + ", " + SmsTable.Types.CHANGE_NUMBER_TYPE + ", " + SmsTable.Types.BOOST_REQUEST_TYPE + ", " + SmsTable.Types.SMS_EXPORT_TYPE + ") AND " + SmsTable.TYPE + " & " + GROUP_V2_LEAVE_BITS + " != " + GROUP_V2_LEAVE_BITS + " " +
"UNION ALL " +
- "SELECT " + MmsSmsColumns.ID + ", 1 AS " + TRANSPORT + ", " + MmsTable.MESSAGE_BOX + " AS " + MmsSmsColumns.NORMALIZED_TYPE + ", " + MmsTable.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " FROM " + MmsTable.TABLE_NAME + " " +
- "WHERE " + MmsSmsColumns.THREAD_ID + " = ? AND " + MmsTable.MESSAGE_BOX + " & " + GROUP_V2_LEAVE_BITS + " != " + GROUP_V2_LEAVE_BITS + " AND " + MmsTable.STORY_TYPE + " = 0 AND " + MmsTable.PARENT_STORY_ID + " <= 0 " +
- "ORDER BY " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC " +
+ "SELECT " + MmsSmsColumns.ID + ", 1 AS " + TRANSPORT + ", " + MmsSmsColumns.TYPE + ", " + MmsTable.DATE_RECEIVED + " FROM " + MmsTable.TABLE_NAME + " " +
+ "WHERE " + MmsSmsColumns.THREAD_ID + " = ? AND " + MmsTable.TYPE + " & " + GROUP_V2_LEAVE_BITS + " != " + GROUP_V2_LEAVE_BITS + " AND " + MmsTable.STORY_TYPE + " = 0 AND " + MmsTable.PARENT_STORY_ID + " <= 0 " +
+ "ORDER BY " + MmsSmsColumns.DATE_RECEIVED + " DESC " +
"LIMIT 1";
public MmsSmsTable(Context context, SignalDatabase databaseHelper) {
@@ -165,7 +161,7 @@ public class MmsSmsTable extends DatabaseTable {
public int getMessagePositionOnOrAfterTimestamp(long threadId, long timestamp) {
String[] projection = new String[] { "COUNT(*)" };
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " +
- MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " >= " + timestamp + " AND " +
+ MmsSmsColumns.DATE_RECEIVED + " >= " + timestamp + " AND " +
MmsTable.STORY_TYPE + " = 0 AND " + MmsTable.PARENT_STORY_ID + " <= 0";
try (Cursor cursor = queryTables(projection, selection, null, null, false)) {
@@ -179,7 +175,7 @@ public class MmsSmsTable extends DatabaseTable {
public @Nullable MessageRecord getMessageFor(long timestamp, RecipientId authorId) {
Recipient author = Recipient.resolved(authorId);
- try (Cursor cursor = queryTables(PROJECTION, MmsSmsColumns.NORMALIZED_DATE_SENT + " = " + timestamp, null, null, true)) {
+ try (Cursor cursor = queryTables(PROJECTION, MmsSmsColumns.DATE_SENT + " = " + timestamp, null, null, true)) {
MmsSmsTable.Reader reader = readerFor(cursor);
MessageRecord messageRecord;
@@ -210,7 +206,7 @@ public class MmsSmsTable extends DatabaseTable {
public Cursor getConversation(long threadId, long offset, long limit) {
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
- String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC";
+ String order = MmsSmsColumns.DATE_RECEIVED + " DESC";
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MmsTable.STORY_TYPE + " = 0 AND " + MmsTable.PARENT_STORY_ID + " <= 0";
String limitStr = limit > 0 || offset > 0 ? offset + ", " + limit : null;
String query = buildQuery(PROJECTION, selection, order, limitStr, false);
@@ -249,7 +245,7 @@ public class MmsSmsTable extends DatabaseTable {
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
try (Cursor cursor = db.rawQuery(SNIPPET_QUERY, SqlUtil.buildArgs(threadId, threadId))) {
if (cursor.moveToFirst()) {
- return CursorUtil.requireLong(cursor, MmsSmsColumns.NORMALIZED_TYPE);
+ return CursorUtil.requireLong(cursor, MmsSmsColumns.TYPE);
} else {
throw new NoSuchMessageException("no message");
}
@@ -266,14 +262,14 @@ public class MmsSmsTable extends DatabaseTable {
.append(MmsSmsColumns.THREAD_ID + " = ")
.append(stickyThread.getConversationId().getThreadId())
.append(" AND ")
- .append(MmsSmsColumns.NORMALIZED_DATE_RECEIVED)
+ .append(MmsSmsColumns.DATE_RECEIVED)
.append(" >= ")
.append(stickyThread.getEarliestTimestamp())
.append(getStickyWherePartForParentStoryId(stickyThread.getConversationId().getGroupStoryId()))
.append(")");
}
- String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " ASC";
+ String order = MmsSmsColumns.DATE_RECEIVED + " ASC";
String selection = MmsSmsColumns.NOTIFIED + " = 0 AND " + MmsTable.STORY_TYPE + " = 0 AND (" + MmsSmsColumns.READ + " = 0 OR " + MmsSmsColumns.REACTIONS_UNREAD + " = 1" + (stickyQuery.length() > 0 ? " OR (" + stickyQuery + ")" : "") + ")";
return queryTables(PROJECTION, selection, order, null, true);
@@ -304,7 +300,7 @@ public class MmsSmsTable extends DatabaseTable {
RecipientId author = targetMessage.isOutgoing() ? Recipient.self().getId() : targetMessage.getRecipient().getId();
String query = MmsTable.QUOTE_ID + " = " + targetMessage.getDateSent() + " AND " + MmsTable.QUOTE_AUTHOR + " = " + author.serialize();
- String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC";
+ String order = MmsSmsColumns.DATE_RECEIVED + " DESC";
List records = new ArrayList<>();
@@ -421,7 +417,7 @@ public class MmsSmsTable extends DatabaseTable {
}
public int getMessageCountBeforeDate(long date) {
- String selection = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " < " + date;
+ String selection = MmsSmsColumns.DATE_RECEIVED + " < " + date;
try (Cursor cursor = queryTables(new String[] { "COUNT(*)" }, selection, null, null, false)) {
if (cursor != null && cursor.moveToFirst()) {
@@ -761,10 +757,10 @@ public class MmsSmsTable extends DatabaseTable {
}
public int getQuotedMessagePosition(long threadId, long quoteId, @NonNull RecipientId recipientId) {
- String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC";
+ String order = MmsSmsColumns.DATE_RECEIVED + " DESC";
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MmsTable.STORY_TYPE + " = 0" + " AND " + MmsTable.PARENT_STORY_ID + " <= 0";
- try (Cursor cursor = queryTables(new String[]{ MmsSmsColumns.NORMALIZED_DATE_SENT, MmsSmsColumns.RECIPIENT_ID, MmsSmsColumns.REMOTE_DELETED}, selection, order, null, false)) {
+ try (Cursor cursor = queryTables(new String[]{ MmsSmsColumns.DATE_SENT, MmsSmsColumns.RECIPIENT_ID, MmsSmsColumns.REMOTE_DELETED}, selection, order, null, false)) {
boolean isOwnNumber = Recipient.resolved(recipientId).isSelf();
while (cursor != null && cursor.moveToNext()) {
@@ -784,10 +780,10 @@ public class MmsSmsTable extends DatabaseTable {
}
public int getMessagePositionInConversation(long threadId, long receivedTimestamp, @NonNull RecipientId recipientId) {
- String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC";
+ String order = MmsSmsColumns.DATE_RECEIVED + " DESC";
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MmsTable.STORY_TYPE + " = 0" + " AND " + MmsTable.PARENT_STORY_ID + " <= 0";
- try (Cursor cursor = queryTables(new String[]{ MmsSmsColumns.NORMALIZED_DATE_RECEIVED, MmsSmsColumns.RECIPIENT_ID, MmsSmsColumns.REMOTE_DELETED}, selection, order, null, false)) {
+ try (Cursor cursor = queryTables(new String[]{ MmsSmsColumns.DATE_RECEIVED, MmsSmsColumns.RECIPIENT_ID, MmsSmsColumns.REMOTE_DELETED}, selection, order, null, false)) {
boolean isOwnNumber = Recipient.resolved(recipientId).isSelf();
while (cursor != null && cursor.moveToNext()) {
@@ -831,14 +827,14 @@ public class MmsSmsTable extends DatabaseTable {
final String selection;
if (groupStoryId > 0) {
- order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " ASC";
+ order = MmsSmsColumns.DATE_RECEIVED + " ASC";
selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " +
- MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " < " + receivedTimestamp + " AND " +
+ MmsSmsColumns.DATE_RECEIVED + " < " + receivedTimestamp + " AND " +
MmsTable.STORY_TYPE + " = 0 AND " + MmsTable.PARENT_STORY_ID + " = " + groupStoryId;
} else {
- order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC";
+ order = MmsSmsColumns.DATE_RECEIVED + " DESC";
selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " +
- MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " > " + receivedTimestamp + " AND " +
+ MmsSmsColumns.DATE_RECEIVED + " > " + receivedTimestamp + " AND " +
MmsTable.STORY_TYPE + " = 0 AND " + MmsTable.PARENT_STORY_ID + " <= 0";
}
@@ -851,10 +847,10 @@ public class MmsSmsTable extends DatabaseTable {
}
public long getTimestampForFirstMessageAfterDate(long date) {
- String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " ASC";
- String selection = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " > " + date;
+ String order = MmsSmsColumns.DATE_RECEIVED + " ASC";
+ String selection = MmsSmsColumns.DATE_RECEIVED + " > " + date;
- try (Cursor cursor = queryTables(new String[] { MmsSmsColumns.NORMALIZED_DATE_RECEIVED }, selection, order, "1", false)) {
+ try (Cursor cursor = queryTables(new String[] { MmsSmsColumns.DATE_RECEIVED }, selection, order, "1", false)) {
if (cursor != null && cursor.moveToFirst()) {
return cursor.getLong(0);
}
@@ -926,41 +922,37 @@ public class MmsSmsTable extends DatabaseTable {
attachmentJsonJoin = "NULL";
}
- String[] mmsProjection = { MmsTable.DATE_SENT + " AS " + MmsSmsColumns.NORMALIZED_DATE_SENT,
- MmsTable.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED,
+ String[] mmsProjection = { MmsSmsColumns.DATE_SENT,
+ MmsSmsColumns.DATE_RECEIVED,
MmsTable.TABLE_NAME + "." + MmsTable.ID + " AS " + MmsSmsColumns.ID,
"'MMS::' || " + MmsTable.TABLE_NAME + "." + MmsTable.ID + " || '::' || " + MmsTable.DATE_SENT + " AS " + MmsSmsColumns.UNIQUE_ROW_ID,
- attachmentJsonJoin + " AS " + AttachmentTable.ATTACHMENT_JSON_ALIAS,
+ attachmentJsonJoin + " AS " + AttachmentTable.ATTACHMENT_JSON_ALIAS,
SmsTable.BODY,
MmsSmsColumns.READ,
MmsSmsColumns.THREAD_ID,
- SmsTable.TYPE,
- SmsTable.RECIPIENT_ID,
- SmsTable.ADDRESS_DEVICE_ID,
- SmsTable.SUBJECT,
- MmsTable.MESSAGE_TYPE,
- MmsTable.MESSAGE_BOX,
- SmsTable.STATUS,
- MmsTable.PART_COUNT,
- MmsTable.CONTENT_LOCATION,
- MmsTable.TRANSACTION_ID,
- MmsTable.MESSAGE_SIZE,
- MmsTable.EXPIRY,
- MmsTable.STATUS,
+ MmsSmsColumns.TYPE,
+ MmsSmsColumns.RECIPIENT_ID,
+ MmsSmsColumns.RECIPIENT_DEVICE_ID,
+ MmsTable.MMS_MESSAGE_TYPE,
+ SmsTable.SMS_STATUS,
+ MmsTable.MMS_CONTENT_LOCATION,
+ MmsTable.MMS_TRANSACTION_ID,
+ MmsTable.MMS_MESSAGE_SIZE,
+ MmsTable.MMS_EXPIRY,
+ MmsTable.MMS_STATUS,
MmsTable.UNIDENTIFIED,
MmsSmsColumns.DELIVERY_RECEIPT_COUNT,
MmsSmsColumns.READ_RECEIPT_COUNT,
MmsSmsColumns.MISMATCHED_IDENTITIES,
- MmsSmsColumns.SUBSCRIPTION_ID,
+ MmsSmsColumns.SMS_SUBSCRIPTION_ID,
MmsSmsColumns.EXPIRES_IN,
MmsSmsColumns.EXPIRE_STARTED,
MmsSmsColumns.NOTIFIED,
- MmsTable.NETWORK_FAILURE, TRANSPORT,
+ MmsTable.NETWORK_FAILURES, TRANSPORT,
MmsTable.QUOTE_ID,
MmsTable.QUOTE_AUTHOR,
MmsTable.QUOTE_BODY,
MmsTable.QUOTE_MISSING,
- MmsTable.QUOTE_ATTACHMENT,
MmsTable.QUOTE_TYPE,
MmsTable.QUOTE_MENTIONS,
MmsTable.SHARED_CONTACTS,
@@ -978,26 +970,36 @@ public class MmsSmsTable extends DatabaseTable {
MmsTable.STORY_TYPE,
MmsTable.PARENT_STORY_ID};
- String[] smsProjection = { SmsTable.DATE_SENT + " AS " + MmsSmsColumns.NORMALIZED_DATE_SENT,
- SmsTable.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED,
+ String[] smsProjection = { MmsSmsColumns.DATE_SENT,
+ MmsSmsColumns.DATE_RECEIVED,
MmsSmsColumns.ID, "'SMS::' || " + MmsSmsColumns.ID + " || '::' || " + SmsTable.DATE_SENT + " AS " + MmsSmsColumns.UNIQUE_ROW_ID,
- "NULL AS " + AttachmentTable.ATTACHMENT_JSON_ALIAS,
- SmsTable.BODY, MmsSmsColumns.READ, MmsSmsColumns.THREAD_ID,
- SmsTable.TYPE, SmsTable.RECIPIENT_ID, SmsTable.ADDRESS_DEVICE_ID, SmsTable.SUBJECT, MmsTable.MESSAGE_TYPE,
- MmsTable.MESSAGE_BOX, SmsTable.STATUS, MmsTable.PART_COUNT,
- MmsTable.CONTENT_LOCATION, MmsTable.TRANSACTION_ID,
- MmsTable.MESSAGE_SIZE, MmsTable.EXPIRY, MmsTable.STATUS,
+ "NULL AS " + AttachmentTable.ATTACHMENT_JSON_ALIAS,
+ SmsTable.BODY,
+ MmsSmsColumns.READ,
+ MmsSmsColumns.THREAD_ID,
+ MmsSmsColumns.TYPE,
+ SmsTable.RECIPIENT_ID,
+ SmsTable.RECIPIENT_DEVICE_ID,
+ MmsTable.MMS_MESSAGE_TYPE,
+ SmsTable.SMS_STATUS,
+ MmsTable.MMS_CONTENT_LOCATION,
+ MmsTable.MMS_TRANSACTION_ID,
+ MmsTable.MMS_MESSAGE_SIZE,
+ MmsTable.MMS_EXPIRY,
+ MmsTable.MMS_STATUS,
MmsTable.UNIDENTIFIED,
- MmsSmsColumns.DELIVERY_RECEIPT_COUNT, MmsSmsColumns.READ_RECEIPT_COUNT,
+ MmsSmsColumns.DELIVERY_RECEIPT_COUNT,
+ MmsSmsColumns.READ_RECEIPT_COUNT,
MmsSmsColumns.MISMATCHED_IDENTITIES,
- MmsSmsColumns.SUBSCRIPTION_ID, MmsSmsColumns.EXPIRES_IN, MmsSmsColumns.EXPIRE_STARTED,
+ MmsSmsColumns.SMS_SUBSCRIPTION_ID,
+ MmsSmsColumns.EXPIRES_IN,
+ MmsSmsColumns.EXPIRE_STARTED,
MmsSmsColumns.NOTIFIED,
- MmsTable.NETWORK_FAILURE, TRANSPORT,
+ MmsTable.NETWORK_FAILURES, TRANSPORT,
MmsTable.QUOTE_ID,
MmsTable.QUOTE_AUTHOR,
MmsTable.QUOTE_BODY,
MmsTable.QUOTE_MISSING,
- MmsTable.QUOTE_ATTACHMENT,
MmsTable.QUOTE_TYPE,
MmsTable.QUOTE_MENTIONS,
MmsTable.SHARED_CONTACTS,
@@ -1038,32 +1040,30 @@ public class MmsSmsTable extends DatabaseTable {
mmsColumnsPresent.add(MmsSmsColumns.THREAD_ID);
mmsColumnsPresent.add(MmsSmsColumns.BODY);
mmsColumnsPresent.add(MmsSmsColumns.RECIPIENT_ID);
- mmsColumnsPresent.add(MmsSmsColumns.ADDRESS_DEVICE_ID);
+ mmsColumnsPresent.add(MmsSmsColumns.RECIPIENT_DEVICE_ID);
mmsColumnsPresent.add(MmsSmsColumns.DELIVERY_RECEIPT_COUNT);
mmsColumnsPresent.add(MmsSmsColumns.READ_RECEIPT_COUNT);
mmsColumnsPresent.add(MmsSmsColumns.MISMATCHED_IDENTITIES);
- mmsColumnsPresent.add(MmsSmsColumns.SUBSCRIPTION_ID);
+ mmsColumnsPresent.add(MmsSmsColumns.SMS_SUBSCRIPTION_ID);
mmsColumnsPresent.add(MmsSmsColumns.EXPIRES_IN);
mmsColumnsPresent.add(MmsSmsColumns.EXPIRE_STARTED);
- mmsColumnsPresent.add(MmsTable.MESSAGE_TYPE);
- mmsColumnsPresent.add(MmsTable.MESSAGE_BOX);
+ mmsColumnsPresent.add(MmsTable.MMS_MESSAGE_TYPE);
+ mmsColumnsPresent.add(MmsTable.TYPE);
mmsColumnsPresent.add(MmsTable.DATE_SENT);
mmsColumnsPresent.add(MmsTable.DATE_RECEIVED);
mmsColumnsPresent.add(MmsTable.DATE_SERVER);
- mmsColumnsPresent.add(MmsTable.PART_COUNT);
- mmsColumnsPresent.add(MmsTable.CONTENT_LOCATION);
- mmsColumnsPresent.add(MmsTable.TRANSACTION_ID);
- mmsColumnsPresent.add(MmsTable.MESSAGE_SIZE);
- mmsColumnsPresent.add(MmsTable.EXPIRY);
+ mmsColumnsPresent.add(MmsTable.MMS_CONTENT_LOCATION);
+ mmsColumnsPresent.add(MmsTable.MMS_TRANSACTION_ID);
+ mmsColumnsPresent.add(MmsTable.MMS_MESSAGE_SIZE);
+ mmsColumnsPresent.add(MmsTable.MMS_EXPIRY);
mmsColumnsPresent.add(MmsTable.NOTIFIED);
- mmsColumnsPresent.add(MmsTable.STATUS);
+ mmsColumnsPresent.add(MmsTable.MMS_STATUS);
mmsColumnsPresent.add(MmsTable.UNIDENTIFIED);
- mmsColumnsPresent.add(MmsTable.NETWORK_FAILURE);
+ mmsColumnsPresent.add(MmsTable.NETWORK_FAILURES);
mmsColumnsPresent.add(MmsTable.QUOTE_ID);
mmsColumnsPresent.add(MmsTable.QUOTE_AUTHOR);
mmsColumnsPresent.add(MmsTable.QUOTE_BODY);
mmsColumnsPresent.add(MmsTable.QUOTE_MISSING);
- mmsColumnsPresent.add(MmsTable.QUOTE_ATTACHMENT);
mmsColumnsPresent.add(MmsTable.QUOTE_TYPE);
mmsColumnsPresent.add(MmsTable.QUOTE_MENTIONS);
mmsColumnsPresent.add(MmsTable.SHARED_CONTACTS);
@@ -1084,22 +1084,21 @@ public class MmsSmsTable extends DatabaseTable {
smsColumnsPresent.add(MmsSmsColumns.ID);
smsColumnsPresent.add(MmsSmsColumns.BODY);
smsColumnsPresent.add(MmsSmsColumns.RECIPIENT_ID);
- smsColumnsPresent.add(MmsSmsColumns.ADDRESS_DEVICE_ID);
+ smsColumnsPresent.add(MmsSmsColumns.RECIPIENT_DEVICE_ID);
smsColumnsPresent.add(MmsSmsColumns.READ);
smsColumnsPresent.add(MmsSmsColumns.THREAD_ID);
smsColumnsPresent.add(MmsSmsColumns.DELIVERY_RECEIPT_COUNT);
smsColumnsPresent.add(MmsSmsColumns.READ_RECEIPT_COUNT);
smsColumnsPresent.add(MmsSmsColumns.MISMATCHED_IDENTITIES);
- smsColumnsPresent.add(MmsSmsColumns.SUBSCRIPTION_ID);
+ smsColumnsPresent.add(MmsSmsColumns.SMS_SUBSCRIPTION_ID);
smsColumnsPresent.add(MmsSmsColumns.EXPIRES_IN);
smsColumnsPresent.add(MmsSmsColumns.EXPIRE_STARTED);
smsColumnsPresent.add(MmsSmsColumns.NOTIFIED);
smsColumnsPresent.add(SmsTable.TYPE);
- smsColumnsPresent.add(SmsTable.SUBJECT);
smsColumnsPresent.add(SmsTable.DATE_SENT);
smsColumnsPresent.add(SmsTable.DATE_RECEIVED);
smsColumnsPresent.add(SmsTable.DATE_SERVER);
- smsColumnsPresent.add(SmsTable.STATUS);
+ smsColumnsPresent.add(SmsTable.SMS_STATUS);
smsColumnsPresent.add(SmsTable.UNIDENTIFIED);
smsColumnsPresent.add(SmsTable.REACTIONS_UNREAD);
smsColumnsPresent.add(SmsTable.REACTIONS_LAST_SEEN);
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsTable.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsTable.java
index 6afa3d7af7..09e6794662 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsTable.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsTable.java
@@ -31,8 +31,6 @@ import com.google.android.mms.pdu_alt.NotificationInd;
import com.google.android.mms.pdu_alt.PduHeaders;
import com.google.protobuf.InvalidProtocolBufferException;
-import net.zetetic.database.sqlcipher.SQLiteStatement;
-
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -121,80 +119,73 @@ public class MmsTable extends MessageTable {
private static final String TAG = Log.tag(MmsTable.class);
- public static final String TABLE_NAME = "mms";
- static final String DATE_SENT = "date";
- static final String DATE_RECEIVED = "date_received";
- public static final String MESSAGE_BOX = "msg_box";
- static final String CONTENT_LOCATION = "ct_l";
- static final String EXPIRY = "exp";
- public static final String MESSAGE_TYPE = "m_type";
- static final String MESSAGE_SIZE = "m_size";
- static final String STATUS = "st";
- static final String TRANSACTION_ID = "tr_id";
- static final String PART_COUNT = "part_count";
- static final String NETWORK_FAILURE = "network_failures";
+ public static final String TABLE_NAME = "mms";
+ static final String MMS_CONTENT_LOCATION = "ct_l";
+ static final String MMS_EXPIRY = "exp";
+ public static final String MMS_MESSAGE_TYPE = "m_type";
+ static final String MMS_MESSAGE_SIZE = "m_size";
+ static final String MMS_STATUS = "st";
+ static final String MMS_TRANSACTION_ID = "tr_id";
+ static final String NETWORK_FAILURES = "network_failures";
static final String QUOTE_ID = "quote_id";
static final String QUOTE_AUTHOR = "quote_author";
static final String QUOTE_BODY = "quote_body";
- static final String QUOTE_ATTACHMENT = "quote_attachment";
static final String QUOTE_MISSING = "quote_missing";
static final String QUOTE_MENTIONS = "quote_mentions";
static final String QUOTE_TYPE = "quote_type";
static final String SHARED_CONTACTS = "shared_contacts";
- static final String LINK_PREVIEWS = "previews";
+ static final String LINK_PREVIEWS = "link_previews";
static final String MENTIONS_SELF = "mentions_self";
- static final String MESSAGE_RANGES = "ranges";
+ static final String MESSAGE_RANGES = "message_ranges";
- public static final String VIEW_ONCE = "reveal_duration";
- public static final String STORY_TYPE = "is_story";
+ public static final String VIEW_ONCE = "view_once";
+ public static final String STORY_TYPE = "story_type";
static final String PARENT_STORY_ID = "parent_story_id";
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
- THREAD_ID + " INTEGER, " +
- DATE_SENT + " INTEGER, " +
- DATE_RECEIVED + " INTEGER, " +
+ DATE_SENT + " INTEGER NOT NULL, " +
+ DATE_RECEIVED + " INTEGER NOT NULL, " +
DATE_SERVER + " INTEGER DEFAULT -1, " +
- MESSAGE_BOX + " INTEGER, " +
- READ + " INTEGER DEFAULT 0, " +
+ THREAD_ID + " INTEGER NOT NULL REFERENCES " + ThreadTable.TABLE_NAME + " (" + ThreadTable.ID + ") ON DELETE CASCADE, " +
+ RECIPIENT_ID + " INTEGER NOT NULL REFERENCES " + RecipientTable.TABLE_NAME + " (" + RecipientTable.ID + ") ON DELETE CASCADE, " +
+ RECIPIENT_DEVICE_ID + " INTEGER, " +
+ TYPE + " INTEGER NOT NULL, " +
BODY + " TEXT, " +
- PART_COUNT + " INTEGER, " +
- CONTENT_LOCATION + " TEXT, " +
- RECIPIENT_ID + " INTEGER, " +
- ADDRESS_DEVICE_ID + " INTEGER, " +
- EXPIRY + " INTEGER, " +
- MESSAGE_TYPE + " INTEGER, " +
- MESSAGE_SIZE + " INTEGER, " +
- STATUS + " INTEGER, " +
- TRANSACTION_ID + " TEXT, " +
+ READ + " INTEGER DEFAULT 0, " +
+ MMS_CONTENT_LOCATION + " TEXT, " +
+ MMS_EXPIRY + " INTEGER, " +
+ MMS_MESSAGE_TYPE + " INTEGER, " +
+ MMS_MESSAGE_SIZE + " INTEGER, " +
+ MMS_STATUS + " INTEGER, " +
+ MMS_TRANSACTION_ID + " TEXT, " +
+ SMS_SUBSCRIPTION_ID + " INTEGER DEFAULT -1, " +
+ RECEIPT_TIMESTAMP + " INTEGER DEFAULT -1, " +
DELIVERY_RECEIPT_COUNT + " INTEGER DEFAULT 0, " +
+ READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " +
+ VIEWED_RECEIPT_COUNT + " INTEGER DEFAULT 0, " +
MISMATCHED_IDENTITIES + " TEXT DEFAULT NULL, " +
- NETWORK_FAILURE + " TEXT DEFAULT NULL," +
- SUBSCRIPTION_ID + " INTEGER DEFAULT -1, " +
+ NETWORK_FAILURES + " TEXT DEFAULT NULL," +
EXPIRES_IN + " INTEGER DEFAULT 0, " +
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_AUTHOR + " INTEGER DEFAULT 0, " +
+ QUOTE_BODY + " TEXT DEFAULT NULL, " +
QUOTE_MISSING + " INTEGER DEFAULT 0, " +
QUOTE_MENTIONS + " BLOB DEFAULT NULL," +
QUOTE_TYPE + " INTEGER DEFAULT 0," +
- SHARED_CONTACTS + " TEXT, " +
+ SHARED_CONTACTS + " TEXT DEFAULT NULL, " +
UNIDENTIFIED + " INTEGER DEFAULT 0, " +
- LINK_PREVIEWS + " TEXT, " +
+ LINK_PREVIEWS + " TEXT DEFAULT NULL, " +
VIEW_ONCE + " INTEGER DEFAULT 0, " +
REACTIONS_UNREAD + " INTEGER DEFAULT 0, " +
REACTIONS_LAST_SEEN + " INTEGER DEFAULT -1, " +
REMOTE_DELETED + " INTEGER DEFAULT 0, " +
MENTIONS_SELF + " INTEGER DEFAULT 0, " +
NOTIFIED_TIMESTAMP + " INTEGER DEFAULT 0, " +
- VIEWED_RECEIPT_COUNT + " INTEGER DEFAULT 0, " +
SERVER_GUID + " TEXT DEFAULT NULL, " +
- RECEIPT_TIMESTAMP + " INTEGER DEFAULT -1, " +
MESSAGE_RANGES + " BLOB DEFAULT NULL, " +
STORY_TYPE + " INTEGER DEFAULT 0, " +
PARENT_STORY_ID + " INTEGER DEFAULT 0, " +
@@ -203,33 +194,64 @@ public class MmsTable extends MessageTable {
public static final String[] CREATE_INDEXS = {
"CREATE INDEX IF NOT EXISTS mms_read_and_notified_and_thread_id_index ON " + TABLE_NAME + "(" + READ + "," + NOTIFIED + "," + THREAD_ID + ");",
- "CREATE INDEX IF NOT EXISTS mms_message_box_index ON " + TABLE_NAME + " (" + MESSAGE_BOX + ");",
+ "CREATE INDEX IF NOT EXISTS mms_type_index ON " + TABLE_NAME + " (" + TYPE + ");",
"CREATE INDEX IF NOT EXISTS mms_date_sent_index ON " + TABLE_NAME + " (" + DATE_SENT + ", " + RECIPIENT_ID + ", " + THREAD_ID + ");",
"CREATE INDEX IF NOT EXISTS mms_date_server_index ON " + TABLE_NAME + " (" + DATE_SERVER + ");",
"CREATE INDEX IF NOT EXISTS mms_thread_date_index ON " + TABLE_NAME + " (" + THREAD_ID + ", " + DATE_RECEIVED + ");",
"CREATE INDEX IF NOT EXISTS mms_reactions_unread_index ON " + TABLE_NAME + " (" + REACTIONS_UNREAD + ");",
- "CREATE INDEX IF NOT EXISTS mms_is_story_index ON " + TABLE_NAME + " (" + STORY_TYPE + ");",
+ "CREATE INDEX IF NOT EXISTS mms_story_type_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_exported_index ON " + TABLE_NAME + " (" + EXPORTED + ");",
- "CREATE INDEX IF NOT EXISTS mms_id_msg_box_payment_transactions_index ON " + TABLE_NAME + " (" + ID + "," + MESSAGE_BOX + ") WHERE " + MESSAGE_BOX + " & " + Types.SPECIAL_TYPE_PAYMENTS_NOTIFICATION + " != 0;"
+ "CREATE INDEX IF NOT EXISTS mms_id_type_payment_transactions_index ON " + TABLE_NAME + " (" + ID + "," + TYPE + ") WHERE " + TYPE + " & " + Types.SPECIAL_TYPE_PAYMENTS_NOTIFICATION + " != 0;"
};
private static final String[] MMS_PROJECTION = new String[] {
MmsTable.TABLE_NAME + "." + ID + " AS " + ID,
- THREAD_ID, DATE_SENT + " AS " + NORMALIZED_DATE_SENT,
- DATE_RECEIVED + " AS " + NORMALIZED_DATE_RECEIVED,
+ THREAD_ID,
+ DATE_SENT,
+ DATE_RECEIVED,
DATE_SERVER,
- MESSAGE_BOX, READ,
- CONTENT_LOCATION, EXPIRY, MESSAGE_TYPE,
- MESSAGE_SIZE, STATUS, TRANSACTION_ID,
- BODY, PART_COUNT, RECIPIENT_ID, 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_TYPE, QUOTE_MISSING, QUOTE_MENTIONS,
- SHARED_CONTACTS, LINK_PREVIEWS, UNIDENTIFIED, VIEW_ONCE, REACTIONS_UNREAD, REACTIONS_LAST_SEEN,
- REMOTE_DELETED, MENTIONS_SELF, NOTIFIED_TIMESTAMP, VIEWED_RECEIPT_COUNT, RECEIPT_TIMESTAMP, MESSAGE_RANGES,
- STORY_TYPE, PARENT_STORY_ID,
+ TYPE,
+ READ,
+ MMS_CONTENT_LOCATION,
+ MMS_EXPIRY,
+ MMS_MESSAGE_TYPE,
+ MMS_MESSAGE_SIZE,
+ MMS_STATUS,
+ MMS_TRANSACTION_ID,
+ BODY,
+ RECIPIENT_ID,
+ RECIPIENT_DEVICE_ID,
+ DELIVERY_RECEIPT_COUNT,
+ READ_RECEIPT_COUNT,
+ MISMATCHED_IDENTITIES,
+ NETWORK_FAILURES,
+ SMS_SUBSCRIPTION_ID,
+ EXPIRES_IN,
+ EXPIRE_STARTED,
+ NOTIFIED,
+ QUOTE_ID,
+ QUOTE_AUTHOR,
+ QUOTE_BODY,
+ QUOTE_TYPE,
+ QUOTE_MISSING,
+ QUOTE_MENTIONS,
+ SHARED_CONTACTS,
+ LINK_PREVIEWS,
+ UNIDENTIFIED,
+ VIEW_ONCE,
+ REACTIONS_UNREAD,
+ REACTIONS_LAST_SEEN,
+ REMOTE_DELETED,
+ MENTIONS_SELF,
+ NOTIFIED_TIMESTAMP,
+ VIEWED_RECEIPT_COUNT,
+ RECEIPT_TIMESTAMP,
+ MESSAGE_RANGES,
+ STORY_TYPE,
+ PARENT_STORY_ID,
"json_group_array(json_object(" +
"'" + AttachmentTable.ROW_ID + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.ROW_ID + ", " +
"'" + AttachmentTable.UNIQUE_ID + "', " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.UNIQUE_ID + ", " +
@@ -266,9 +288,6 @@ public class MmsTable extends MessageTable {
private static final String RAW_ID_WHERE = TABLE_NAME + "._id = ?";
- private static final String OUTGOING_INSECURE_MESSAGES_CLAUSE = "(" + MESSAGE_BOX + " & " + Types.BASE_TYPE_MASK + ") = " + Types.BASE_SENT_TYPE + " AND NOT (" + MESSAGE_BOX + " & " + Types.SECURE_MESSAGE_BIT + ")";
- private static final String OUTGOING_SECURE_MESSAGES_CLAUSE = "(" + MESSAGE_BOX + " & " + Types.BASE_TYPE_MASK + ") = " + Types.BASE_SENT_TYPE + " AND (" + MESSAGE_BOX + " & " + (Types.SECURE_MESSAGE_BIT | Types.PUSH_MESSAGE_BIT) + ")";
-
private final EarlyReceiptCache earlyDeliveryReceiptCache = new EarlyReceiptCache("MmsDelivery");
public MmsTable(Context context, SignalDatabase databaseHelper) {
@@ -292,7 +311,7 @@ public class MmsTable extends MessageTable {
@Override
protected String getTypeField() {
- return MESSAGE_BOX;
+ return TYPE;
}
@Override
@@ -384,8 +403,8 @@ public class MmsTable extends MessageTable {
@Override
public @NonNull List getViewedIncomingMessages(long threadId) {
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
- String[] columns = new String[]{ID, RECIPIENT_ID, DATE_SENT, MESSAGE_BOX, THREAD_ID, STORY_TYPE};
- String where = THREAD_ID + " = ? AND " + VIEWED_RECEIPT_COUNT + " > 0 AND " + MESSAGE_BOX + " & " + Types.BASE_INBOX_TYPE + " = " + Types.BASE_INBOX_TYPE;
+ String[] columns = new String[]{ ID, RECIPIENT_ID, DATE_SENT, TYPE, THREAD_ID, STORY_TYPE};
+ String where = THREAD_ID + " = ? AND " + VIEWED_RECEIPT_COUNT + " > 0 AND " + TYPE + " & " + Types.BASE_INBOX_TYPE + " = " + Types.BASE_INBOX_TYPE;
String[] args = SqlUtil.buildArgs(threadId);
@@ -427,21 +446,20 @@ public class MmsTable extends MessageTable {
}
SQLiteDatabase database = databaseHelper.getSignalWritableDatabase();
- String[] columns = new String[]{ID, RECIPIENT_ID, DATE_SENT, MESSAGE_BOX, THREAD_ID, STORY_TYPE};
+ String[] columns = new String[]{ ID, RECIPIENT_ID, DATE_SENT, TYPE, THREAD_ID, STORY_TYPE};
String where = ID + " IN (" + Util.join(messageIds, ",") + ") AND " + VIEWED_RECEIPT_COUNT + " = 0";
List results = new LinkedList<>();
database.beginTransaction();
try (Cursor cursor = database.query(TABLE_NAME, columns, where, null, null, null, null)) {
while (cursor != null && cursor.moveToNext()) {
- long type = CursorUtil.requireLong(cursor, MESSAGE_BOX);
+ long type = CursorUtil.requireLong(cursor, TYPE);
if (Types.isSecureType(type) && Types.isInboxType(type)) {
long messageId = CursorUtil.requireLong(cursor, ID);
long threadId = CursorUtil.requireLong(cursor, THREAD_ID);
RecipientId recipientId = RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID));
long dateSent = CursorUtil.requireLong(cursor, DATE_SENT);
SyncMessageId syncMessageId = new SyncMessageId(recipientId, dateSent);
- StoryType storyType = StoryType.fromCode(CursorUtil.requireInt(cursor, STORY_TYPE));
results.add(new MarkedMessageInfo(threadId, syncMessageId, new MessageId(messageId, true), null));
@@ -599,11 +617,6 @@ public class MmsTable extends MessageTable {
database.endTransaction();
}
- @Override
- public SQLiteStatement createInsertStatement(SQLiteDatabase database) {
- throw new UnsupportedOperationException();
- }
-
@Override
public void ensureMigration() {
databaseHelper.getSignalWritableDatabase();
@@ -827,7 +840,7 @@ public class MmsTable extends MessageTable {
@Override
public @NonNull List getUnreadStoryThreadRecipientIds() {
SQLiteDatabase db = getReadableDatabase();
- String query = "SELECT DISTINCT " + ThreadTable.RECIPIENT_ID + "\n"
+ String query = "SELECT DISTINCT " + ThreadTable.TABLE_NAME + "." + ThreadTable.RECIPIENT_ID + "\n"
+ "FROM " + TABLE_NAME + "\n"
+ "JOIN " + ThreadTable.TABLE_NAME + "\n"
+ "ON " + TABLE_NAME + "." + THREAD_ID + " = " + ThreadTable.TABLE_NAME + "." + ThreadTable.ID + "\n"
@@ -849,27 +862,27 @@ public class MmsTable extends MessageTable {
@Override
public @NonNull List getOrderedStoryRecipientsAndIds(boolean isOutgoingOnly) {
- String where = "WHERE is_story > 0 AND remote_deleted = 0" + (isOutgoingOnly ? " AND is_outgoing != 0" : "") + "\n";
+ String where = "WHERE " + STORY_TYPE + " > 0 AND " + REMOTE_DELETED + " = 0" + (isOutgoingOnly ? " AND is_outgoing != 0" : "") + "\n";
SQLiteDatabase db = getReadableDatabase();
String query = "SELECT\n"
- + " mms.date AS sent_timestamp,\n"
- + " mms._id AS mms_id,\n"
- + " thread_recipient_id,\n"
+ + " " + TABLE_NAME + "." + DATE_SENT + " AS sent_timestamp,\n"
+ + " " + TABLE_NAME + "." + ID + " AS mms_id,\n"
+ + " " + ThreadTable.TABLE_NAME + "." + ThreadTable.RECIPIENT_ID + ",\n"
+ " (" + getOutgoingTypeClause() + ") AS is_outgoing,\n"
- + " viewed_receipt_count,\n"
- + " mms.date,\n"
- + " receipt_timestamp,\n"
- + " (" + getOutgoingTypeClause() + ") = 0 AND viewed_receipt_count = 0 AS is_unread\n"
- + "FROM mms\n"
- + "JOIN thread\n"
- + "ON mms.thread_id = thread._id\n"
+ + " " + VIEWED_RECEIPT_COUNT + ",\n"
+ + " " + TABLE_NAME + "." + DATE_SENT + ",\n"
+ + " " + RECEIPT_TIMESTAMP + ",\n"
+ + " (" + getOutgoingTypeClause() + ") = 0 AND " + VIEWED_RECEIPT_COUNT + " = 0 AS is_unread\n"
+ + "FROM " + TABLE_NAME + "\n"
+ + "JOIN " + ThreadTable.TABLE_NAME + "\n"
+ + "ON " + TABLE_NAME + "." + THREAD_ID + " = " + ThreadTable.TABLE_NAME + "." + ThreadTable.ID + "\n"
+ where
+ "ORDER BY\n"
+ "is_unread DESC,\n"
+ "CASE\n"
- + "WHEN is_outgoing = 0 AND viewed_receipt_count = 0 THEN mms.date\n"
- + "WHEN is_outgoing = 0 AND viewed_receipt_count > 0 THEN receipt_timestamp\n"
- + "WHEN is_outgoing = 1 THEN mms.date\n"
+ + "WHEN is_outgoing = 0 AND " + VIEWED_RECEIPT_COUNT + " = 0 THEN " + MmsTable.TABLE_NAME + "." + MmsTable.DATE_SENT + "\n"
+ + "WHEN is_outgoing = 0 AND viewed_receipt_count > 0 THEN " + MmsTable.RECEIPT_TIMESTAMP + "\n"
+ + "WHEN is_outgoing = 1 THEN " + MmsTable.TABLE_NAME + "." + MmsTable.DATE_SENT + "\n"
+ "END DESC";
List results;
@@ -1047,7 +1060,7 @@ public class MmsTable extends MessageTable {
String[] columns = new String[]{ID};
long type = Types.getOutgoingEncryptedMessageType() | Types.GROUP_LEAVE_BIT;
- String query = ID + " = ? AND " + MESSAGE_BOX + " & " + type + " = " + type + " AND " + MESSAGE_BOX + " & " + Types.GROUP_V2_BIT + " = 0";
+ String query = ID + " = ? AND " + TYPE + " & " + type + " = " + type + " AND " + TYPE + " & " + Types.GROUP_V2_BIT + " = 0";
String[] args = SqlUtil.buildArgs(messageId);
try (Cursor cursor = db.query(TABLE_NAME, columns, query, args, null, null, null, null)) {
@@ -1065,7 +1078,7 @@ public class MmsTable extends MessageTable {
String[] columns = new String[]{DATE_SENT};
long type = Types.getOutgoingEncryptedMessageType() | Types.GROUP_LEAVE_BIT;
- String query = THREAD_ID + " = ? AND " + MESSAGE_BOX + " & " + type + " = " + type + " AND " + MESSAGE_BOX + " & " + Types.GROUP_V2_BIT + " = 0 AND " + DATE_SENT + " < ?";
+ String query = THREAD_ID + " = ? AND " + TYPE + " & " + type + " = " + type + " AND " + TYPE + " & " + Types.GROUP_V2_BIT + " = 0 AND " + DATE_SENT + " < ?";
String[] args = new String[]{String.valueOf(threadId), String.valueOf(quitTimeBarrier)};
String orderBy = DATE_SENT + " DESC";
String limit = "1";
@@ -1139,7 +1152,7 @@ public class MmsTable extends MessageTable {
@Override
public void addFailures(long messageId, List failure) {
try {
- addToDocument(messageId, NETWORK_FAILURE, failure, NetworkFailureSet.class);
+ addToDocument(messageId, NETWORK_FAILURES, failure, NetworkFailureSet.class);
} catch (IOException e) {
Log.w(TAG, e);
}
@@ -1148,7 +1161,7 @@ public class MmsTable extends MessageTable {
@Override
public void setNetworkFailures(long messageId, Set failures) {
try {
- setDocument(databaseHelper.getSignalWritableDatabase(), messageId, NETWORK_FAILURE, new NetworkFailureSet(failures));
+ setDocument(databaseHelper.getSignalWritableDatabase(), messageId, NETWORK_FAILURES, new NetworkFailureSet(failures));
} catch (IOException e) {
Log.w(TAG, e);
}
@@ -1174,13 +1187,13 @@ public class MmsTable extends MessageTable {
throw new IllegalArgumentException("Unsupported qualifier: " + messageQualifier);
}
- try (Cursor cursor = SQLiteDatabaseExtensionsKt.select(database, ID, THREAD_ID, MESSAGE_BOX, RECIPIENT_ID, receiptType.getColumnName(), RECEIPT_TIMESTAMP)
+ try (Cursor cursor = SQLiteDatabaseExtensionsKt.select(database, ID, THREAD_ID, TYPE, RECIPIENT_ID, receiptType.getColumnName(), RECEIPT_TIMESTAMP)
.from(TABLE_NAME)
.where(DATE_SENT + " = ?" + qualifierWhere, messageId.getTimetamp())
.run())
{
while (cursor.moveToNext()) {
- if (Types.isOutgoingMessageType(CursorUtil.requireLong(cursor, MESSAGE_BOX))) {
+ if (Types.isOutgoingMessageType(CursorUtil.requireLong(cursor, TYPE))) {
RecipientId theirRecipientId = RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID));
RecipientId ourRecipientId = messageId.getRecipientId();
String columnName = receiptType.getColumnName();
@@ -1340,7 +1353,7 @@ public class MmsTable extends MessageTable {
db.beginTransaction();
try {
db.execSQL("UPDATE " + TABLE_NAME +
- " SET " + MESSAGE_BOX + " = (" + MESSAGE_BOX + " & " + (Types.TOTAL_MASK - maskOff) + " | " + maskOn + " )" +
+ " SET " + TYPE + " = (" + TYPE + " & " + (Types.TOTAL_MASK - maskOff) + " | " + maskOn + " )" +
" WHERE " + ID + " = ?", new String[] { id + "" });
if (threadId.isPresent()) {
@@ -1435,7 +1448,6 @@ public class MmsTable extends MessageTable {
values.putNull(BODY);
values.putNull(QUOTE_BODY);
values.putNull(QUOTE_AUTHOR);
- values.putNull(QUOTE_ATTACHMENT);
values.putNull(QUOTE_TYPE);
values.putNull(QUOTE_ID);
values.putNull(LINK_PREVIEWS);
@@ -1469,7 +1481,7 @@ public class MmsTable extends MessageTable {
public void markDownloadState(long messageId, long state) {
SQLiteDatabase database = databaseHelper.getSignalWritableDatabase();
ContentValues contentValues = new ContentValues();
- contentValues.put(STATUS, state);
+ contentValues.put(MMS_STATUS, state);
database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {messageId + ""});
ApplicationDependencies.getDatabaseObserver().notifyMessageUpdateObservers(new MessageId(messageId, true));
@@ -1608,10 +1620,10 @@ public class MmsTable extends MessageTable {
database.beginTransaction();
try {
- cursor = database.query(TABLE_NAME, new String[] {ID, RECIPIENT_ID, DATE_SENT, MESSAGE_BOX, EXPIRES_IN, EXPIRE_STARTED, THREAD_ID, STORY_TYPE }, where, arguments, null, null, null);
+ cursor = database.query(TABLE_NAME, new String[] { ID, RECIPIENT_ID, DATE_SENT, TYPE, EXPIRES_IN, EXPIRE_STARTED, THREAD_ID, STORY_TYPE }, where, arguments, null, null, null);
while(cursor != null && cursor.moveToNext()) {
- if (Types.isSecureType(CursorUtil.requireLong(cursor, MESSAGE_BOX))) {
+ if (Types.isSecureType(CursorUtil.requireLong(cursor, TYPE))) {
long threadId = CursorUtil.requireLong(cursor, THREAD_ID);
RecipientId recipientId = RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID));
long dateSent = CursorUtil.requireLong(cursor, DATE_SENT);
@@ -1712,9 +1724,9 @@ public class MmsTable extends MessageTable {
if (cursor != null && cursor.moveToNext()) {
return Optional.of(new MmsNotificationInfo(RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(RECIPIENT_ID))),
- cursor.getString(cursor.getColumnIndexOrThrow(CONTENT_LOCATION)),
- cursor.getString(cursor.getColumnIndexOrThrow(TRANSACTION_ID)),
- cursor.getInt(cursor.getColumnIndexOrThrow(SUBSCRIPTION_ID))));
+ cursor.getString(cursor.getColumnIndexOrThrow(MMS_CONTENT_LOCATION)),
+ cursor.getString(cursor.getColumnIndexOrThrow(MMS_TRANSACTION_ID)),
+ cursor.getInt(cursor.getColumnIndexOrThrow(SMS_SUBSCRIPTION_ID))));
} else {
return Optional.empty();
}
@@ -1739,17 +1751,17 @@ public class MmsTable extends MessageTable {
List associatedAttachments = attachmentDatabase.getAttachmentsForMessage(messageId);
List mentions = mentionDatabase.getMentionsForMessage(messageId);
- long outboxType = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_BOX));
+ long outboxType = cursor.getLong(cursor.getColumnIndexOrThrow(TYPE));
String body = cursor.getString(cursor.getColumnIndexOrThrow(BODY));
- long timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(NORMALIZED_DATE_SENT));
- int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(SUBSCRIPTION_ID));
+ long timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(DATE_SENT));
+ int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(SMS_SUBSCRIPTION_ID));
long expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(EXPIRES_IN));
boolean viewOnce = cursor.getLong(cursor.getColumnIndexOrThrow(VIEW_ONCE)) == 1;
long recipientId = cursor.getLong(cursor.getColumnIndexOrThrow(RECIPIENT_ID));
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID));
int distributionType = SignalDatabase.threads().getDistributionType(threadId);
String mismatchDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsTable.MISMATCHED_IDENTITIES));
- String networkDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsTable.NETWORK_FAILURE));
+ String networkDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsTable.NETWORK_FAILURES));
StoryType storyType = StoryType.fromCode(CursorUtil.requireInt(cursor, STORY_TYPE));
ParentStoryId parentStoryId = ParentStoryId.deserialize(CursorUtil.requireLong(cursor, PARENT_STORY_ID));
@@ -1942,14 +1954,13 @@ public class MmsTable extends MessageTable {
contentValues.put(DATE_SERVER, retrieved.getServerTimeMillis());
contentValues.put(RECIPIENT_ID, retrieved.getFrom().serialize());
- contentValues.put(MESSAGE_BOX, mailbox);
- contentValues.put(MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF);
+ contentValues.put(TYPE, mailbox);
+ contentValues.put(MMS_MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF);
contentValues.put(THREAD_ID, threadId);
- contentValues.put(CONTENT_LOCATION, contentLocation);
- contentValues.put(STATUS, Status.DOWNLOAD_INITIALIZED);
+ contentValues.put(MMS_CONTENT_LOCATION, contentLocation);
+ contentValues.put(MMS_STATUS, Status.DOWNLOAD_INITIALIZED);
contentValues.put(DATE_RECEIVED, retrieved.isPushMessage() ? retrieved.getReceivedTimeMillis() : generatePduCompatTimestamp(retrieved.getReceivedTimeMillis()));
- contentValues.put(PART_COUNT, retrieved.getAttachments().size());
- contentValues.put(SUBSCRIPTION_ID, retrieved.getSubscriptionId());
+ contentValues.put(SMS_SUBSCRIPTION_ID, retrieved.getSubscriptionId());
contentValues.put(EXPIRES_IN, retrieved.getExpiresIn());
contentValues.put(VIEW_ONCE, retrieved.isViewOnce() ? 1 : 0);
contentValues.put(STORY_TYPE, retrieved.getStoryType().getCode());
@@ -2101,12 +2112,12 @@ public class MmsTable extends MessageTable {
Log.i(TAG, "Message received type: " + notification.getMessageType());
- contentBuilder.add(CONTENT_LOCATION, notification.getContentLocation());
+ contentBuilder.add(MMS_CONTENT_LOCATION, notification.getContentLocation());
contentBuilder.add(DATE_SENT, System.currentTimeMillis());
- contentBuilder.add(EXPIRY, notification.getExpiry());
- contentBuilder.add(MESSAGE_SIZE, notification.getMessageSize());
- contentBuilder.add(TRANSACTION_ID, notification.getTransactionId());
- contentBuilder.add(MESSAGE_TYPE, notification.getMessageType());
+ contentBuilder.add(MMS_EXPIRY, notification.getExpiry());
+ contentBuilder.add(MMS_MESSAGE_SIZE, notification.getMessageSize());
+ contentBuilder.add(MMS_TRANSACTION_ID, notification.getTransactionId());
+ contentBuilder.add(MMS_MESSAGE_TYPE, notification.getMessageType());
if (notification.getFrom() != null) {
Recipient recipient = Recipient.external(context, Util.toIsoString(notification.getFrom().getTextString()));
@@ -2115,12 +2126,12 @@ public class MmsTable extends MessageTable {
contentValues.put(RECIPIENT_ID, RecipientId.UNKNOWN.serialize());
}
- contentValues.put(MESSAGE_BOX, Types.BASE_INBOX_TYPE);
+ contentValues.put(TYPE, Types.BASE_INBOX_TYPE);
contentValues.put(THREAD_ID, threadId);
- contentValues.put(STATUS, Status.DOWNLOAD_INITIALIZED);
+ contentValues.put(MMS_STATUS, Status.DOWNLOAD_INITIALIZED);
contentValues.put(DATE_RECEIVED, generatePduCompatTimestamp(System.currentTimeMillis()));
contentValues.put(READ, Util.isDefaultSmsProvider(context) ? 0 : 1);
- contentValues.put(SUBSCRIPTION_ID, subscriptionId);
+ contentValues.put(SMS_SUBSCRIPTION_ID, subscriptionId);
if (!contentValues.containsKey(DATE_SENT))
contentValues.put(DATE_SENT, contentValues.getAsLong(DATE_RECEIVED));
@@ -2170,7 +2181,7 @@ public class MmsTable extends MessageTable {
private void markGiftRedemptionState(long messageId, @NonNull GiftBadge.RedemptionState redemptionState) {
String[] projection = SqlUtil.buildArgs(BODY, THREAD_ID);
- String where = "(" + MESSAGE_BOX + " & " + Types.SPECIAL_TYPES_MASK + " = " + Types.SPECIAL_TYPE_GIFT_BADGE + ") AND " +
+ String where = "(" + TYPE + " & " + Types.SPECIAL_TYPES_MASK + " = " + Types.SPECIAL_TYPE_GIFT_BADGE + ") AND " +
ID + " = ?";
String[] args = SqlUtil.buildArgs(messageId);
boolean updated = false;
@@ -2282,13 +2293,13 @@ public class MmsTable extends MessageTable {
ContentValues contentValues = new ContentValues();
contentValues.put(DATE_SENT, message.getSentTimeMillis());
- contentValues.put(MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_SEND_REQ);
+ contentValues.put(MMS_MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_SEND_REQ);
- contentValues.put(MESSAGE_BOX, type);
+ contentValues.put(TYPE, type);
contentValues.put(THREAD_ID, threadId);
contentValues.put(READ, 1);
contentValues.put(DATE_RECEIVED, System.currentTimeMillis());
- contentValues.put(SUBSCRIPTION_ID, message.getSubscriptionId());
+ contentValues.put(SMS_SUBSCRIPTION_ID, message.getSubscriptionId());
contentValues.put(EXPIRES_IN, message.getExpiresIn());
contentValues.put(VIEW_ONCE, message.isViewOnce());
contentValues.put(RECIPIENT_ID, message.getRecipient().getId().serialize());
@@ -2415,7 +2426,6 @@ public class MmsTable extends MessageTable {
allAttachments.addAll(previewAttachments);
contentValues.put(BODY, body);
- contentValues.put(PART_COUNT, allAttachments.size());
contentValues.put(MENTIONS_SELF, mentionsSelf ? 1 : 0);
if (messageRanges != null) {
@@ -2568,9 +2578,9 @@ public class MmsTable extends MessageTable {
@Override
public boolean isSent(long messageId) {
SQLiteDatabase database = databaseHelper.getSignalReadableDatabase();
- try (Cursor cursor = database.query(TABLE_NAME, new String[] { MESSAGE_BOX }, ID + " = ?", new String[] { String.valueOf(messageId)}, null, null, null)) {
+ try (Cursor cursor = database.query(TABLE_NAME, new String[] { TYPE }, ID + " = ?", new String[] { String.valueOf(messageId)}, null, null, null)) {
if (cursor != null && cursor.moveToNext()) {
- long type = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_BOX));
+ long type = cursor.getLong(cursor.getColumnIndexOrThrow(TYPE));
return Types.isSentType(type);
}
}
@@ -2585,7 +2595,7 @@ public class MmsTable extends MessageTable {
@Override
public Set getAllRateLimitedMessageIds() {
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
- String where = "(" + MESSAGE_BOX + " & " + Types.TOTAL_MASK + " & " + Types.MESSAGE_RATE_LIMITED_BIT + ") > 0";
+ String where = "(" + TYPE + " & " + Types.TOTAL_MASK + " & " + Types.MESSAGE_RATE_LIMITED_BIT + ") > 0";
Set ids = new HashSet<>();
@@ -2851,7 +2861,6 @@ public class MmsTable extends MessageTable {
0,
threadId, message.getBody(),
slideDeck,
- slideDeck.getSlides().size(),
message.isSecure() ? MmsSmsColumns.Types.getOutgoingEncryptedMessageType() : MmsSmsColumns.Types.getOutgoingSmsMessageType(),
Collections.emptySet(),
Collections.emptySet(),
@@ -2915,7 +2924,7 @@ public class MmsTable extends MessageTable {
@Override
public MessageRecord getCurrent() {
- long mmsType = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.MESSAGE_TYPE));
+ long mmsType = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.MMS_MESSAGE_TYPE));
if (mmsType == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) {
return getNotificationMmsMessageRecord(cursor);
@@ -2945,22 +2954,22 @@ public class MmsTable extends MessageTable {
private NotificationMmsMessageRecord getNotificationMmsMessageRecord(Cursor cursor) {
long id = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.ID));
- long dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.NORMALIZED_DATE_SENT));
- long dateReceived = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.NORMALIZED_DATE_RECEIVED));
+ long dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.DATE_SENT));
+ long dateReceived = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.DATE_RECEIVED));
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.THREAD_ID));
- long mailbox = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.MESSAGE_BOX));
+ long mailbox = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.TYPE));
long recipientId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.RECIPIENT_ID));
- int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.ADDRESS_DEVICE_ID));
+ int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.RECIPIENT_DEVICE_ID));
Recipient recipient = Recipient.live(RecipientId.from(recipientId)).get();
- String contentLocation = cursor.getString(cursor.getColumnIndexOrThrow(MmsTable.CONTENT_LOCATION));
- String transactionId = cursor.getString(cursor.getColumnIndexOrThrow(MmsTable.TRANSACTION_ID));
- long messageSize = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.MESSAGE_SIZE));
- long expiry = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.EXPIRY));
- int status = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.STATUS));
+ String contentLocation = cursor.getString(cursor.getColumnIndexOrThrow(MmsTable.MMS_CONTENT_LOCATION));
+ String transactionId = cursor.getString(cursor.getColumnIndexOrThrow(MmsTable.MMS_TRANSACTION_ID));
+ long messageSize = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.MMS_MESSAGE_SIZE));
+ long expiry = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.MMS_EXPIRY));
+ int status = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.MMS_STATUS));
int deliveryReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.DELIVERY_RECEIPT_COUNT));
int readReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.READ_RECEIPT_COUNT));
- int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.SUBSCRIPTION_ID));
+ int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.SMS_SUBSCRIPTION_ID));
int viewedReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsSmsColumns.VIEWED_RECEIPT_COUNT));
long receiptTimestamp = CursorUtil.requireLong(cursor, MmsSmsColumns.RECEIPT_TIMESTAMP);
StoryType storyType = StoryType.fromCode(CursorUtil.requireInt(cursor, STORY_TYPE));
@@ -3001,20 +3010,19 @@ public class MmsTable extends MessageTable {
private MediaMmsMessageRecord getMediaMmsMessageRecord(Cursor cursor) {
long id = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.ID));
- long dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.NORMALIZED_DATE_SENT));
- long dateReceived = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.NORMALIZED_DATE_RECEIVED));
+ long dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.DATE_SENT));
+ long dateReceived = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.DATE_RECEIVED));
long dateServer = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.DATE_SERVER));
- long box = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.MESSAGE_BOX));
+ long box = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.TYPE));
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.THREAD_ID));
long recipientId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.RECIPIENT_ID));
- int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.ADDRESS_DEVICE_ID));
+ int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.RECIPIENT_DEVICE_ID));
int deliveryReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.DELIVERY_RECEIPT_COUNT));
int readReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.READ_RECEIPT_COUNT));
String body = cursor.getString(cursor.getColumnIndexOrThrow(MmsTable.BODY));
- int partCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.PART_COUNT));
String mismatchDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsTable.MISMATCHED_IDENTITIES));
- String networkDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsTable.NETWORK_FAILURE));
- int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.SUBSCRIPTION_ID));
+ String networkDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsTable.NETWORK_FAILURES));
+ int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.SMS_SUBSCRIPTION_ID));
long expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.EXPIRES_IN));
long expireStarted = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.EXPIRE_STARTED));
boolean unidentified = cursor.getInt(cursor.getColumnIndexOrThrow(MmsTable.UNIDENTIFIED)) == 1;
@@ -3067,7 +3075,7 @@ public class MmsTable extends MessageTable {
return new MediaMmsMessageRecord(id, recipient, recipient,
addressDeviceId, dateSent, dateReceived, dateServer, deliveryReceiptCount,
- threadId, body, slideDeck, partCount, box, mismatches,
+ threadId, body, slideDeck, box, mismatches,
networkFailures, subscriptionId, expiresIn, expireStarted,
isViewOnce, readReceiptCount, quote, contacts, previews, unidentified, Collections.emptyList(),
remoteDelete, mentionsSelf, notifiedTimestamp, viewedReceiptCount, receiptTimestamp, messageRanges,
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SearchTable.java b/app/src/main/java/org/thoughtcrime/securesms/database/SearchTable.java
index 38ddf18123..b7a935f1e1 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/SearchTable.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/SearchTable.java
@@ -61,9 +61,9 @@ public class SearchTable extends DatabaseTable {
private static final String MESSAGES_QUERY =
"SELECT " +
ThreadTable.TABLE_NAME + "." + ThreadTable.RECIPIENT_ID + " AS " + CONVERSATION_RECIPIENT + ", " +
- MmsSmsColumns.RECIPIENT_ID + " AS " + MESSAGE_RECIPIENT + ", " +
+ SmsTable.TABLE_NAME + "." + MmsSmsColumns.RECIPIENT_ID + " AS " + MESSAGE_RECIPIENT + ", " +
"snippet(" + SMS_FTS_TABLE_NAME + ", -1, '', '', '" + SNIPPET_WRAP + "', 7) AS " + SNIPPET + ", " +
- SmsTable.TABLE_NAME + "." + SmsTable.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + ", " +
+ SmsTable.TABLE_NAME + "." + MmsSmsColumns.DATE_RECEIVED + ", " +
SMS_FTS_TABLE_NAME + "." + THREAD_ID + ", " +
SMS_FTS_TABLE_NAME + "." + BODY + ", " +
SMS_FTS_TABLE_NAME + "." + ID + " AS " + MESSAGE_ID + ", " +
@@ -78,9 +78,9 @@ public class SearchTable extends DatabaseTable {
"UNION ALL " +
"SELECT " +
ThreadTable.TABLE_NAME + "." + ThreadTable.RECIPIENT_ID + " AS " + CONVERSATION_RECIPIENT + ", " +
- MmsSmsColumns.RECIPIENT_ID + " AS " + MESSAGE_RECIPIENT + ", " +
+ MmsTable.TABLE_NAME + "." + MmsSmsColumns.RECIPIENT_ID + " AS " + MESSAGE_RECIPIENT + ", " +
"snippet(" + MMS_FTS_TABLE_NAME + ", -1, '', '', '" + SNIPPET_WRAP + "', 7) AS " + SNIPPET + ", " +
- MmsTable.TABLE_NAME + "." + MmsTable.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + ", " +
+ MmsTable.TABLE_NAME + "." + MmsSmsColumns.DATE_RECEIVED + ", " +
MMS_FTS_TABLE_NAME + "." + THREAD_ID + ", " +
MMS_FTS_TABLE_NAME + "." + BODY + ", " +
MMS_FTS_TABLE_NAME + "." + ID + " AS " + MESSAGE_ID + ", " +
@@ -89,17 +89,17 @@ public class SearchTable extends DatabaseTable {
"INNER JOIN " + MMS_FTS_TABLE_NAME + " ON " + MMS_FTS_TABLE_NAME + "." + ID + " = " + MmsTable.TABLE_NAME + "." + MmsTable.ID + " " +
"INNER JOIN " + ThreadTable.TABLE_NAME + " ON " + MMS_FTS_TABLE_NAME + "." + THREAD_ID + " = " + ThreadTable.TABLE_NAME + "." + ThreadTable.ID + " " +
"WHERE " + MMS_FTS_TABLE_NAME + " MATCH ? " +
- "AND " + MmsTable.TABLE_NAME + "." + MmsTable.MESSAGE_BOX + " & " + MmsSmsColumns.Types.GROUP_V2_BIT + " = 0 " +
- "AND " + MmsTable.TABLE_NAME + "." + MmsTable.MESSAGE_BOX + " & " + MmsSmsColumns.Types.SPECIAL_TYPE_PAYMENTS_NOTIFICATION + " = 0 " +
- "ORDER BY " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC " +
+ "AND " + MmsTable.TABLE_NAME + "." + MmsTable.TYPE + " & " + MmsSmsColumns.Types.GROUP_V2_BIT + " = 0 " +
+ "AND " + MmsTable.TABLE_NAME + "." + MmsTable.TYPE + " & " + MmsSmsColumns.Types.SPECIAL_TYPE_PAYMENTS_NOTIFICATION + " = 0 " +
+ "ORDER BY " + MmsSmsColumns.DATE_RECEIVED + " DESC " +
"LIMIT 500";
private static final String MESSAGES_FOR_THREAD_QUERY =
"SELECT " +
ThreadTable.TABLE_NAME + "." + ThreadTable.RECIPIENT_ID + " AS " + CONVERSATION_RECIPIENT + ", " +
- MmsSmsColumns.RECIPIENT_ID + " AS " + MESSAGE_RECIPIENT + ", " +
+ SmsTable.TABLE_NAME + "." + MmsSmsColumns.RECIPIENT_ID + " AS " + MESSAGE_RECIPIENT + ", " +
"snippet(" + SMS_FTS_TABLE_NAME + ", -1, '', '', '" + SNIPPET_WRAP + "', 7) AS " + SNIPPET + ", " +
- SmsTable.TABLE_NAME + "." + SmsTable.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + ", " +
+ SmsTable.TABLE_NAME + "." + MmsSmsColumns.DATE_RECEIVED + ", " +
SMS_FTS_TABLE_NAME + "." + THREAD_ID + ", " +
SMS_FTS_TABLE_NAME + "." + BODY + ", " +
SMS_FTS_TABLE_NAME + "." + ID + " AS " + MESSAGE_ID + ", " +
@@ -111,9 +111,9 @@ public class SearchTable extends DatabaseTable {
"UNION ALL " +
"SELECT " +
ThreadTable.TABLE_NAME + "." + ThreadTable.RECIPIENT_ID + " AS " + CONVERSATION_RECIPIENT + ", " +
- MmsSmsColumns.RECIPIENT_ID + " AS " + MESSAGE_RECIPIENT + ", " +
+ MmsTable.TABLE_NAME + "." + MmsSmsColumns.RECIPIENT_ID + " AS " + MESSAGE_RECIPIENT + ", " +
"snippet(" + MMS_FTS_TABLE_NAME + ", -1, '', '', '" + SNIPPET_WRAP + "', 7) AS " + SNIPPET + ", " +
- MmsTable.TABLE_NAME + "." + MmsTable.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + ", " +
+ MmsTable.TABLE_NAME + "." + MmsSmsColumns.DATE_RECEIVED + ", " +
MMS_FTS_TABLE_NAME + "." + THREAD_ID + ", " +
MMS_FTS_TABLE_NAME + "." + BODY + ", " +
MMS_FTS_TABLE_NAME + "." + ID + " AS " + MESSAGE_ID + ", " +
@@ -122,7 +122,7 @@ public class SearchTable extends DatabaseTable {
"INNER JOIN " + MMS_FTS_TABLE_NAME + " ON " + MMS_FTS_TABLE_NAME + "." + ID + " = " + MmsTable.TABLE_NAME + "." + MmsTable.ID + " " +
"INNER JOIN " + ThreadTable.TABLE_NAME + " ON " + MMS_FTS_TABLE_NAME + "." + THREAD_ID + " = " + ThreadTable.TABLE_NAME + "." + ThreadTable.ID + " " +
"WHERE " + MMS_FTS_TABLE_NAME + " MATCH ? AND " + MmsTable.TABLE_NAME + "." + MmsSmsColumns.THREAD_ID + " = ? " +
- "ORDER BY " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC " +
+ "ORDER BY " + MmsSmsColumns.DATE_RECEIVED + " DESC " +
"LIMIT 500";
public SearchTable(@NonNull Context context, @NonNull SignalDatabase databaseHelper) {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt
index d492d57bb7..a62f0a4383 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt
@@ -156,15 +156,25 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data
}
override fun onUpgrade(db: net.zetetic.database.sqlcipher.SQLiteDatabase, oldVersion: Int, newVersion: Int) {
+ // The caller of onUpgrade starts a transaction, which prevents us from turning off foreign keys.
+ // At this point it hasn't done anything, so we can just end it and then start it again ourselves.
+ db.endTransaction()
+
Log.i(TAG, "Upgrading database: $oldVersion, $newVersion")
val startTime = System.currentTimeMillis()
+ db.setForeignKeyConstraintsEnabled(false)
db.beginTransaction()
try {
migrate(context, db, oldVersion, newVersion)
db.setTransactionSuccessful()
} finally {
db.endTransaction()
+ db.setForeignKeyConstraintsEnabled(true)
+
+ // We have to re-begin the transaction for the calling code (see comment at start of method)
+ db.beginTransaction()
}
+
migratePostTransaction(context, oldVersion)
Log.i(TAG, "Upgrade complete. Took " + (System.currentTimeMillis() - startTime) + " ms.")
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsMigrator.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsMigrator.java
deleted file mode 100644
index 4f77ed2190..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsMigrator.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2011 Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.thoughtcrime.securesms.database;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteException;
-import android.net.Uri;
-
-import androidx.annotation.Nullable;
-
-import com.annimon.stream.Stream;
-
-import net.zetetic.database.sqlcipher.SQLiteStatement;
-
-import org.signal.core.util.logging.Log;
-import org.thoughtcrime.securesms.groups.GroupId;
-import org.thoughtcrime.securesms.recipients.Recipient;
-import org.thoughtcrime.securesms.recipients.RecipientId;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-public class SmsMigrator {
-
- private static final String TAG = Log.tag(SmsMigrator.class);
-
- private static class SystemColumns {
- private static final String ADDRESS = "address";
- private static final String PERSON = "person";
- private static final String DATE_RECEIVED = "date";
- private static final String PROTOCOL = "protocol";
- private static final String READ = "read";
- private static final String STATUS = "status";
- private static final String TYPE = "type";
- private static final String SUBJECT = "subject";
- private static final String REPLY_PATH_PRESENT = "reply_path_present";
- private static final String BODY = "body";
- private static final String SERVICE_CENTER = "service_center";
- }
-
- private static void addStringToStatement(SQLiteStatement statement, Cursor cursor,
- int index, String key)
- {
- int columnIndex = cursor.getColumnIndexOrThrow(key);
-
- if (cursor.isNull(columnIndex)) {
- statement.bindNull(index);
- } else {
- statement.bindString(index, cursor.getString(columnIndex));
- }
- }
-
- private static void addIntToStatement(SQLiteStatement statement, Cursor cursor,
- int index, String key)
- {
- int columnIndex = cursor.getColumnIndexOrThrow(key);
-
- if (cursor.isNull(columnIndex)) {
- statement.bindNull(index);
- } else {
- statement.bindLong(index, cursor.getLong(columnIndex));
- }
- }
-
- @SuppressWarnings("SameParameterValue")
- private static void addTranslatedTypeToStatement(SQLiteStatement statement, Cursor cursor, int index, String key)
- {
- int columnIndex = cursor.getColumnIndexOrThrow(key);
-
- if (cursor.isNull(columnIndex)) {
- statement.bindLong(index, SmsTable.Types.BASE_INBOX_TYPE);
- } else {
- long theirType = cursor.getLong(columnIndex);
- statement.bindLong(index, SmsTable.Types.translateFromSystemBaseType(theirType));
- }
- }
-
- private static boolean isAppropriateTypeForMigration(Cursor cursor, int columnIndex) {
- long systemType = cursor.getLong(columnIndex);
- long ourType = SmsTable.Types.translateFromSystemBaseType(systemType);
-
- return ourType == MmsSmsColumns.Types.BASE_INBOX_TYPE ||
- ourType == MmsSmsColumns.Types.BASE_SENT_TYPE ||
- ourType == MmsSmsColumns.Types.BASE_SENT_FAILED_TYPE;
- }
-
- private static void getContentValuesForRow(Context context, Cursor cursor, long threadId, SQLiteStatement statement) {
- String address = cursor.getString(cursor.getColumnIndexOrThrow(SystemColumns.ADDRESS));
- RecipientId id = Recipient.external(context, address).getId();
-
- statement.bindString(1, id.serialize());
- addIntToStatement(statement, cursor, 2, SystemColumns.PERSON);
- addIntToStatement(statement, cursor, 3, SystemColumns.DATE_RECEIVED);
- addIntToStatement(statement, cursor, 4, SystemColumns.DATE_RECEIVED);
- addIntToStatement(statement, cursor, 5, SystemColumns.PROTOCOL);
- addIntToStatement(statement, cursor, 6, SystemColumns.READ);
- addIntToStatement(statement, cursor, 7, SystemColumns.STATUS);
- addTranslatedTypeToStatement(statement, cursor, 8, SystemColumns.TYPE);
- addIntToStatement(statement, cursor, 9, SystemColumns.REPLY_PATH_PRESENT);
- addStringToStatement(statement, cursor, 10, SystemColumns.SUBJECT);
- addStringToStatement(statement, cursor, 11, SystemColumns.BODY);
- addStringToStatement(statement, cursor, 12, SystemColumns.SERVICE_CENTER);
-
- statement.bindLong(13, threadId);
- }
-
- private static String getTheirCanonicalAddress(Context context, String theirRecipientId) {
- Uri uri = Uri.parse("content://mms-sms/canonical-address/" + theirRecipientId);
- Cursor cursor = null;
-
- try {
- cursor = context.getContentResolver().query(uri, null, null, null, null);
-
- if (cursor != null && cursor.moveToFirst()) {
- return cursor.getString(0);
- } else {
- return null;
- }
- } catch (IllegalStateException iae) {
- Log.w(TAG, iae);
- return null;
- } finally {
- if (cursor != null)
- cursor.close();
- }
- }
-
- private static @Nullable Set getOurRecipients(Context context, String theirRecipients) {
- StringTokenizer tokenizer = new StringTokenizer(theirRecipients.trim(), " ");
- Set recipientList = new HashSet<>();
-
- while (tokenizer.hasMoreTokens()) {
- String theirRecipientId = tokenizer.nextToken();
- String address = getTheirCanonicalAddress(context, theirRecipientId);
-
- if (address != null) {
- recipientList.add(Recipient.external(context, address));
- }
- }
-
- if (recipientList.isEmpty()) return null;
- else return recipientList;
- }
-
- private static void migrateConversation(Context context, SmsMigrationProgressListener listener,
- ProgressDescription progress,
- long theirThreadId, long ourThreadId)
- {
- MessageTable ourSmsDatabase = SignalDatabase.sms();
- Cursor cursor = null;
- SQLiteStatement statement = null;
-
- try {
- Uri uri = Uri.parse("content://sms/conversations/" + theirThreadId);
-
- try {
- cursor = context.getContentResolver().query(uri, null, null, null, null);
- } catch (SQLiteException e) {
- /// Work around for weird sony-specific (?) bug: #4309
- Log.w(TAG, e);
- return;
- }
-
- SQLiteDatabase transaction = ourSmsDatabase.beginTransaction();
- statement = ourSmsDatabase.createInsertStatement(transaction);
-
- while (cursor != null && cursor.moveToNext()) {
- int addressColumn = cursor.getColumnIndexOrThrow(SystemColumns.ADDRESS);
- int typeColumn = cursor.getColumnIndex(SmsTable.TYPE);
-
- if (!cursor.isNull(addressColumn) && (cursor.isNull(typeColumn) || isAppropriateTypeForMigration(cursor, typeColumn))) {
- getContentValuesForRow(context, cursor, ourThreadId, statement);
- statement.execute();
- }
-
- listener.progressUpdate(new ProgressDescription(progress, cursor.getCount(), cursor.getPosition()));
- }
-
- ourSmsDatabase.endTransaction(transaction);
- SignalDatabase.threads().update(ourThreadId, true);
- SignalDatabase.threads().setLastScrolled(ourThreadId, 0);
- SignalDatabase.threads().notifyConversationListeners(ourThreadId);
-
- } finally {
- if (statement != null)
- statement.close();
- if (cursor != null)
- cursor.close();
- }
- }
-
- public static void migrateDatabase(Context context, SmsMigrationProgressListener listener)
- {
-// if (context.getSharedPreferences("SecureSMS", Context.MODE_PRIVATE).getBoolean("migrated", false))
-// return;
-
- ThreadTable threadTable = SignalDatabase.threads();
- Cursor cursor = null;
-
- try {
- Uri threadListUri = Uri.parse("content://mms-sms/conversations?simple=true");
- cursor = context.getContentResolver().query(threadListUri, null, null, null, "date ASC");
-
- while (cursor != null && cursor.moveToNext()) {
- long theirThreadId = cursor.getLong(cursor.getColumnIndexOrThrow("_id"));
- String theirRecipients = cursor.getString(cursor.getColumnIndexOrThrow("recipient_ids"));
- Set ourRecipients = getOurRecipients(context, theirRecipients);
- ProgressDescription progress = new ProgressDescription(cursor.getCount(), cursor.getPosition(), 100, 0);
-
- if (ourRecipients != null) {
- if (ourRecipients.size() == 1) {
- long ourThreadId = threadTable.getOrCreateThreadIdFor(ourRecipients.iterator().next());
- migrateConversation(context, listener, progress, theirThreadId, ourThreadId);
- } else if (ourRecipients.size() > 1) {
- ourRecipients.add(Recipient.self());
-
- List recipientIds = Stream.of(ourRecipients).map(Recipient::getId).toList();
-
- GroupId.Mms ourGroupId = SignalDatabase.groups().getOrCreateMmsGroupForMembers(recipientIds);
- RecipientId ourGroupRecipientId = SignalDatabase.recipients().getOrInsertFromGroupId(ourGroupId);
- Recipient ourGroupRecipient = Recipient.resolved(ourGroupRecipientId);
- long ourThreadId = threadTable.getOrCreateThreadIdFor(ourGroupRecipient, ThreadTable.DistributionTypes.CONVERSATION);
-
- migrateConversation(context, listener, progress, theirThreadId, ourThreadId);
- }
- }
-
- progress.incrementPrimaryComplete();
- listener.progressUpdate(progress);
- }
- } finally {
- if (cursor != null)
- cursor.close();
- }
-
- context.getSharedPreferences("SecureSMS", Context.MODE_PRIVATE).edit()
- .putBoolean("migrated", true).apply();
- }
-
- public interface SmsMigrationProgressListener {
- void progressUpdate(ProgressDescription description);
- }
-
- public static class ProgressDescription {
- public final int primaryTotal;
- public int primaryComplete;
- public final int secondaryTotal;
- public final int secondaryComplete;
-
- ProgressDescription(int primaryTotal, int primaryComplete,
- int secondaryTotal, int secondaryComplete)
- {
- this.primaryTotal = primaryTotal;
- this.primaryComplete = primaryComplete;
- this.secondaryTotal = secondaryTotal;
- this.secondaryComplete = secondaryComplete;
- }
-
- ProgressDescription(ProgressDescription that, int secondaryTotal, int secondaryComplete) {
- this.primaryComplete = that.primaryComplete;
- this.primaryTotal = that.primaryTotal;
- this.secondaryComplete = secondaryComplete;
- this.secondaryTotal = secondaryTotal;
- }
-
- void incrementPrimaryComplete() {
- primaryComplete += 1;
- }
- }
-
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsTable.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsTable.java
index 3b01621970..42dc2fd039 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsTable.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsTable.java
@@ -31,8 +31,6 @@ import com.google.android.mms.pdu_alt.NotificationInd;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
-import net.zetetic.database.sqlcipher.SQLiteStatement;
-
import org.signal.core.util.CursorExtensionsKt;
import org.signal.core.util.CursorUtil;
import org.signal.core.util.SQLiteDatabaseExtensionsKt;
@@ -100,36 +98,23 @@ public class SmsTable extends MessageTable {
private static final String TAG = Log.tag(SmsTable.class);
- public static final String TABLE_NAME = "sms";
- public static final String PERSON = "person";
- static final String DATE_RECEIVED = "date";
- static final String DATE_SENT = "date_sent";
- public static final String PROTOCOL = "protocol";
- public static final String STATUS = "status";
- public static final String TYPE = "type";
- public static final String REPLY_PATH_PRESENT = "reply_path_present";
- public static final String SUBJECT = "subject";
- public static final String SERVICE_CENTER = "service_center";
+ public static final String TABLE_NAME = "sms";
+ public static final String SMS_STATUS = "status";
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
- THREAD_ID + " INTEGER, " +
- RECIPIENT_ID + " INTEGER, " +
- ADDRESS_DEVICE_ID + " INTEGER DEFAULT 1, " +
- PERSON + " INTEGER, " +
- DATE_RECEIVED + " INTEGER, " +
- DATE_SENT + " INTEGER, " +
+ DATE_SENT + " INTEGER NOT NULL, " +
+ DATE_RECEIVED + " INTEGER NOT NULL, " +
DATE_SERVER + " INTEGER DEFAULT -1, " +
- PROTOCOL + " INTEGER, " +
- READ + " INTEGER DEFAULT 0, " +
- STATUS + " INTEGER DEFAULT -1," +
+ THREAD_ID + " INTEGER NOT NULL REFERENCES " + ThreadTable.TABLE_NAME + " (" + ThreadTable.ID + ") ON DELETE CASCADE, " +
+ RECIPIENT_ID + " INTEGER NOT NULL REFERENCES " + RecipientTable.TABLE_NAME + " (" + RecipientTable.ID + ") ON DELETE CASCADE, " +
+ RECIPIENT_DEVICE_ID + " INTEGER DEFAULT 1, " +
TYPE + " INTEGER, " +
- REPLY_PATH_PRESENT + " INTEGER, " +
- DELIVERY_RECEIPT_COUNT + " INTEGER DEFAULT 0," +
- SUBJECT + " TEXT, " +
BODY + " TEXT, " +
+ READ + " INTEGER DEFAULT 0, " +
+ SMS_STATUS + " INTEGER DEFAULT -1," +
+ DELIVERY_RECEIPT_COUNT + " INTEGER DEFAULT 0," +
MISMATCHED_IDENTITIES + " TEXT DEFAULT NULL, " +
- SERVICE_CENTER + " TEXT, " +
- SUBSCRIPTION_ID + " INTEGER DEFAULT -1, " +
+ SMS_SUBSCRIPTION_ID + " INTEGER DEFAULT -1, " +
EXPIRES_IN + " INTEGER DEFAULT 0, " +
EXPIRE_STARTED + " INTEGER DEFAULT 0, " +
NOTIFIED + " DEFAULT 0, " +
@@ -155,15 +140,30 @@ public class SmsTable extends MessageTable {
};
private static final String[] MESSAGE_PROJECTION = new String[] {
- ID, THREAD_ID, RECIPIENT_ID, ADDRESS_DEVICE_ID, PERSON,
- DATE_RECEIVED + " AS " + NORMALIZED_DATE_RECEIVED,
- DATE_SENT + " AS " + NORMALIZED_DATE_SENT,
+ ID,
+ THREAD_ID,
+ RECIPIENT_ID,
+ RECIPIENT_DEVICE_ID,
+ DATE_RECEIVED,
+ DATE_SENT,
DATE_SERVER,
- 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, UNIDENTIFIED, REACTIONS_UNREAD, REACTIONS_LAST_SEEN,
- REMOTE_DELETED, NOTIFIED_TIMESTAMP, RECEIPT_TIMESTAMP
+ READ,
+ SMS_STATUS,
+ TYPE,
+ BODY,
+ DELIVERY_RECEIPT_COUNT,
+ MISMATCHED_IDENTITIES,
+ SMS_SUBSCRIPTION_ID,
+ EXPIRES_IN,
+ EXPIRE_STARTED,
+ NOTIFIED,
+ READ_RECEIPT_COUNT,
+ UNIDENTIFIED,
+ REACTIONS_UNREAD,
+ REACTIONS_LAST_SEEN,
+ REMOTE_DELETED,
+ NOTIFIED_TIMESTAMP,
+ RECEIPT_TIMESTAMP
};
@VisibleForTesting
@@ -489,7 +489,7 @@ public class SmsTable extends MessageTable {
public void markSmsStatus(long id, int status) {
Log.i(TAG, "Updating ID: " + id + " to status: " + status);
ContentValues contentValues = new ContentValues();
- contentValues.put(STATUS, status);
+ contentValues.put(SMS_STATUS, status);
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {id+""});
@@ -731,7 +731,7 @@ public class SmsTable extends MessageTable {
ContentValues values = new ContentValues();
values.put(RECIPIENT_ID, sender.serialize());
- values.put(ADDRESS_DEVICE_ID, 1);
+ values.put(RECIPIENT_DEVICE_ID, 1);
values.put(DATE_RECEIVED, timestamp);
values.put(DATE_SENT, timestamp);
values.put(READ, markRead ? 1 : 0);
@@ -808,7 +808,7 @@ public class SmsTable extends MessageTable {
ContentValues values = new ContentValues();
values.put(RECIPIENT_ID, sender.serialize());
- values.put(ADDRESS_DEVICE_ID, 1);
+ values.put(RECIPIENT_DEVICE_ID, 1);
values.put(DATE_RECEIVED, timestamp);
values.put(DATE_SENT, timestamp);
values.put(READ, 0);
@@ -880,7 +880,7 @@ public class SmsTable extends MessageTable {
ContentValues values = new ContentValues(6);
values.put(RECIPIENT_ID, recipientId.serialize());
- values.put(ADDRESS_DEVICE_ID, 1);
+ values.put(RECIPIENT_DEVICE_ID, 1);
values.put(DATE_RECEIVED, System.currentTimeMillis());
values.put(DATE_SENT, timestamp);
values.put(READ, unread ? 0 : 1);
@@ -1008,7 +1008,7 @@ public class SmsTable extends MessageTable {
.forEach(threadId -> {
ContentValues values = new ContentValues();
values.put(RECIPIENT_ID, recipient.getId().serialize());
- values.put(ADDRESS_DEVICE_ID, 1);
+ values.put(RECIPIENT_DEVICE_ID, 1);
values.put(DATE_RECEIVED, System.currentTimeMillis());
values.put(DATE_SENT, System.currentTimeMillis());
values.put(READ, 1);
@@ -1056,7 +1056,7 @@ public class SmsTable extends MessageTable {
{
ContentValues values = new ContentValues();
values.put(RECIPIENT_ID, recipientId.serialize());
- values.put(ADDRESS_DEVICE_ID, 1);
+ values.put(RECIPIENT_DEVICE_ID, 1);
values.put(DATE_RECEIVED, System.currentTimeMillis());
values.put(DATE_SENT, System.currentTimeMillis());
values.put(READ, 1);
@@ -1092,7 +1092,7 @@ public class SmsTable extends MessageTable {
.forEach(threadId -> {
ContentValues values = new ContentValues();
values.put(RECIPIENT_ID, recipientId.serialize());
- values.put(ADDRESS_DEVICE_ID, 1);
+ values.put(RECIPIENT_DEVICE_ID, 1);
values.put(DATE_RECEIVED, System.currentTimeMillis());
values.put(DATE_SENT, System.currentTimeMillis());
values.put(READ, 1);
@@ -1121,7 +1121,7 @@ public class SmsTable extends MessageTable {
public void insertBoostRequestMessage(@NonNull RecipientId recipientId, long threadId) {
ContentValues values = new ContentValues();
values.put(RECIPIENT_ID, recipientId.serialize());
- values.put(ADDRESS_DEVICE_ID, 1);
+ values.put(RECIPIENT_DEVICE_ID, 1);
values.put(DATE_RECEIVED, System.currentTimeMillis());
values.put(DATE_SENT, System.currentTimeMillis());
values.put(READ, 1);
@@ -1136,7 +1136,7 @@ public class SmsTable extends MessageTable {
public void insertThreadMergeEvent(@NonNull RecipientId recipientId, long threadId, @NonNull ThreadMergeEvent event) {
ContentValues values = new ContentValues();
values.put(RECIPIENT_ID, recipientId.serialize());
- values.put(ADDRESS_DEVICE_ID, 1);
+ values.put(RECIPIENT_DEVICE_ID, 1);
values.put(DATE_RECEIVED, System.currentTimeMillis());
values.put(DATE_SENT, System.currentTimeMillis());
values.put(READ, 1);
@@ -1153,7 +1153,7 @@ public class SmsTable extends MessageTable {
public void insertSmsExportMessage(@NonNull RecipientId recipientId, long threadId) {
ContentValues values = new ContentValues();
values.put(RECIPIENT_ID, recipientId.serialize());
- values.put(ADDRESS_DEVICE_ID, 1);
+ values.put(RECIPIENT_DEVICE_ID, 1);
values.put(DATE_RECEIVED, System.currentTimeMillis());
values.put(DATE_SENT, System.currentTimeMillis());
values.put(READ, 1);
@@ -1251,21 +1251,14 @@ public class SmsTable extends MessageTable {
ContentValues values = new ContentValues();
values.put(RECIPIENT_ID, message.getSender().serialize());
- values.put(ADDRESS_DEVICE_ID, message.getSenderDeviceId());
+ values.put(RECIPIENT_DEVICE_ID, message.getSenderDeviceId());
values.put(DATE_RECEIVED, message.getReceivedTimestampMillis());
values.put(DATE_SENT, message.getSentTimestampMillis());
values.put(DATE_SERVER, message.getServerTimestampMillis());
- values.put(PROTOCOL, message.getProtocol());
values.put(READ, unread ? 0 : 1);
- values.put(SUBSCRIPTION_ID, message.getSubscriptionId());
+ values.put(SMS_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());
-
- values.put(REPLY_PATH_PRESENT, message.isReplyPathPresent());
- values.put(SERVICE_CENTER, message.getServiceCenterAddress());
values.put(BODY, message.getMessageBody());
values.put(TYPE, type);
values.put(THREAD_ID, threadId);
@@ -1316,7 +1309,7 @@ public class SmsTable extends MessageTable {
ContentValues values = new ContentValues();
values.put(RECIPIENT_ID, recipientId.serialize());
- values.put(ADDRESS_DEVICE_ID, senderDeviceId);
+ values.put(RECIPIENT_DEVICE_ID, senderDeviceId);
values.put(DATE_RECEIVED, System.currentTimeMillis());
values.put(DATE_SENT, sentTimestamp);
values.put(DATE_SERVER, -1);
@@ -1341,7 +1334,7 @@ public class SmsTable extends MessageTable {
public void insertBadDecryptMessage(@NonNull RecipientId recipientId, int senderDevice, long sentTimestamp, long receivedTimestamp, long threadId) {
ContentValues values = new ContentValues();
values.put(RECIPIENT_ID, recipientId.serialize());
- values.put(ADDRESS_DEVICE_ID, senderDevice);
+ values.put(RECIPIENT_DEVICE_ID, senderDevice);
values.put(DATE_SENT, sentTimestamp);
values.put(DATE_RECEIVED, receivedTimestamp);
values.put(DATE_SERVER, -1);
@@ -1387,7 +1380,7 @@ public class SmsTable extends MessageTable {
contentValues.put(DATE_SENT, date);
contentValues.put(READ, 1);
contentValues.put(TYPE, type);
- contentValues.put(SUBSCRIPTION_ID, message.getSubscriptionId());
+ contentValues.put(SMS_SUBSCRIPTION_ID, message.getSubscriptionId());
contentValues.put(EXPIRES_IN, message.getExpiresIn());
contentValues.put(DELIVERY_RECEIPT_COUNT, Stream.of(earlyDeliveryReceipts.values()).mapToLong(EarlyReceiptCache.Receipt::getCount).sum());
contentValues.put(RECEIPT_TIMESTAMP, Stream.of(earlyDeliveryReceipts.values()).mapToLong(EarlyReceiptCache.Receipt::getTimestamp).max().orElse(-1));
@@ -1732,24 +1725,6 @@ public class SmsTable extends MessageTable {
databaseHelper.getSignalWritableDatabase().endTransaction();
}
- @Override
- public SQLiteStatement createInsertStatement(SQLiteDatabase database) {
- return database.compileStatement("INSERT INTO " + TABLE_NAME + " (" + RECIPIENT_ID + ", " +
- PERSON + ", " +
- DATE_SENT + ", " +
- DATE_RECEIVED + ", " +
- PROTOCOL + ", " +
- READ + ", " +
- STATUS + ", " +
- TYPE + ", " +
- REPLY_PATH_PRESENT + ", " +
- SUBJECT + ", " +
- BODY + ", " +
- SERVICE_CENTER +
- ", " + THREAD_ID + ") " +
- " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
- }
-
@Override
public @Nullable ViewOnceExpirationInfo getNearestExpiringViewOnceMessage() {
throw new UnsupportedOperationException();
@@ -1948,17 +1923,17 @@ public class SmsTable extends MessageTable {
public SmsMessageRecord getCurrent() {
long messageId = cursor.getLong(cursor.getColumnIndexOrThrow(SmsTable.ID));
long recipientId = cursor.getLong(cursor.getColumnIndexOrThrow(SmsTable.RECIPIENT_ID));
- int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(SmsTable.ADDRESS_DEVICE_ID));
+ int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(SmsTable.RECIPIENT_DEVICE_ID));
long type = cursor.getLong(cursor.getColumnIndexOrThrow(SmsTable.TYPE));
- long dateReceived = cursor.getLong(cursor.getColumnIndexOrThrow(SmsTable.NORMALIZED_DATE_RECEIVED));
- long dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(SmsTable.NORMALIZED_DATE_SENT));
+ long dateReceived = cursor.getLong(cursor.getColumnIndexOrThrow(SmsTable.DATE_RECEIVED));
+ long dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(SmsTable.DATE_SENT));
long dateServer = cursor.getLong(cursor.getColumnIndexOrThrow(SmsTable.DATE_SERVER));
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(SmsTable.THREAD_ID));
- int status = cursor.getInt(cursor.getColumnIndexOrThrow(SmsTable.STATUS));
+ int status = cursor.getInt(cursor.getColumnIndexOrThrow(SmsTable.SMS_STATUS));
int deliveryReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(SmsTable.DELIVERY_RECEIPT_COUNT));
int readReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(SmsTable.READ_RECEIPT_COUNT));
String mismatchDocument = cursor.getString(cursor.getColumnIndexOrThrow(SmsTable.MISMATCHED_IDENTITIES));
- int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(SmsTable.SUBSCRIPTION_ID));
+ int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(SmsTable.SMS_SUBSCRIPTION_ID));
long expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(SmsTable.EXPIRES_IN));
long expireStarted = cursor.getLong(cursor.getColumnIndexOrThrow(SmsTable.EXPIRE_STARTED));
String body = cursor.getString(cursor.getColumnIndexOrThrow(SmsTable.BODY));
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/StorySendTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/StorySendTable.kt
index f87bd4768e..9315a5e347 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/StorySendTable.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/StorySendTable.kt
@@ -326,7 +326,7 @@ class StorySendTable(context: Context, databaseHelper: SignalDatabase) : Databas
// language=sql
"""
SELECT
- $RECIPIENT_ID,
+ $TABLE_NAME.$RECIPIENT_ID,
$ALLOWS_REPLIES,
$DISTRIBUTION_ID,
${MmsTable.REMOTE_DELETED}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadTable.kt
index 155841f05e..866bbb8e38 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadTable.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadTable.kt
@@ -76,14 +76,13 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
const val TABLE_NAME = "thread"
const val ID = "_id"
const val DATE = "date"
- const val MEANINGFUL_MESSAGES = "message_count"
- const val RECIPIENT_ID = "thread_recipient_id"
- const val SNIPPET = "snippet"
- const val SNIPPET_CHARSET = "snippet_charset"
+ const val MEANINGFUL_MESSAGES = "meaningful_messages"
+ const val RECIPIENT_ID = "recipient_id"
const val READ = "read"
const val UNREAD_COUNT = "unread_count"
const val TYPE = "type"
const val ERROR = "error"
+ const val SNIPPET = "snippet"
const val SNIPPET_TYPE = "snippet_type"
const val SNIPPET_URI = "snippet_uri"
const val SNIPPET_CONTENT_TYPE = "snippet_content_type"
@@ -106,11 +105,10 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
$DATE INTEGER DEFAULT 0,
$MEANINGFUL_MESSAGES INTEGER DEFAULT 0,
$RECIPIENT_ID INTEGER,
- $SNIPPET TEXT,
- $SNIPPET_CHARSET INTEGER DEFAULT 0,
$READ INTEGER DEFAULT ${ReadStatus.READ.serialize()},
$TYPE INTEGER DEFAULT 0,
$ERROR INTEGER DEFAULT 0,
+ $SNIPPET TEXT,
$SNIPPET_TYPE INTEGER DEFAULT 0,
$SNIPPET_URI TEXT DEFAULT NULL,
$SNIPPET_CONTENT_TYPE TEXT DEFAULT NULL,
@@ -143,7 +141,6 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
MEANINGFUL_MESSAGES,
RECIPIENT_ID,
SNIPPET,
- SNIPPET_CHARSET,
READ,
UNREAD_COUNT,
TYPE,
@@ -343,7 +340,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
mmsSms.getConversation(threadId).use { cursor ->
if (cursor.count > length) {
cursor.moveToPosition(length - 1)
- max(trimBeforeDate, cursor.requireLong(MmsSmsColumns.NORMALIZED_DATE_RECEIVED))
+ max(trimBeforeDate, cursor.requireLong(MmsSmsColumns.DATE_RECEIVED))
} else {
trimBeforeDate
}
@@ -702,14 +699,14 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
}
if (hideSelf) {
- where += " AND $RECIPIENT_ID != ${Recipient.self().id.toLong()}"
+ where += " AND $TABLE_NAME.$RECIPIENT_ID != ${Recipient.self().id.toLong()}"
}
where += " AND $ARCHIVED = 0"
where += " AND ${RecipientTable.TABLE_NAME}.${RecipientTable.BLOCKED} = 0"
if (SignalStore.releaseChannelValues().releaseChannelRecipientId != null) {
- where += " AND $RECIPIENT_ID != ${SignalStore.releaseChannelValues().releaseChannelRecipientId!!.toLong()}"
+ where += " AND $TABLE_NAME.$RECIPIENT_ID != ${SignalStore.releaseChannelValues().releaseChannelRecipientId!!.toLong()}"
}
val query = createQuery(
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt
index 3c52395e84..664850d107 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt
@@ -21,6 +21,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V162_ThreadUnreadSe
import org.thoughtcrime.securesms.database.helpers.migration.V163_RemoteMegaphoneSnoozeSupportMigration
import org.thoughtcrime.securesms.database.helpers.migration.V164_ThreadDatabaseReadIndexMigration
import org.thoughtcrime.securesms.database.helpers.migration.V165_MmsMessageBoxPaymentTransactionIndexMigration
+import org.thoughtcrime.securesms.database.helpers.migration.V166_ThreadAndMessageForeignKeys
/**
* Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness.
@@ -29,7 +30,7 @@ object SignalDatabaseMigrations {
val TAG: String = Log.tag(SignalDatabaseMigrations.javaClass)
- const val DATABASE_VERSION = 165
+ const val DATABASE_VERSION = 166
@JvmStatic
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
@@ -100,6 +101,10 @@ object SignalDatabaseMigrations {
if (oldVersion < 165) {
V165_MmsMessageBoxPaymentTransactionIndexMigration.migrate(context, db, oldVersion, newVersion)
}
+
+ if (oldVersion < 166) {
+ V166_ThreadAndMessageForeignKeys.migrate(context, db, oldVersion, newVersion)
+ }
}
@JvmStatic
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V166_ThreadAndMessageForeignKeys.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V166_ThreadAndMessageForeignKeys.kt
new file mode 100644
index 0000000000..f4782ae7c4
--- /dev/null
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V166_ThreadAndMessageForeignKeys.kt
@@ -0,0 +1,424 @@
+package org.thoughtcrime.securesms.database.helpers.migration
+
+import android.app.Application
+import net.zetetic.database.sqlcipher.SQLiteDatabase
+import org.signal.core.util.Stopwatch
+import org.signal.core.util.delete
+import org.signal.core.util.logging.Log
+import org.signal.core.util.readToList
+import org.signal.core.util.requireLong
+import org.signal.core.util.update
+
+/**
+ * This one's a doozy. We want to add additional foreign key constraints between the thread, recipient, and message tables. This will let us know for sure
+ * that there aren't threads with invalid recipients, or messages with invalid threads, or multiple threads for the same recipient.
+ */
+object V166_ThreadAndMessageForeignKeys : SignalDatabaseMigration {
+
+ private val TAG = Log.tag(V166_ThreadAndMessageForeignKeys::class.java)
+
+ override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
+ val stopwatch = Stopwatch("migration")
+
+ removeDuplicateThreadEntries(db)
+ stopwatch.split("thread-dupes")
+
+ updateThreadTableSchema(db)
+ stopwatch.split("thread-schema")
+
+ fixDanglingSmsMessages(db)
+ stopwatch.split("sms-dangling")
+
+ fixDanglingMmsMessages(db)
+ stopwatch.split("mms-dangling")
+
+ updateSmsTableSchema(db)
+ stopwatch.split("sms-schema")
+
+ updateMmsTableSchema(db)
+ stopwatch.split("mms-schema")
+
+ stopwatch.stop(TAG)
+ }
+
+ private fun removeDuplicateThreadEntries(db: SQLiteDatabase) {
+ db.rawQuery(
+ """
+ SELECT
+ thread_recipient_id,
+ COUNT(*) AS thread_count
+ FROM thread
+ GROUP BY thread_recipient_id HAVING thread_count > 1
+ """.trimMargin()
+ ).use { cursor ->
+ while (cursor.moveToNext()) {
+ val recipientId = cursor.requireLong("thread_recipient_id")
+ val count = cursor.requireLong("thread_count")
+ Log.w(TAG, "There were $count threads for RecipientId::$recipientId. Merging.")
+
+ val threads: List = getThreadsByRecipientId(db, cursor.requireLong("thread_recipient_id"))
+ mergeThreads(db, threads)
+ }
+ }
+ }
+
+ private fun getThreadsByRecipientId(db: SQLiteDatabase, recipientId: Long): List {
+ return db.rawQuery("SELECT _id, date FROM thread WHERE thread_recipient_id = ?".trimIndent(), recipientId).readToList { cursor ->
+ ThreadInfo(cursor.requireLong("_id"), cursor.requireLong("date"))
+ }
+ }
+
+ private fun mergeThreads(db: SQLiteDatabase, threads: List) {
+ val primaryThread: ThreadInfo = threads.maxByOrNull { it.date }!!
+ val secondaryThreads: List = threads.filterNot { it.id == primaryThread.id }
+
+ secondaryThreads.forEach { secondaryThread ->
+ remapThread(db, primaryThread.id, secondaryThread.id)
+ }
+ }
+
+ private fun remapThread(db: SQLiteDatabase, primaryId: Long, secondaryId: Long) {
+ db.update("drafts")
+ .values("thread_id" to primaryId)
+ .where("thread_id = ?", secondaryId)
+ .run()
+
+ db.update("mention")
+ .values("thread_id" to primaryId)
+ .where("thread_id = ?", secondaryId)
+ .run()
+
+ db.update("mms")
+ .values("thread_id" to primaryId)
+ .where("thread_id = ?", secondaryId)
+ .run()
+
+ db.update("sms")
+ .values("thread_id" to primaryId)
+ .where("thread_id = ?", secondaryId)
+ .run()
+
+ db.update("pending_retry_receipts")
+ .values("thread_id" to primaryId)
+ .where("thread_id = ?", secondaryId)
+ .run()
+
+ db.delete("thread")
+ .where("_id = ?", secondaryId)
+ .run()
+ }
+
+ private fun updateThreadTableSchema(db: SQLiteDatabase) {
+ db.execSQL(
+ """
+ CREATE TABLE thread_tmp (
+ _id INTEGER PRIMARY KEY AUTOINCREMENT,
+ date INTEGER DEFAULT 0,
+ meaningful_messages INTEGER DEFAULT 0,
+ recipient_id INTEGER NOT NULL UNIQUE REFERENCES recipient (_id) ON DELETE CASCADE,
+ read INTEGER DEFAULT 1,
+ type INTEGER DEFAULT 0,
+ error INTEGER DEFAULT 0,
+ snippet TEXT,
+ snippet_type INTEGER DEFAULT 0,
+ snippet_uri TEXT DEFAULT NULL,
+ snippet_content_type TEXT DEFAULT NULL,
+ snippet_extras TEXT DEFAULT NULL,
+ unread_count INTEGER DEFAULT 0,
+ archived INTEGER DEFAULT 0,
+ status INTEGER DEFAULT 0,
+ delivery_receipt_count INTEGER DEFAULT 0,
+ read_receipt_count INTEGER DEFAULT 0,
+ expires_in INTEGER DEFAULT 0,
+ last_seen INTEGER DEFAULT 0,
+ has_sent INTEGER DEFAULT 0,
+ last_scrolled INTEGER DEFAULT 0,
+ pinned INTEGER DEFAULT 0,
+ unread_self_mention_count INTEGER DEFAULT 0
+ )
+ """.trimIndent()
+ )
+
+ db.execSQL(
+ """
+ INSERT INTO thread_tmp
+ SELECT
+ _id,
+ date,
+ message_count,
+ thread_recipient_id,
+ read,
+ type,
+ error,
+ snippet,
+ snippet_type,
+ snippet_uri,
+ snippet_content_type,
+ snippet_extras,
+ unread_count,
+ archived,
+ status,
+ delivery_receipt_count,
+ read_receipt_count,
+ expires_in,
+ last_seen,
+ has_sent,
+ last_scrolled,
+ pinned,
+ unread_self_mention_count
+ FROM thread
+ """.trimMargin()
+ )
+
+ db.execSQL("DROP TABLE thread")
+ db.execSQL("ALTER TABLE thread_tmp RENAME TO thread")
+
+ db.execSQL("CREATE INDEX thread_recipient_id_index ON thread (recipient_id)")
+ db.execSQL("CREATE INDEX archived_count_index ON thread (archived, meaningful_messages)")
+ db.execSQL("CREATE INDEX thread_pinned_index ON thread (pinned)")
+ db.execSQL("CREATE INDEX thread_read ON thread (read)")
+ }
+
+ private fun fixDanglingSmsMessages(db: SQLiteDatabase) {
+ db.delete("sms")
+ .where("address NOT IN (SELECT _id FROM recipient)")
+ .run()
+
+ // Can't even attempt to "fix" these because without the threadId we don't know if it's a 1:1 or group message
+ db.delete("sms")
+ .where("thread_id NOT IN (SELECT _id FROM thread)")
+ .run()
+ }
+
+ private fun fixDanglingMmsMessages(db: SQLiteDatabase) {
+ db.delete("mms")
+ .where("address NOT IN (SELECT _id FROM recipient)")
+ .run()
+
+ // Can't even attempt to "fix" these because without the threadId we don't know if it's a 1:1 or group message
+ db.delete("mms")
+ .where("thread_id NOT IN (SELECT _id FROM thread)")
+ .run()
+ }
+
+ private fun updateSmsTableSchema(db: SQLiteDatabase) {
+ db.execSQL(
+ """
+ CREATE TABLE sms_tmp (
+ _id INTEGER PRIMARY KEY AUTOINCREMENT,
+ date_sent INTEGER NOT NULL,
+ date_received INTEGER NOT NULL,
+ date_server INTEGER DEFAULT -1,
+ thread_id INTEGER NOT NULL REFERENCES thread (_id) ON DELETE CASCADE,
+ recipient_id NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE,
+ recipient_device_id INTEGER DEFAULT 1,
+ type INTEGER,
+ body TEXT,
+ read INTEGER DEFAULT 0,
+ status INTEGER DEFAULT -1,
+ delivery_receipt_count INTEGER DEFAULT 0,
+ mismatched_identities TEXT DEFAULT NULL,
+ subscription_id INTEGER DEFAULT -1,
+ expires_in INTEGER DEFAULT 0,
+ expire_started INTEGER DEFAULT 0,
+ notified INTEGER DEFAULT 0,
+ read_receipt_count INTEGER DEFAULT 0,
+ unidentified INTEGER DEFAULT 0,
+ reactions_unread INTEGER DEFAULT 0,
+ reactions_last_seen INTEGER DEFAULT -1,
+ remote_deleted INTEGER DEFAULT 0,
+ notified_timestamp INTEGER DEFAULT 0,
+ server_guid TEXT DEFAULT NULL,
+ receipt_timestamp INTEGER DEFAULT -1,
+ export_state BLOB DEFAULT NULL,
+ exported INTEGER DEFAULT 0
+ )
+ """.trimIndent()
+ )
+
+ db.execSQL(
+ """
+ INSERT INTO sms_tmp
+ SELECT
+ _id,
+ date_sent,
+ date,
+ date_server,
+ thread_id,
+ address,
+ address_device_id,
+ type,
+ body,
+ read,
+ status,
+ delivery_receipt_count,
+ mismatched_identities,
+ subscription_id,
+ expires_in,
+ expire_started,
+ notified,
+ read_receipt_count,
+ unidentified,
+ reactions_unread,
+ reactions_last_seen,
+ remote_deleted,
+ notified_timestamp,
+ server_guid,
+ receipt_timestamp,
+ export_state,
+ exported
+ FROM sms
+ """.trimIndent()
+ )
+
+ db.execSQL("DROP TABLE sms")
+ db.execSQL("ALTER TABLE sms_tmp RENAME TO sms")
+
+ db.execSQL("CREATE INDEX sms_read_and_notified_and_thread_id_index ON sms(read, notified, thread_id)")
+ db.execSQL("CREATE INDEX sms_type_index ON sms (type)")
+ db.execSQL("CREATE INDEX sms_date_sent_index ON sms (date_sent, recipient_id, thread_id)")
+ db.execSQL("CREATE INDEX sms_date_server_index ON sms (date_server)")
+ db.execSQL("CREATE INDEX sms_thread_date_index ON sms (thread_id, date_received)")
+ db.execSQL("CREATE INDEX sms_reactions_unread_index ON sms (reactions_unread)")
+ db.execSQL("CREATE INDEX sms_exported_index ON sms (exported)")
+
+ db.execSQL("CREATE TRIGGER sms_ai AFTER INSERT ON sms BEGIN INSERT INTO sms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id); END;")
+ db.execSQL("CREATE TRIGGER sms_ad AFTER DELETE ON sms BEGIN INSERT INTO sms_fts(sms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); END;")
+ db.execSQL("CREATE TRIGGER sms_au AFTER UPDATE ON sms BEGIN INSERT INTO sms_fts(sms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); INSERT INTO sms_fts(rowid, body, thread_id) VALUES(new._id, new.body, new.thread_id); END;")
+ db.execSQL("CREATE TRIGGER msl_sms_delete AFTER DELETE ON sms BEGIN DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old._id AND is_mms = 0); END")
+ }
+
+ private fun updateMmsTableSchema(db: SQLiteDatabase) {
+ db.execSQL(
+ """
+ CREATE TABLE mms_tmp (
+ _id INTEGER PRIMARY KEY AUTOINCREMENT,
+ date_sent INTEGER NOT NULL,
+ date_received INTEGER NOT NULL,
+ date_server INTEGER DEFAULT -1,
+ thread_id INTEGER NOT NULL REFERENCES thread (_id) ON DELETE CASCADE,
+ recipient_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE,
+ recipient_device_id INTEGER,
+ type INTEGER NOT NULL,
+ body TEXT,
+ read INTEGER DEFAULT 0,
+ ct_l TEXT,
+ exp INTEGER,
+ m_type INTEGER,
+ m_size INTEGER,
+ st INTEGER,
+ tr_id TEXT,
+ subscription_id INTEGER DEFAULT -1,
+ receipt_timestamp INTEGER DEFAULT -1,
+ delivery_receipt_count INTEGER DEFAULT 0,
+ read_receipt_count INTEGER DEFAULT 0,
+ viewed_receipt_count INTEGER DEFAULT 0,
+ mismatched_identities TEXT DEFAULT NULL,
+ network_failures TEXT DEFAULT NULL,
+ expires_in INTEGER DEFAULT 0,
+ expire_started INTEGER DEFAULT 0,
+ notified INTEGER DEFAULT 0,
+ quote_id INTEGER DEFAULT 0,
+ quote_author INTEGER DEFAULT 0,
+ quote_body TEXT DEFAULT NULL,
+ quote_missing INTEGER DEFAULT 0,
+ quote_mentions BLOB DEFAULT NULL,
+ quote_type INTEGER DEFAULT 0,
+ shared_contacts TEXT DEFAULT NULL,
+ unidentified INTEGER DEFAULT 0,
+ link_previews TEXT DEFAULT NULL,
+ view_once INTEGER DEFAULT 0,
+ reactions_unread INTEGER DEFAULT 0,
+ reactions_last_seen INTEGER DEFAULT -1,
+ remote_deleted INTEGER DEFAULT 0,
+ mentions_self INTEGER DEFAULT 0,
+ notified_timestamp INTEGER DEFAULT 0,
+ server_guid TEXT DEFAULT NULL,
+ message_ranges BLOB DEFAULT NULL,
+ story_type INTEGER DEFAULT 0,
+ parent_story_id INTEGER DEFAULT 0,
+ export_state BLOB DEFAULT NULL,
+ exported INTEGER DEFAULT 0
+ )
+ """.trimIndent()
+ )
+
+ db.execSQL(
+ """
+ INSERT INTO mms_tmp
+ SELECT
+ _id,
+ date,
+ date_received,
+ date_server,
+ thread_id,
+ address,
+ address_device_id,
+ msg_box,
+ body,
+ read,
+ ct_l,
+ exp,
+ m_type,
+ m_size,
+ st,
+ tr_id,
+ subscription_id,
+ receipt_timestamp,
+ delivery_receipt_count,
+ read_receipt_count,
+ viewed_receipt_count,
+ mismatched_identities,
+ network_failures,
+ expires_in,
+ expire_started,
+ notified,
+ quote_id,
+ quote_author,
+ quote_body,
+ quote_missing,
+ quote_mentions,
+ quote_type,
+ shared_contacts,
+ unidentified,
+ previews,
+ reveal_duration,
+ reactions_unread,
+ reactions_last_seen,
+ remote_deleted,
+ mentions_self,
+ notified_timestamp,
+ server_guid,
+ ranges,
+ is_story,
+ parent_story_id,
+ export_state,
+ exported
+ FROM mms
+ """.trimIndent()
+ )
+
+ db.execSQL("DROP TABLE mms")
+ db.execSQL("ALTER TABLE mms_tmp RENAME TO mms")
+
+ db.execSQL("CREATE INDEX mms_read_and_notified_and_thread_id_index ON mms(read, notified, thread_id)")
+ db.execSQL("CREATE INDEX mms_type_index ON mms (type)")
+ db.execSQL("CREATE INDEX mms_date_sent_index ON mms (date_sent, recipient_id, thread_id)")
+ db.execSQL("CREATE INDEX mms_date_server_index ON mms (date_server)")
+ db.execSQL("CREATE INDEX mms_thread_date_index ON mms (thread_id, date_received)")
+ db.execSQL("CREATE INDEX mms_reactions_unread_index ON mms (reactions_unread)")
+ db.execSQL("CREATE INDEX IF NOT EXISTS mms_story_type_index ON mms (story_type)")
+ db.execSQL("CREATE INDEX IF NOT EXISTS mms_parent_story_id_index ON mms (parent_story_id)")
+ db.execSQL("CREATE INDEX IF NOT EXISTS mms_thread_story_parent_story_index ON mms (thread_id, date_received, story_type, parent_story_id)")
+ db.execSQL("CREATE INDEX IF NOT EXISTS mms_quote_id_quote_author_index ON mms (quote_id, quote_author)")
+ db.execSQL("CREATE INDEX IF NOT EXISTS mms_exported_index ON mms (exported)")
+ db.execSQL("CREATE INDEX IF NOT EXISTS mms_id_type_payment_transactions_index ON mms (_id, type) WHERE type & ${0x300000000L} != 0")
+
+ db.execSQL("CREATE TRIGGER mms_ai AFTER INSERT ON mms BEGIN INSERT INTO mms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id); END")
+ db.execSQL("CREATE TRIGGER mms_ad AFTER DELETE ON mms BEGIN INSERT INTO mms_fts(mms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); END")
+ db.execSQL("CREATE TRIGGER mms_au AFTER UPDATE ON mms BEGIN INSERT INTO mms_fts(mms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); INSERT INTO mms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id); END")
+ db.execSQL("CREATE TRIGGER msl_mms_delete AFTER DELETE ON mms BEGIN DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old._id AND is_mms = 1); END")
+ }
+
+ data class ThreadInfo(val id: Long, val date: Long)
+}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java
index 7bc00039f2..4d49357963 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java
@@ -60,7 +60,6 @@ import java.util.stream.Collectors;
public class MediaMmsMessageRecord extends MmsMessageRecord {
private final static String TAG = Log.tag(MediaMmsMessageRecord.class);
- private final int partCount;
private final boolean mentionsSelf;
private final BodyRangeList messageRanges;
private final Payment payment;
@@ -76,7 +75,6 @@ public class MediaMmsMessageRecord extends MmsMessageRecord {
long threadId,
String body,
@NonNull SlideDeck slideDeck,
- int partCount,
long mailbox,
Set mismatches,
Set failures,
@@ -106,7 +104,6 @@ public class MediaMmsMessageRecord extends MmsMessageRecord {
subscriptionId, expiresIn, expireStarted, viewOnce, slideDeck,
readReceiptCount, quote, contacts, linkPreviews, unidentified, reactions, remoteDelete, notifiedTimestamp, viewedReceiptCount, receiptTimestamp,
storyType, parentStoryId, giftBadge);
- this.partCount = partCount;
this.mentionsSelf = mentionsSelf;
this.messageRanges = messageRanges;
this.payment = payment;
@@ -140,10 +137,6 @@ public class MediaMmsMessageRecord extends MmsMessageRecord {
return super.getDisplayBody(context);
}
- public int getPartCount() {
- return partCount;
- }
-
public @Nullable BodyRangeList getMessageRanges() {
return messageRanges;
}
@@ -164,14 +157,14 @@ public class MediaMmsMessageRecord extends MmsMessageRecord {
public @NonNull MediaMmsMessageRecord withReactions(@NonNull List reactions) {
return new MediaMmsMessageRecord(getId(), getRecipient(), getIndividualRecipient(), getRecipientDeviceId(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), getSlideDeck(),
- getPartCount(), getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
+ getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), getQuote(), getSharedContacts(), getLinkPreviews(), isUnidentified(), reactions, isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment());
}
public @NonNull MediaMmsMessageRecord withoutQuote() {
return new MediaMmsMessageRecord(getId(), getRecipient(), getIndividualRecipient(), getRecipientDeviceId(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), getSlideDeck(),
- getPartCount(), getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
+ getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), null, getSharedContacts(), getLinkPreviews(), isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment());
}
@@ -192,14 +185,14 @@ public class MediaMmsMessageRecord extends MmsMessageRecord {
SlideDeck slideDeck = MmsTable.Reader.buildSlideDeck(context, slideAttachments);
return new MediaMmsMessageRecord(getId(), getRecipient(), getIndividualRecipient(), getRecipientDeviceId(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), slideDeck,
- getPartCount(), getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
+ getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), quote, contacts, linkPreviews, isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment());
}
public @NonNull MediaMmsMessageRecord withPayment(@NonNull Payment payment) {
return new MediaMmsMessageRecord(getId(), getRecipient(), getIndividualRecipient(), getRecipientDeviceId(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), getSlideDeck(),
- getPartCount(), getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
+ getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), getQuote(), getSharedContacts(), getLinkPreviews(), isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), payment);
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java
index 3c9bff36e3..db03de0ea8 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java
@@ -111,9 +111,10 @@ public class ApplicationMigrations {
static final int SYSTEM_NAME_SYNC = 67;
static final int STORY_VIEWED_STATE = 68;
static final int STORY_READ_STATE = 69;
+ static final int THREAD_MESSAGE_SCHEMA_CHANGE = 70;
}
- public static final int CURRENT_VERSION = 69;
+ public static final int CURRENT_VERSION = 70;
/**
* This *must* be called after the {@link JobManager} has been instantiated, but *before* the call
@@ -491,6 +492,10 @@ public class ApplicationMigrations {
jobs.put(Version.STORY_READ_STATE, new StoryReadStateMigrationJob());
}
+ if (lastSeenVersion < Version.THREAD_MESSAGE_SCHEMA_CHANGE) {
+ jobs.put(Version.THREAD_MESSAGE_SCHEMA_CHANGE, new DatabaseMigrationJob());
+ }
+
return jobs;
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java b/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java
index c39eeea6d7..8224cadd38 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java
@@ -451,7 +451,7 @@ public class SearchRepository {
Recipient messageRecipient = Recipient.live(messageRecipientId).get();
String body = CursorUtil.requireString(cursor, SearchTable.BODY);
String bodySnippet = CursorUtil.requireString(cursor, SearchTable.SNIPPET);
- long receivedMs = CursorUtil.requireLong(cursor, MmsSmsColumns.NORMALIZED_DATE_RECEIVED);
+ long receivedMs = CursorUtil.requireLong(cursor, MmsSmsColumns.DATE_RECEIVED);
long threadId = CursorUtil.requireLong(cursor, MmsSmsColumns.THREAD_ID);
int messageId = CursorUtil.requireInt(cursor, SearchTable.MESSAGE_ID);
boolean isMms = CursorUtil.requireInt(cursor, SearchTable.IS_MMS) == 1;
diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/ApplicationMigrationService.java b/app/src/main/java/org/thoughtcrime/securesms/service/ApplicationMigrationService.java
deleted file mode 100644
index 180382d630..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/service/ApplicationMigrationService.java
+++ /dev/null
@@ -1,226 +0,0 @@
-package org.thoughtcrime.securesms.service;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.graphics.BitmapFactory;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-
-import androidx.core.app.NotificationCompat;
-
-import org.signal.core.util.PendingIntentFlags;
-import org.signal.core.util.logging.Log;
-import org.thoughtcrime.securesms.MainActivity;
-import org.thoughtcrime.securesms.R;
-import org.thoughtcrime.securesms.database.SmsMigrator;
-import org.thoughtcrime.securesms.database.SmsMigrator.ProgressDescription;
-import org.thoughtcrime.securesms.notifications.NotificationChannels;
-import org.thoughtcrime.securesms.notifications.NotificationIds;
-
-import java.lang.ref.WeakReference;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-
-// FIXME: This class is nuts.
-public class ApplicationMigrationService extends Service
- implements SmsMigrator.SmsMigrationProgressListener
-{
- private static final String TAG = Log.tag(ApplicationMigrationService.class);
- public static final String MIGRATE_DATABASE = "org.thoughtcrime.securesms.ApplicationMigration.MIGRATE_DATABSE";
- public static final String COMPLETED_ACTION = "org.thoughtcrime.securesms.ApplicationMigrationService.COMPLETED";
- private static final String PREFERENCES_NAME = "SecureSMS";
- private static final String DATABASE_MIGRATED = "migrated";
-
- private final BroadcastReceiver completedReceiver = new CompletedReceiver();
- private final Binder binder = new ApplicationMigrationBinder();
- private final Executor executor = Executors.newSingleThreadExecutor();
-
- private WeakReference handler = null;
- private NotificationCompat.Builder notification = null;
- private ImportState state = new ImportState(ImportState.STATE_IDLE, null);
-
- @Override
- public void onCreate() {
- registerCompletedReceiver();
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- if (intent == null) return START_NOT_STICKY;
-
- if (intent.getAction() != null && intent.getAction().equals(MIGRATE_DATABASE)) {
- executor.execute(new ImportRunnable());
- }
-
- return START_NOT_STICKY;
- }
-
- @Override
- public void onDestroy() {
- unregisterCompletedReceiver();
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return binder;
- }
-
- public void setImportStateHandler(Handler handler) {
- this.handler = new WeakReference<>(handler);
- }
-
- private void registerCompletedReceiver() {
- IntentFilter filter = new IntentFilter();
- filter.addAction(COMPLETED_ACTION);
-
- registerReceiver(completedReceiver, filter);
- }
-
- private void unregisterCompletedReceiver() {
- unregisterReceiver(completedReceiver);
- }
-
- private void notifyImportComplete() {
- Intent intent = new Intent();
- intent.setAction(COMPLETED_ACTION);
-
- sendOrderedBroadcast(intent, null);
- }
-
- @Override
- public void progressUpdate(ProgressDescription progress) {
- setState(new ImportState(ImportState.STATE_MIGRATING_IN_PROGRESS, progress));
- }
-
- public ImportState getState() {
- return state;
- }
-
- private void setState(ImportState state) {
- this.state = state;
-
- if (this.handler != null) {
- Handler handler = this.handler.get();
-
- if (handler != null) {
- handler.obtainMessage(state.state, state.progress).sendToTarget();
- }
- }
-
- if (state.progress != null && state.progress.secondaryComplete == 0) {
- updateBackgroundNotification(state.progress.primaryTotal, state.progress.primaryComplete);
- }
- }
-
- private void updateBackgroundNotification(int total, int complete) {
- notification.setProgress(total, complete, false);
-
- ((NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE))
- .notify(NotificationIds.APPLICATION_MIGRATION, notification.build());
- }
-
- private NotificationCompat.Builder initializeBackgroundNotification() {
- NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NotificationChannels.OTHER);
-
- builder.setSmallIcon(R.drawable.ic_notification);
- builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_notification));
- builder.setContentTitle(getString(R.string.ApplicationMigrationService_importing_text_messages));
- builder.setContentText(getString(R.string.ApplicationMigrationService_import_in_progress));
- builder.setOngoing(true);
- builder.setProgress(100, 0, false);
- // TODO [greyson] Navigation
- builder.setContentIntent(PendingIntent.getActivity(this, 0, MainActivity.clearTop(this), PendingIntentFlags.mutable()));
-
- stopForeground(true);
- startForeground(NotificationIds.APPLICATION_MIGRATION, builder.build());
-
- return builder;
- }
-
- private class ImportRunnable implements Runnable {
-
- ImportRunnable() {}
-
- @Override
- public void run() {
- notification = initializeBackgroundNotification();
- PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
- WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "signal:migration");
-
- try {
- wakeLock.acquire();
-
- setState(new ImportState(ImportState.STATE_MIGRATING_BEGIN, null));
-
- SmsMigrator.migrateDatabase(ApplicationMigrationService.this,
- ApplicationMigrationService.this);
-
- setState(new ImportState(ImportState.STATE_MIGRATING_COMPLETE, null));
-
- setDatabaseImported(ApplicationMigrationService.this);
- stopForeground(true);
- notifyImportComplete();
- stopSelf();
- } finally {
- wakeLock.release();
- }
- }
- }
-
- public class ApplicationMigrationBinder extends Binder {
- public ApplicationMigrationService getService() {
- return ApplicationMigrationService.this;
- }
- }
-
- private static class CompletedReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NotificationChannels.OTHER);
- builder.setSmallIcon(R.drawable.ic_notification);
- builder.setContentTitle(context.getString(R.string.ApplicationMigrationService_import_complete));
- builder.setContentText(context.getString(R.string.ApplicationMigrationService_system_database_import_is_complete));
- // TODO [greyson] Navigation
- builder.setContentIntent(PendingIntent.getActivity(context, 0, MainActivity.clearTop(context), PendingIntentFlags.mutable()));
- builder.setWhen(System.currentTimeMillis());
- builder.setDefaults(Notification.DEFAULT_VIBRATE);
- builder.setAutoCancel(true);
-
- Notification notification = builder.build();
- ((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE)).notify(NotificationIds.SMS_IMPORT_COMPLETE, notification);
- }
- }
-
- public static class ImportState {
- public static final int STATE_IDLE = 0;
- public static final int STATE_MIGRATING_BEGIN = 1;
- public static final int STATE_MIGRATING_IN_PROGRESS = 2;
- public static final int STATE_MIGRATING_COMPLETE = 3;
-
- public int state;
- public ProgressDescription progress;
-
- public ImportState(int state, ProgressDescription progress) {
- this.state = state;
- this.progress = progress;
- }
- }
-
- public static boolean isDatabaseImported(Context context) {
- return context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE)
- .getBoolean(DATABASE_MIGRATED, false);
- }
-
- public static void setDatabaseImported(Context context) {
- context.getSharedPreferences(PREFERENCES_NAME, 0).edit().putBoolean(DATABASE_MIGRATED, true).apply();
- }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/MmsListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/MmsListener.java
index 3746233ae0..96d8f64ba7 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/service/MmsListener.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/service/MmsListener.java
@@ -31,10 +31,6 @@ public class MmsListener extends BroadcastReceiver {
private static final String TAG = Log.tag(MmsListener.class);
private boolean isRelevant(Context context, Intent intent) {
- if (!ApplicationMigrationService.isDatabaseImported(context)) {
- return false;
- }
-
if (Telephony.Sms.Intents.WAP_PUSH_RECEIVED_ACTION.equals(intent.getAction()) && Util.isDefaultSmsProvider(context)) {
return false;
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/SmsListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/SmsListener.java
index 19b579287d..93ac1121ea 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/service/SmsListener.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/service/SmsListener.java
@@ -86,9 +86,6 @@ public class SmsListener extends BroadcastReceiver {
if (isExemption(message, messageBody))
return false;
- if (!ApplicationMigrationService.isDatabaseImported(context))
- return false;
-
if (SMS_RECEIVED_ACTION.equals(intent.getAction()) && Util.isDefaultSmsProvider(context)) {
return false;
}
diff --git a/app/src/spinner/java/org/thoughtcrime/securesms/database/GV2UpdateTransformer.kt b/app/src/spinner/java/org/thoughtcrime/securesms/database/GV2UpdateTransformer.kt
index 9becc0e1fa..29d27a4333 100644
--- a/app/src/spinner/java/org/thoughtcrime/securesms/database/GV2UpdateTransformer.kt
+++ b/app/src/spinner/java/org/thoughtcrime/securesms/database/GV2UpdateTransformer.kt
@@ -39,8 +39,7 @@ object GV2UpdateTransformer : ColumnTransformer {
private fun Cursor.getMessageType(): Long {
return when {
- getColumnIndex(SmsTable.TYPE) != -1 -> requireLong(SmsTable.TYPE)
- getColumnIndex(MmsTable.MESSAGE_BOX) != -1 -> requireLong(MmsTable.MESSAGE_BOX)
+ getColumnIndex(MmsSmsColumns.TYPE) != -1 -> requireLong(MmsSmsColumns.TYPE)
else -> -1
}
}
diff --git a/app/src/test/java/org/thoughtcrime/securesms/database/FakeMessageRecords.kt b/app/src/test/java/org/thoughtcrime/securesms/database/FakeMessageRecords.kt
index fbf2deb202..73a5332171 100644
--- a/app/src/test/java/org/thoughtcrime/securesms/database/FakeMessageRecords.kt
+++ b/app/src/test/java/org/thoughtcrime/securesms/database/FakeMessageRecords.kt
@@ -151,7 +151,6 @@ object FakeMessageRecords {
threadId,
body,
slideDeck,
- partCount,
mailbox,
mismatches,
failures,
diff --git a/app/src/test/java/org/thoughtcrime/securesms/database/TestMms.kt b/app/src/test/java/org/thoughtcrime/securesms/database/TestMms.kt
index 68d11c061f..ca34c31208 100644
--- a/app/src/test/java/org/thoughtcrime/securesms/database/TestMms.kt
+++ b/app/src/test/java/org/thoughtcrime/securesms/database/TestMms.kt
@@ -77,13 +77,13 @@ object TestMms {
): Long {
val contentValues = ContentValues().apply {
put(MmsTable.DATE_SENT, message.sentTimeMillis)
- put(MmsTable.MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_SEND_REQ)
+ put(MmsTable.MMS_MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_SEND_REQ)
- put(MmsTable.MESSAGE_BOX, type)
+ put(MmsTable.TYPE, type)
put(MmsSmsColumns.THREAD_ID, threadId)
put(MmsSmsColumns.READ, if (unread) 0 else 1)
put(MmsTable.DATE_RECEIVED, receivedTimestampMillis)
- put(MmsSmsColumns.SUBSCRIPTION_ID, message.subscriptionId)
+ put(MmsSmsColumns.SMS_SUBSCRIPTION_ID, message.subscriptionId)
put(MmsSmsColumns.EXPIRES_IN, message.expiresIn)
put(MmsTable.VIEW_ONCE, message.isViewOnce)
put(MmsSmsColumns.RECIPIENT_ID, recipientId.serialize())
@@ -93,7 +93,6 @@ object TestMms {
put(MmsTable.STORY_TYPE, message.storyType.code)
put(MmsSmsColumns.BODY, body)
- put(MmsTable.PART_COUNT, 0)
put(MmsTable.MENTIONS_SELF, 0)
}
@@ -106,7 +105,6 @@ object TestMms {
values.putNull(MmsSmsColumns.BODY)
values.putNull(MmsTable.QUOTE_BODY)
values.putNull(MmsTable.QUOTE_AUTHOR)
- values.putNull(MmsTable.QUOTE_ATTACHMENT)
values.put(MmsTable.QUOTE_TYPE, -1)
values.putNull(MmsTable.QUOTE_ID)
values.putNull(MmsTable.LINK_PREVIEWS)
diff --git a/app/src/test/java/org/thoughtcrime/securesms/database/TestSms.kt b/app/src/test/java/org/thoughtcrime/securesms/database/TestSms.kt
index fa0a470f8c..566d42befc 100644
--- a/app/src/test/java/org/thoughtcrime/securesms/database/TestSms.kt
+++ b/app/src/test/java/org/thoughtcrime/securesms/database/TestSms.kt
@@ -1,7 +1,6 @@
package org.thoughtcrime.securesms.database
import android.content.ContentValues
-import android.text.TextUtils
import org.thoughtcrime.securesms.groups.GroupId
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.sms.IncomingTextMessage
@@ -61,22 +60,14 @@ object TestSms {
): Long {
val values = ContentValues().apply {
put(MmsSmsColumns.RECIPIENT_ID, message.sender.serialize())
- put(MmsSmsColumns.ADDRESS_DEVICE_ID, message.senderDeviceId)
+ put(MmsSmsColumns.RECIPIENT_DEVICE_ID, message.senderDeviceId)
put(SmsTable.DATE_RECEIVED, message.receivedTimestampMillis)
put(SmsTable.DATE_SENT, message.sentTimestampMillis)
put(MmsSmsColumns.DATE_SERVER, message.serverTimestampMillis)
- put(SmsTable.PROTOCOL, message.protocol)
put(MmsSmsColumns.READ, if (unread) 0 else 1)
- put(MmsSmsColumns.SUBSCRIPTION_ID, message.subscriptionId)
+ put(MmsSmsColumns.SMS_SUBSCRIPTION_ID, message.subscriptionId)
put(MmsSmsColumns.EXPIRES_IN, message.expiresIn)
put(MmsSmsColumns.UNIDENTIFIED, message.isUnidentified)
-
- if (!TextUtils.isEmpty(message.pseudoSubject)) {
- put(SmsTable.SUBJECT, message.pseudoSubject)
- }
-
- put(SmsTable.REPLY_PATH_PRESENT, message.isReplyPathPresent)
- put(SmsTable.SERVICE_CENTER, message.serviceCenterAddress)
put(MmsSmsColumns.BODY, message.messageBody)
put(SmsTable.TYPE, type)
put(MmsSmsColumns.THREAD_ID, threadId)
diff --git a/core-util/src/main/java/org/signal/core/util/SQLiteDatabaseExtensions.kt b/core-util/src/main/java/org/signal/core/util/SQLiteDatabaseExtensions.kt
index b45e15751c..c7140e1b77 100644
--- a/core-util/src/main/java/org/signal/core/util/SQLiteDatabaseExtensions.kt
+++ b/core-util/src/main/java/org/signal/core/util/SQLiteDatabaseExtensions.kt
@@ -6,6 +6,7 @@ import android.database.sqlite.SQLiteDatabase
import androidx.core.content.contentValuesOf
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.sqlite.db.SupportSQLiteQueryBuilder
+import org.intellij.lang.annotations.Language
/**
* Begins a transaction on the `this` database, runs the provided [block] providing the `this` value as it's argument
@@ -85,7 +86,7 @@ class SelectBuilderPart2(
private val columns: Array,
private val tableName: String
) {
- fun where(where: String, vararg whereArgs: Any): SelectBuilderPart3 {
+ fun where(@Language("sql") where: String, vararg whereArgs: Any): SelectBuilderPart3 {
return SelectBuilderPart3(db, columns, tableName, where, SqlUtil.buildArgs(*whereArgs))
}
@@ -213,7 +214,7 @@ class UpdateBuilderPart2(
private val tableName: String,
private val values: ContentValues
) {
- fun where(where: String, vararg whereArgs: Any): UpdateBuilderPart3 {
+ fun where(@Language("sql") where: String, vararg whereArgs: Any): UpdateBuilderPart3 {
return UpdateBuilderPart3(db, tableName, values, where, SqlUtil.buildArgs(*whereArgs))
}
@@ -239,7 +240,7 @@ class DeleteBuilderPart1(
private val db: SupportSQLiteDatabase,
private val tableName: String
) {
- fun where(where: String, vararg whereArgs: Any): DeleteBuilderPart2 {
+ fun where(@Language("sql") where: String, vararg whereArgs: Any): DeleteBuilderPart2 {
return DeleteBuilderPart2(db, tableName, where, SqlUtil.buildArgs(*whereArgs))
}