2015-01-15 21:35:35 +00:00
|
|
|
package org.thoughtcrime.securesms.database;
|
|
|
|
|
|
|
|
import android.content.ContentValues;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.database.Cursor;
|
|
|
|
import android.database.sqlite.SQLiteDatabase;
|
|
|
|
import android.database.sqlite.SQLiteOpenHelper;
|
|
|
|
import android.text.TextUtils;
|
|
|
|
import android.util.Log;
|
|
|
|
|
|
|
|
import org.thoughtcrime.securesms.database.documents.Document;
|
|
|
|
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
|
|
|
|
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchList;
|
|
|
|
import org.thoughtcrime.securesms.util.JsonUtils;
|
2016-03-23 17:34:41 +00:00
|
|
|
import org.whispersystems.libsignal.IdentityKey;
|
2015-01-15 21:35:35 +00:00
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.LinkedList;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
public abstract class MessagingDatabase extends Database implements MmsSmsColumns {
|
|
|
|
|
|
|
|
private static final String TAG = MessagingDatabase.class.getSimpleName();
|
|
|
|
|
|
|
|
public MessagingDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
|
|
|
super(context, databaseHelper);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected abstract String getTableName();
|
|
|
|
|
2015-05-26 20:12:11 +00:00
|
|
|
public void setMismatchedIdentity(long messageId, final long recipientId, final IdentityKey identityKey) {
|
|
|
|
List<IdentityKeyMismatch> items = new ArrayList<IdentityKeyMismatch>() {{
|
|
|
|
add(new IdentityKeyMismatch(recipientId, identityKey));
|
|
|
|
}};
|
|
|
|
|
|
|
|
IdentityKeyMismatchList document = new IdentityKeyMismatchList(items);
|
|
|
|
|
|
|
|
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
|
|
|
database.beginTransaction();
|
|
|
|
|
|
|
|
try {
|
|
|
|
setDocument(database, messageId, MISMATCHED_IDENTITIES, document);
|
|
|
|
|
|
|
|
database.setTransactionSuccessful();
|
|
|
|
} catch (IOException ioe) {
|
|
|
|
Log.w(TAG, ioe);
|
|
|
|
} finally {
|
|
|
|
database.endTransaction();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-15 21:35:35 +00:00
|
|
|
public void addMismatchedIdentity(long messageId, long recipientId, IdentityKey identityKey) {
|
|
|
|
try {
|
|
|
|
addToDocument(messageId, MISMATCHED_IDENTITIES,
|
|
|
|
new IdentityKeyMismatch(recipientId, identityKey),
|
|
|
|
IdentityKeyMismatchList.class);
|
|
|
|
} catch (IOException e) {
|
|
|
|
Log.w(TAG, e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void removeMismatchedIdentity(long messageId, long recipientId, IdentityKey identityKey) {
|
|
|
|
try {
|
|
|
|
removeFromDocument(messageId, MISMATCHED_IDENTITIES,
|
|
|
|
new IdentityKeyMismatch(recipientId, identityKey),
|
|
|
|
IdentityKeyMismatchList.class);
|
|
|
|
} catch (IOException e) {
|
|
|
|
Log.w(TAG, e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected <D extends Document<I>, I> void removeFromDocument(long messageId, String column, I object, Class<D> clazz) throws IOException {
|
|
|
|
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
|
|
|
database.beginTransaction();
|
|
|
|
|
|
|
|
try {
|
|
|
|
D document = getDocument(database, messageId, column, clazz);
|
|
|
|
Iterator<I> iterator = document.getList().iterator();
|
|
|
|
|
|
|
|
while (iterator.hasNext()) {
|
|
|
|
I item = iterator.next();
|
|
|
|
|
|
|
|
if (item.equals(object)) {
|
|
|
|
iterator.remove();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setDocument(database, messageId, column, document);
|
|
|
|
database.setTransactionSuccessful();
|
|
|
|
} finally {
|
|
|
|
database.endTransaction();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected <T extends Document<I>, I> void addToDocument(long messageId, String column, final I object, Class<T> clazz) throws IOException {
|
|
|
|
List<I> list = new ArrayList<I>() {{
|
|
|
|
add(object);
|
|
|
|
}};
|
|
|
|
|
|
|
|
addToDocument(messageId, column, list, clazz);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected <T extends Document<I>, I> void addToDocument(long messageId, String column, List<I> objects, Class<T> clazz) throws IOException {
|
|
|
|
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
|
|
|
database.beginTransaction();
|
|
|
|
|
|
|
|
try {
|
|
|
|
T document = getDocument(database, messageId, column, clazz);
|
|
|
|
document.getList().addAll(objects);
|
|
|
|
setDocument(database, messageId, column, document);
|
|
|
|
|
|
|
|
database.setTransactionSuccessful();
|
|
|
|
} finally {
|
|
|
|
database.endTransaction();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void setDocument(SQLiteDatabase database, long messageId, String column, Document document) throws IOException {
|
|
|
|
ContentValues contentValues = new ContentValues();
|
|
|
|
|
|
|
|
if (document == null || document.size() == 0) {
|
|
|
|
contentValues.put(column, (String)null);
|
|
|
|
} else {
|
|
|
|
contentValues.put(column, JsonUtils.toJson(document));
|
|
|
|
}
|
|
|
|
|
|
|
|
database.update(getTableName(), contentValues, ID_WHERE, new String[] {String.valueOf(messageId)});
|
|
|
|
}
|
|
|
|
|
|
|
|
private <D extends Document> D getDocument(SQLiteDatabase database, long messageId,
|
|
|
|
String column, Class<D> clazz)
|
|
|
|
{
|
|
|
|
Cursor cursor = null;
|
|
|
|
|
|
|
|
try {
|
|
|
|
cursor = database.query(getTableName(), new String[] {column},
|
|
|
|
ID_WHERE, new String[] {String.valueOf(messageId)},
|
|
|
|
null, null, null);
|
|
|
|
|
|
|
|
if (cursor != null && cursor.moveToNext()) {
|
|
|
|
String document = cursor.getString(cursor.getColumnIndexOrThrow(column));
|
|
|
|
|
|
|
|
try {
|
|
|
|
if (!TextUtils.isEmpty(document)) {
|
|
|
|
return JsonUtils.fromJson(document, clazz);
|
|
|
|
}
|
|
|
|
} catch (IOException e) {
|
|
|
|
Log.w(TAG, e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
return clazz.newInstance();
|
2015-05-26 20:12:11 +00:00
|
|
|
} catch (InstantiationException e) {
|
|
|
|
throw new AssertionError(e);
|
|
|
|
} catch (IllegalAccessException e) {
|
2015-01-15 21:35:35 +00:00
|
|
|
throw new AssertionError(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
if (cursor != null)
|
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
}
|
2016-02-20 01:07:41 +00:00
|
|
|
|
|
|
|
public static class SyncMessageId {
|
|
|
|
|
|
|
|
private final String address;
|
|
|
|
private final long timetamp;
|
|
|
|
|
|
|
|
public SyncMessageId(String address, long timetamp) {
|
|
|
|
this.address = address;
|
|
|
|
this.timetamp = timetamp;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getAddress() {
|
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
|
|
|
public long getTimetamp() {
|
|
|
|
return timetamp;
|
|
|
|
}
|
|
|
|
}
|
2015-01-15 21:35:35 +00:00
|
|
|
}
|