mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 09:49:30 +01:00
Fix out-of-sync local state after rejoining a group via invite link.
This commit is contained in:
committed by
Greyson Parrelli
parent
3895578d51
commit
26709177d2
@@ -69,24 +69,25 @@ public class GroupDatabase extends Database implements RecipientIdDatabaseRefere
|
||||
|
||||
private static final String TAG = Log.tag(GroupDatabase.class);
|
||||
|
||||
static final String TABLE_NAME = "groups";
|
||||
private static final String ID = "_id";
|
||||
static final String GROUP_ID = "group_id";
|
||||
public static final String RECIPIENT_ID = "recipient_id";
|
||||
private static final String TITLE = "title";
|
||||
static final String MEMBERS = "members";
|
||||
private static final String AVATAR_ID = "avatar_id";
|
||||
private static final String AVATAR_KEY = "avatar_key";
|
||||
private static final String AVATAR_CONTENT_TYPE = "avatar_content_type";
|
||||
private static final String AVATAR_RELAY = "avatar_relay";
|
||||
private static final String AVATAR_DIGEST = "avatar_digest";
|
||||
private static final String TIMESTAMP = "timestamp";
|
||||
static final String ACTIVE = "active";
|
||||
static final String MMS = "mms";
|
||||
private static final String EXPECTED_V2_ID = "expected_v2_id";
|
||||
private static final String UNMIGRATED_V1_MEMBERS = "former_v1_members";
|
||||
private static final String DISTRIBUTION_ID = "distribution_id";
|
||||
private static final String SHOW_AS_STORY_STATE = "display_as_story";
|
||||
static final String TABLE_NAME = "groups";
|
||||
private static final String ID = "_id";
|
||||
static final String GROUP_ID = "group_id";
|
||||
public static final String RECIPIENT_ID = "recipient_id";
|
||||
private static final String TITLE = "title";
|
||||
static final String MEMBERS = "members";
|
||||
private static final String AVATAR_ID = "avatar_id";
|
||||
private static final String AVATAR_KEY = "avatar_key";
|
||||
private static final String AVATAR_CONTENT_TYPE = "avatar_content_type";
|
||||
private static final String AVATAR_RELAY = "avatar_relay";
|
||||
private static final String AVATAR_DIGEST = "avatar_digest";
|
||||
private static final String TIMESTAMP = "timestamp";
|
||||
static final String ACTIVE = "active";
|
||||
static final String MMS = "mms";
|
||||
private static final String EXPECTED_V2_ID = "expected_v2_id";
|
||||
private static final String UNMIGRATED_V1_MEMBERS = "former_v1_members";
|
||||
private static final String DISTRIBUTION_ID = "distribution_id";
|
||||
private static final String SHOW_AS_STORY_STATE = "display_as_story";
|
||||
private static final String LAST_FORCE_UPDATE_TIMESTAMP = "last_force_update_timestamp";
|
||||
|
||||
/** Was temporarily used for PNP accept by pni but is no longer needed/updated */
|
||||
@Deprecated
|
||||
@@ -101,27 +102,28 @@ public class GroupDatabase extends Database implements RecipientIdDatabaseRefere
|
||||
/** Serialized {@link DecryptedGroup} protobuf */
|
||||
public static final String V2_DECRYPTED_GROUP = "decrypted_group";
|
||||
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " +
|
||||
GROUP_ID + " TEXT, " +
|
||||
RECIPIENT_ID + " INTEGER, " +
|
||||
TITLE + " TEXT, " +
|
||||
MEMBERS + " TEXT, " +
|
||||
AVATAR_ID + " INTEGER, " +
|
||||
AVATAR_KEY + " BLOB, " +
|
||||
AVATAR_CONTENT_TYPE + " TEXT, " +
|
||||
AVATAR_RELAY + " TEXT, " +
|
||||
TIMESTAMP + " INTEGER, " +
|
||||
ACTIVE + " INTEGER DEFAULT 1, " +
|
||||
AVATAR_DIGEST + " BLOB, " +
|
||||
MMS + " INTEGER DEFAULT 0, " +
|
||||
V2_MASTER_KEY + " BLOB, " +
|
||||
V2_REVISION + " BLOB, " +
|
||||
V2_DECRYPTED_GROUP + " BLOB, " +
|
||||
EXPECTED_V2_ID + " TEXT DEFAULT NULL, " +
|
||||
UNMIGRATED_V1_MEMBERS + " TEXT DEFAULT NULL, " +
|
||||
DISTRIBUTION_ID + " TEXT DEFAULT NULL, " +
|
||||
SHOW_AS_STORY_STATE + " INTEGER DEFAULT 0, " +
|
||||
AUTH_SERVICE_ID + " TEXT DEFAULT NULL);";
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " +
|
||||
GROUP_ID + " TEXT, " +
|
||||
RECIPIENT_ID + " INTEGER, " +
|
||||
TITLE + " TEXT, " +
|
||||
MEMBERS + " TEXT, " +
|
||||
AVATAR_ID + " INTEGER, " +
|
||||
AVATAR_KEY + " BLOB, " +
|
||||
AVATAR_CONTENT_TYPE + " TEXT, " +
|
||||
AVATAR_RELAY + " TEXT, " +
|
||||
TIMESTAMP + " INTEGER, " +
|
||||
ACTIVE + " INTEGER DEFAULT 1, " +
|
||||
AVATAR_DIGEST + " BLOB, " +
|
||||
MMS + " INTEGER DEFAULT 0, " +
|
||||
V2_MASTER_KEY + " BLOB, " +
|
||||
V2_REVISION + " BLOB, " +
|
||||
V2_DECRYPTED_GROUP + " BLOB, " +
|
||||
EXPECTED_V2_ID + " TEXT DEFAULT NULL, " +
|
||||
UNMIGRATED_V1_MEMBERS + " TEXT DEFAULT NULL, " +
|
||||
DISTRIBUTION_ID + " TEXT DEFAULT NULL, " +
|
||||
SHOW_AS_STORY_STATE + " INTEGER DEFAULT 0, " +
|
||||
AUTH_SERVICE_ID + " TEXT DEFAULT NULL, " +
|
||||
LAST_FORCE_UPDATE_TIMESTAMP + " INTEGER DEFAULT 0);";
|
||||
|
||||
public static final String[] CREATE_INDEXS = {
|
||||
"CREATE UNIQUE INDEX IF NOT EXISTS group_id_index ON " + TABLE_NAME + " (" + GROUP_ID + ");",
|
||||
@@ -132,7 +134,7 @@ public class GroupDatabase extends Database implements RecipientIdDatabaseRefere
|
||||
|
||||
private static final String[] GROUP_PROJECTION = {
|
||||
GROUP_ID, RECIPIENT_ID, TITLE, MEMBERS, UNMIGRATED_V1_MEMBERS, AVATAR_ID, AVATAR_KEY, AVATAR_CONTENT_TYPE, AVATAR_RELAY, AVATAR_DIGEST,
|
||||
TIMESTAMP, ACTIVE, MMS, V2_MASTER_KEY, V2_REVISION, V2_DECRYPTED_GROUP
|
||||
TIMESTAMP, ACTIVE, MMS, V2_MASTER_KEY, V2_REVISION, V2_DECRYPTED_GROUP, LAST_FORCE_UPDATE_TIMESTAMP
|
||||
};
|
||||
|
||||
static final List<String> TYPED_GROUP_PROJECTION = Stream.of(GROUP_PROJECTION).map(columnName -> TABLE_NAME + "." + columnName).toList();
|
||||
@@ -955,6 +957,12 @@ public class GroupDatabase extends Database implements RecipientIdDatabaseRefere
|
||||
database.update(TABLE_NAME, values, GROUP_ID + " = ?", new String[] {groupId.toString()});
|
||||
}
|
||||
|
||||
public void setLastForceUpdateTimestamp(@NonNull GroupId groupId, long timestamp) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(LAST_FORCE_UPDATE_TIMESTAMP, timestamp);
|
||||
getWritableDatabase().update(TABLE_NAME, values, GROUP_ID + " = ?", SqlUtil.buildArgs(groupId));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public boolean isCurrentMember(@NonNull GroupId.Push groupId, @NonNull RecipientId recipientId) {
|
||||
SQLiteDatabase database = databaseHelper.getSignalReadableDatabase();
|
||||
@@ -1114,7 +1122,8 @@ public class GroupDatabase extends Database implements RecipientIdDatabaseRefere
|
||||
CursorUtil.requireBlob(cursor, V2_MASTER_KEY),
|
||||
CursorUtil.requireInt(cursor, V2_REVISION),
|
||||
CursorUtil.requireBlob(cursor, V2_DECRYPTED_GROUP),
|
||||
CursorUtil.getString(cursor, DISTRIBUTION_ID).map(DistributionId::from).orElse(null));
|
||||
CursorUtil.getString(cursor, DISTRIBUTION_ID).map(DistributionId::from).orElse(null),
|
||||
CursorUtil.requireLong(cursor, LAST_FORCE_UPDATE_TIMESTAMP));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1155,6 +1164,7 @@ public class GroupDatabase extends Database implements RecipientIdDatabaseRefere
|
||||
private final boolean mms;
|
||||
@Nullable private final V2GroupProperties v2GroupProperties;
|
||||
private final DistributionId distributionId;
|
||||
private final long lastForceUpdateTimestamp;
|
||||
|
||||
public GroupRecord(@NonNull GroupId id,
|
||||
@NonNull RecipientId recipientId,
|
||||
@@ -1171,19 +1181,21 @@ public class GroupDatabase extends Database implements RecipientIdDatabaseRefere
|
||||
@Nullable byte[] groupMasterKeyBytes,
|
||||
int groupRevision,
|
||||
@Nullable byte[] decryptedGroupBytes,
|
||||
@Nullable DistributionId distributionId)
|
||||
@Nullable DistributionId distributionId,
|
||||
long lastForceUpdateTimestamp)
|
||||
{
|
||||
this.id = id;
|
||||
this.recipientId = recipientId;
|
||||
this.title = title;
|
||||
this.avatarId = avatarId;
|
||||
this.avatarKey = avatarKey;
|
||||
this.avatarDigest = avatarDigest;
|
||||
this.avatarContentType = avatarContentType;
|
||||
this.relay = relay;
|
||||
this.active = active;
|
||||
this.mms = mms;
|
||||
this.distributionId = distributionId;
|
||||
this.id = id;
|
||||
this.recipientId = recipientId;
|
||||
this.title = title;
|
||||
this.avatarId = avatarId;
|
||||
this.avatarKey = avatarKey;
|
||||
this.avatarDigest = avatarDigest;
|
||||
this.avatarContentType = avatarContentType;
|
||||
this.relay = relay;
|
||||
this.active = active;
|
||||
this.mms = mms;
|
||||
this.distributionId = distributionId;
|
||||
this.lastForceUpdateTimestamp = lastForceUpdateTimestamp;
|
||||
|
||||
V2GroupProperties v2GroupProperties = null;
|
||||
if (groupMasterKeyBytes != null && decryptedGroupBytes != null) {
|
||||
@@ -1292,6 +1304,10 @@ public class GroupDatabase extends Database implements RecipientIdDatabaseRefere
|
||||
return distributionId;
|
||||
}
|
||||
|
||||
public long getLastForceUpdateTimestamp() {
|
||||
return lastForceUpdateTimestamp;
|
||||
}
|
||||
|
||||
public boolean isV1Group() {
|
||||
return !mms && !isV2Group();
|
||||
}
|
||||
|
||||
@@ -12,13 +12,14 @@ import org.thoughtcrime.securesms.database.helpers.migration.V154_PniSignaturesM
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V155_SmsExporterMigration
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V156_RecipientUnregisteredTimestampMigration
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V157_RecipeintHiddenMigration
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V158_GroupsLastForceUpdateTimestampMigration
|
||||
|
||||
/**
|
||||
* Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness.
|
||||
*/
|
||||
object SignalDatabaseMigrations {
|
||||
|
||||
const val DATABASE_VERSION = 157
|
||||
const val DATABASE_VERSION = 158
|
||||
|
||||
@JvmStatic
|
||||
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
@@ -57,6 +58,10 @@ object SignalDatabaseMigrations {
|
||||
if (oldVersion < 157) {
|
||||
V157_RecipeintHiddenMigration.migrate(context, db, oldVersion, newVersion)
|
||||
}
|
||||
|
||||
if (oldVersion < 158) {
|
||||
V158_GroupsLastForceUpdateTimestampMigration.migrate(context, db, oldVersion, newVersion)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.thoughtcrime.securesms.database.helpers.migration
|
||||
|
||||
import android.app.Application
|
||||
import net.zetetic.database.sqlcipher.SQLiteDatabase
|
||||
|
||||
/**
|
||||
* Track last time we did a forced sanity check for this group with the server.
|
||||
*/
|
||||
object V158_GroupsLastForceUpdateTimestampMigration : SignalDatabaseMigration {
|
||||
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
db.execSQL("ALTER TABLE groups ADD COLUMN last_force_update_timestamp INTEGER DEFAULT 0")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user