kopia lustrzana https://github.com/ryukoposting/Signal-Android
Convert SenderKeySharedTable to kotlin.
rodzic
79ec76f11f
commit
98980b8192
|
@ -1,170 +0,0 @@
|
|||
package org.thoughtcrime.securesms.database;
|
||||
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.libsignal.protocol.SignalProtocolAddress;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.signal.core.util.CursorUtil;
|
||||
import org.signal.core.util.SqlUtil;
|
||||
import org.whispersystems.signalservice.api.push.DistributionId;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Keeps track of which recipients are aware of which distributionIds. For the storage of sender
|
||||
* keys themselves, see {@link SenderKeyTable}.
|
||||
*/
|
||||
public class SenderKeySharedTable extends DatabaseTable {
|
||||
|
||||
private static final String TAG = Log.tag(SenderKeySharedTable.class);
|
||||
|
||||
public static final String TABLE_NAME = "sender_key_shared";
|
||||
|
||||
private static final String ID = "_id";
|
||||
public static final String DISTRIBUTION_ID = "distribution_id";
|
||||
public static final String ADDRESS = "address";
|
||||
public static final String DEVICE = "device";
|
||||
public static final String TIMESTAMP = "timestamp";
|
||||
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
|
||||
DISTRIBUTION_ID + " TEXT NOT NULL, " +
|
||||
ADDRESS + " TEXT NOT NULL, " +
|
||||
DEVICE + " INTEGER NOT NULL, " +
|
||||
TIMESTAMP + " INTEGER DEFAULT 0, " +
|
||||
"UNIQUE(" + DISTRIBUTION_ID + "," + ADDRESS + ", " + DEVICE + ") ON CONFLICT REPLACE);";
|
||||
|
||||
SenderKeySharedTable(Context context, SignalDatabase databaseHelper) {
|
||||
super(context, databaseHelper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark that a distributionId has been shared with the provided recipients
|
||||
*/
|
||||
public void markAsShared(@NonNull DistributionId distributionId, @NonNull Collection<SignalProtocolAddress> addresses) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
|
||||
db.beginTransaction();
|
||||
try {
|
||||
for (SignalProtocolAddress address : addresses) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(ADDRESS, address.getName());
|
||||
values.put(DEVICE, address.getDeviceId());
|
||||
values.put(DISTRIBUTION_ID, distributionId.toString());
|
||||
values.put(TIMESTAMP, System.currentTimeMillis());
|
||||
|
||||
db.insertWithOnConflict(TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the set of recipientIds that know about the distributionId in question.
|
||||
*/
|
||||
public @NonNull Set<SignalProtocolAddress> getSharedWith(@NonNull DistributionId distributionId) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
String query = DISTRIBUTION_ID + " = ?";
|
||||
String[] args = SqlUtil.buildArgs(distributionId);
|
||||
|
||||
Set<SignalProtocolAddress> addresses = new HashSet<>();
|
||||
|
||||
try (Cursor cursor = db.query(TABLE_NAME, new String[]{ ADDRESS, DEVICE }, query, args, null, null, null)) {
|
||||
while (cursor.moveToNext()) {
|
||||
String address = CursorUtil.requireString(cursor, ADDRESS);
|
||||
int device = CursorUtil.requireInt(cursor, DEVICE);
|
||||
|
||||
addresses.add(new SignalProtocolAddress(address, device));
|
||||
}
|
||||
}
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the shared statuses for all provided addresses.
|
||||
*/
|
||||
public void delete(@NonNull DistributionId distributionId, @NonNull Collection<SignalProtocolAddress> addresses) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
String query = DISTRIBUTION_ID + " = ? AND " + ADDRESS + " = ? AND " + DEVICE + " = ?";
|
||||
|
||||
db.beginTransaction();
|
||||
try {
|
||||
for (SignalProtocolAddress address : addresses) {
|
||||
db.delete(TABLE_NAME, query, SqlUtil.buildArgs(distributionId, address.getName(), address.getDeviceId()));
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all shared statuses for a given distributionId.
|
||||
*/
|
||||
public void deleteAllFor(@NonNull DistributionId distributionId) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
db.delete(TABLE_NAME, DISTRIBUTION_ID + " = ?", SqlUtil.buildArgs(distributionId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the shared status for all distributionIds for a set of addresses.
|
||||
*/
|
||||
public void deleteAllFor(@NonNull Collection<SignalProtocolAddress> addresses) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
String query = ADDRESS + " = ? AND " + DEVICE + " = ?";
|
||||
|
||||
db.beginTransaction();
|
||||
try {
|
||||
for (SignalProtocolAddress address : addresses) {
|
||||
db.delete(TABLE_NAME, query, SqlUtil.buildArgs(address.getName(), address.getDeviceId()));
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the shared status for all distributionIds for a given recipientId.
|
||||
*/
|
||||
public void deleteAllFor(@NonNull RecipientId recipientId) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
|
||||
if (recipient.hasServiceId()) {
|
||||
db.delete(TABLE_NAME, ADDRESS + " = ?", SqlUtil.buildArgs(recipient.requireServiceId().toString()));
|
||||
} else {
|
||||
Log.w(TAG, "Recipient doesn't have a UUID! " + recipientId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all database content.
|
||||
*/
|
||||
public void deleteAll() {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
db.delete(TABLE_NAME, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the shared state of all of our sender keys. Used for debugging.
|
||||
*/
|
||||
public Cursor getAllSharedWithCursor() {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
return db.query(TABLE_NAME, null, null, null, null, null, DISTRIBUTION_ID + ", " + ADDRESS + ", " + DEVICE);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
package org.thoughtcrime.securesms.database
|
||||
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import androidx.core.content.contentValuesOf
|
||||
import org.signal.core.util.delete
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.readToSet
|
||||
import org.signal.core.util.requireInt
|
||||
import org.signal.core.util.requireString
|
||||
import org.signal.core.util.select
|
||||
import org.signal.core.util.withinTransaction
|
||||
import org.signal.libsignal.protocol.SignalProtocolAddress
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.whispersystems.signalservice.api.push.DistributionId
|
||||
|
||||
/**
|
||||
* Keeps track of which recipients are aware of which distributionIds. For the storage of sender
|
||||
* keys themselves, see [SenderKeyTable].
|
||||
*/
|
||||
class SenderKeySharedTable internal constructor(context: Context?, databaseHelper: SignalDatabase?) : DatabaseTable(context, databaseHelper) {
|
||||
companion object {
|
||||
private val TAG = Log.tag(SenderKeySharedTable::class.java)
|
||||
const val TABLE_NAME = "sender_key_shared"
|
||||
private const val ID = "_id"
|
||||
const val DISTRIBUTION_ID = "distribution_id"
|
||||
const val ADDRESS = "address"
|
||||
const val DEVICE = "device"
|
||||
const val TIMESTAMP = "timestamp"
|
||||
const val CREATE_TABLE = """
|
||||
CREATE TABLE $TABLE_NAME (
|
||||
$ID INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
$DISTRIBUTION_ID TEXT NOT NULL,
|
||||
$ADDRESS TEXT NOT NULL,
|
||||
$DEVICE INTEGER NOT NULL,
|
||||
$TIMESTAMP INTEGER DEFAULT 0,
|
||||
UNIQUE($DISTRIBUTION_ID,$ADDRESS, $DEVICE) ON CONFLICT REPLACE
|
||||
)
|
||||
"""
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark that a distributionId has been shared with the provided recipients
|
||||
*/
|
||||
fun markAsShared(distributionId: DistributionId, addresses: Collection<SignalProtocolAddress>) {
|
||||
writableDatabase.withinTransaction { db ->
|
||||
for (address in addresses) {
|
||||
val values = contentValuesOf(
|
||||
ADDRESS to address.name,
|
||||
DEVICE to address.deviceId,
|
||||
DISTRIBUTION_ID to distributionId.toString(),
|
||||
TIMESTAMP to System.currentTimeMillis(),
|
||||
)
|
||||
db.insertWithOnConflict(TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the set of recipientIds that know about the distributionId in question.
|
||||
*/
|
||||
fun getSharedWith(distributionId: DistributionId): Set<SignalProtocolAddress> {
|
||||
return readableDatabase
|
||||
.select(ADDRESS, DEVICE)
|
||||
.from(TABLE_NAME)
|
||||
.where("$DISTRIBUTION_ID = ?", distributionId)
|
||||
.run()
|
||||
.readToSet { cursor ->
|
||||
SignalProtocolAddress(
|
||||
cursor.requireString(ADDRESS),
|
||||
cursor.requireInt(DEVICE)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the shared statuses for all provided addresses.
|
||||
*/
|
||||
fun delete(distributionId: DistributionId, addresses: Collection<SignalProtocolAddress>) {
|
||||
writableDatabase.withinTransaction { db ->
|
||||
for (address in addresses) {
|
||||
db.delete(TABLE_NAME)
|
||||
.where("$DISTRIBUTION_ID = ? AND $ADDRESS = ? AND $DEVICE = ?", distributionId, address.name, address.deviceId)
|
||||
.run()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all shared statuses for a given distributionId.
|
||||
*/
|
||||
fun deleteAllFor(distributionId: DistributionId) {
|
||||
writableDatabase
|
||||
.delete(TABLE_NAME)
|
||||
.where("$DISTRIBUTION_ID = ?", distributionId)
|
||||
.run()
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the shared status for all distributionIds for a set of addresses.
|
||||
*/
|
||||
fun deleteAllFor(addresses: Collection<SignalProtocolAddress>) {
|
||||
writableDatabase.withinTransaction { db ->
|
||||
for (address in addresses) {
|
||||
db.delete(TABLE_NAME)
|
||||
.where("$ADDRESS = ? AND $DEVICE = ?", address.name, address.deviceId)
|
||||
.run()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the shared status for all distributionIds for a given recipientId.
|
||||
*/
|
||||
fun deleteAllFor(recipientId: RecipientId) {
|
||||
val recipient = Recipient.resolved(recipientId)
|
||||
if (recipient.hasServiceId()) {
|
||||
writableDatabase
|
||||
.delete(TABLE_NAME)
|
||||
.where("$ADDRESS = ?", recipient.requireServiceId().toString())
|
||||
.run()
|
||||
} else {
|
||||
Log.w(TAG, "Recipient doesn't have a UUID! $recipientId")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all database content.
|
||||
*/
|
||||
fun deleteAll() {
|
||||
writableDatabase
|
||||
.delete(TABLE_NAME)
|
||||
.run()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the shared state of all of our sender keys. Used for debugging.
|
||||
*/
|
||||
fun getAllSharedWithCursor(): Cursor {
|
||||
return readableDatabase.query(TABLE_NAME, null, null, null, null, null, "$DISTRIBUTION_ID, $ADDRESS, $DEVICE")
|
||||
}
|
||||
}
|
Ładowanie…
Reference in New Issue