mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 12:05:22 +00:00
add new contact database api
This commit is contained in:
parent
cbd6ae3bcb
commit
a16e67d1fd
@ -34,6 +34,7 @@ import org.thoughtcrime.securesms.loki.database.LokiMessageDatabase;
|
||||
import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase;
|
||||
import org.thoughtcrime.securesms.loki.database.LokiUserDatabase;
|
||||
import org.thoughtcrime.securesms.loki.database.SessionJobDatabase;
|
||||
import org.thoughtcrime.securesms.loki.database.SessionContactDatabase;
|
||||
|
||||
public class DatabaseFactory {
|
||||
|
||||
@ -63,6 +64,7 @@ public class DatabaseFactory {
|
||||
private final LokiUserDatabase lokiUserDatabase;
|
||||
private final LokiBackupFilesDatabase lokiBackupFilesDatabase;
|
||||
private final SessionJobDatabase sessionJobDatabase;
|
||||
private final SessionContactDatabase sessionContactDatabase;
|
||||
|
||||
// Refactor
|
||||
private final Storage storage;
|
||||
@ -157,6 +159,10 @@ public class DatabaseFactory {
|
||||
public static SessionJobDatabase getSessionJobDatabase(Context context) {
|
||||
return getInstance(context).sessionJobDatabase;
|
||||
}
|
||||
|
||||
public static SessionContactDatabase getSessionContactDatabase(Context context) {
|
||||
return getInstance(context).sessionContactDatabase;
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region Refactor
|
||||
@ -202,6 +208,7 @@ public class DatabaseFactory {
|
||||
this.storage = new Storage(context, databaseHelper);
|
||||
this.attachmentProvider = new DatabaseAttachmentProvider(context, databaseHelper);
|
||||
this.sessionJobDatabase = new SessionJobDatabase(context, databaseHelper);
|
||||
this.sessionContactDatabase = new SessionContactDatabase(context, databaseHelper);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import android.content.Context
|
||||
import android.net.Uri
|
||||
import okhttp3.HttpUrl
|
||||
import org.session.libsession.messaging.StorageProtocol
|
||||
import org.session.libsession.messaging.contacts.Contact
|
||||
import org.session.libsession.messaging.jobs.AttachmentUploadJob
|
||||
import org.session.libsession.messaging.jobs.Job
|
||||
import org.session.libsession.messaging.jobs.JobQueue
|
||||
@ -624,6 +625,18 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
return DatabaseFactory.getLokiUserDatabase(context).getProfilePictureURL(publicKey)
|
||||
}
|
||||
|
||||
override fun getContactWithSessionID(sessionID: String): Contact? {
|
||||
return DatabaseFactory.getSessionContactDatabase(context).getContactWithSessionID(sessionID)
|
||||
}
|
||||
|
||||
override fun getAllContacts(): Set<Contact> {
|
||||
return DatabaseFactory.getSessionContactDatabase(context).getAllContacts()
|
||||
}
|
||||
|
||||
override fun setContact(contact: Contact) {
|
||||
DatabaseFactory.getSessionContactDatabase(context).setContact(contact)
|
||||
}
|
||||
|
||||
override fun getRecipientSettings(address: Address): Recipient.RecipientSettings? {
|
||||
val recipientSettings = DatabaseFactory.getRecipientDatabase(context).getRecipientSettings(address)
|
||||
return if (recipientSettings.isPresent) { recipientSettings.get() } else null
|
||||
|
@ -28,6 +28,7 @@ import org.thoughtcrime.securesms.loki.database.LokiBackupFilesDatabase;
|
||||
import org.thoughtcrime.securesms.loki.database.LokiMessageDatabase;
|
||||
import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase;
|
||||
import org.thoughtcrime.securesms.loki.database.LokiUserDatabase;
|
||||
import org.thoughtcrime.securesms.loki.database.SessionContactDatabase;
|
||||
import org.thoughtcrime.securesms.loki.database.SessionJobDatabase;
|
||||
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsMigration;
|
||||
|
||||
@ -56,9 +57,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
private static final int lokiV22 = 43;
|
||||
private static final int lokiV23 = 44;
|
||||
private static final int lokiV24 = 45;
|
||||
private static final int lokiV25 = 46;
|
||||
|
||||
// Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes
|
||||
private static final int DATABASE_VERSION = lokiV24;
|
||||
private static final int DATABASE_VERSION = lokiV25;
|
||||
private static final String DATABASE_NAME = "signal.db";
|
||||
|
||||
private final Context context;
|
||||
@ -128,6 +130,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
db.execSQL(SessionJobDatabase.getCreateSessionJobTableCommand());
|
||||
db.execSQL(LokiMessageDatabase.getUpdateMessageIDTableForType());
|
||||
db.execSQL(LokiMessageDatabase.getUpdateMessageMappingTable());
|
||||
db.execSQL(SessionContactDatabase.getCreateSessionContactTableCommand());
|
||||
|
||||
executeStatements(db, SmsDatabase.CREATE_INDEXS);
|
||||
executeStatements(db, MmsDatabase.CREATE_INDEXS);
|
||||
@ -291,6 +294,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
db.execSQL(LokiAPIDatabase.getCreateSwarmTableCommand());
|
||||
}
|
||||
|
||||
if (oldVersion < lokiV25) {
|
||||
db.execSQL(SessionContactDatabase.getCreateSessionContactTableCommand());
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
|
@ -0,0 +1,76 @@
|
||||
package org.thoughtcrime.securesms.loki.database
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import net.sqlcipher.Cursor
|
||||
import org.session.libsession.messaging.contacts.Contact
|
||||
import org.session.libsession.messaging.jobs.Job
|
||||
import org.session.libsignal.utilities.Base64
|
||||
import org.thoughtcrime.securesms.database.Database
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
|
||||
import org.thoughtcrime.securesms.loki.utilities.*
|
||||
|
||||
class SessionContactDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper) {
|
||||
companion object {
|
||||
private const val sessionContactTable = "session_contact_database"
|
||||
const val sessionID = "session_id"
|
||||
const val name = "name"
|
||||
const val nickname = "nickname"
|
||||
const val profilePictureURL = "profile_picture_url"
|
||||
const val profilePictureFileName = "profile_picture_file_name"
|
||||
const val profilePictureEncryptionKey = "profile_picture_encryption_key"
|
||||
const val threadID = "thread_id"
|
||||
const val isTrusted = "is_trusted"
|
||||
@JvmStatic val createSessionContactTableCommand =
|
||||
"CREATE TABLE $sessionContactTable " +
|
||||
"($sessionID STRING PRIMARY KEY, " +
|
||||
"$name TEXT DEFAULT NULL, " +
|
||||
"$nickname TEXT DEFAULT NULL, " +
|
||||
"$profilePictureURL TEXT DEFAULT NULL, " +
|
||||
"$profilePictureFileName TEXT DEFAULT NULL, " +
|
||||
"$profilePictureEncryptionKey BLOB DEFAULT NULL, " +
|
||||
"$threadID INTEGER DEFAULT -1, " +
|
||||
"$isTrusted INTEGER DEFAULT 0);"
|
||||
}
|
||||
|
||||
fun getContactWithSessionID(sessionID: String): Contact? {
|
||||
val database = databaseHelper.readableDatabase
|
||||
return database.get(sessionContactTable, "$sessionID = ?", arrayOf(sessionID)) { cursor ->
|
||||
contactFromCursor(cursor)
|
||||
}
|
||||
}
|
||||
|
||||
fun getAllContacts(): Set<Contact> {
|
||||
val database = databaseHelper.readableDatabase
|
||||
return database.getAll(sessionContactTable, null, null) { cursor ->
|
||||
contactFromCursor(cursor)
|
||||
}.toSet()
|
||||
}
|
||||
|
||||
fun setContact(contact: Contact) {
|
||||
val database = databaseHelper.writableDatabase
|
||||
val contentValues = ContentValues(8)
|
||||
contentValues.put(sessionID, contact.sessionID)
|
||||
contentValues.put(name, contact.name)
|
||||
contentValues.put(nickname, contact.nickname)
|
||||
contentValues.put(profilePictureURL, contact.profilePictureURL)
|
||||
contentValues.put(profilePictureFileName, contact.profilePictureFileName)
|
||||
contentValues.put(profilePictureEncryptionKey, Base64.encodeBytes(contact.profilePictureEncryptionKey))
|
||||
contentValues.put(threadID, threadID)
|
||||
contentValues.put(isTrusted, if (contact.isTrusted) 1 else 0)
|
||||
database.insertOrUpdate(sessionContactTable, contentValues, "$sessionID = ?", arrayOf(contact.sessionID))
|
||||
}
|
||||
|
||||
private fun contactFromCursor(cursor: Cursor): Contact {
|
||||
val sessionID = cursor.getString(sessionID)
|
||||
val contact = Contact(sessionID)
|
||||
contact.name = cursor.getString(name)
|
||||
contact.nickname = cursor.getString(nickname)
|
||||
contact.profilePictureURL = cursor.getString(profilePictureURL)
|
||||
contact.profilePictureFileName = cursor.getString(profilePictureFileName)
|
||||
contact.profilePictureEncryptionKey = Base64.decode(cursor.getString(profilePictureEncryptionKey))
|
||||
contact.threadID = cursor.getInt(threadID)
|
||||
contact.isTrusted = cursor.getInt(isTrusted) != 0
|
||||
return contact
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package org.thoughtcrime.securesms.sskenvironment
|
||||
|
||||
import android.content.Context
|
||||
import org.session.libsession.messaging.contacts.Contact
|
||||
import org.session.libsession.messaging.threads.recipients.Recipient
|
||||
import org.session.libsession.utilities.SSKEnvironment
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
@ -10,18 +11,31 @@ import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob
|
||||
class ProfileManager: SSKEnvironment.ProfileManagerProtocol {
|
||||
override fun setDisplayName(context: Context, recipient: Recipient, displayName: String) {
|
||||
val database = DatabaseFactory.getLokiUserDatabase(context)
|
||||
val publicKey = recipient.address.serialize()
|
||||
if (recipient.name == null) {
|
||||
// Migrate the profile name in LokiUserDatabase to recipient
|
||||
database.getDisplayName(publicKey)?.let { setProfileName(context, recipient, it) }
|
||||
val sessionID = recipient.address.serialize()
|
||||
database.setDisplayName(sessionID, displayName)
|
||||
// New API
|
||||
val contactDatabase = DatabaseFactory.getSessionContactDatabase(context)
|
||||
var contact = contactDatabase.getContactWithSessionID(sessionID)
|
||||
if (contact == null) contact = Contact(sessionID)
|
||||
if (contact.nickname != displayName) {
|
||||
contact.nickname = displayName
|
||||
contactDatabase.setContact(contact)
|
||||
}
|
||||
database.setDisplayName(publicKey, displayName)
|
||||
}
|
||||
|
||||
override fun setProfileName(context: Context, recipient: Recipient, profileName: String) {
|
||||
val database = DatabaseFactory.getRecipientDatabase(context)
|
||||
database.setProfileName(recipient, profileName)
|
||||
recipient.notifyListeners()
|
||||
// New API
|
||||
val sessionID = recipient.address.serialize()
|
||||
val contactDatabase = DatabaseFactory.getSessionContactDatabase(context)
|
||||
var contact = contactDatabase.getContactWithSessionID(sessionID)
|
||||
if (contact == null) contact = Contact(sessionID)
|
||||
if (contact.name != profileName) {
|
||||
contact.name = profileName
|
||||
contactDatabase.setContact(contact)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setProfilePictureURL(context: Context, recipient: Recipient, profilePictureURL: String) {
|
||||
@ -31,6 +45,15 @@ class ProfileManager: SSKEnvironment.ProfileManagerProtocol {
|
||||
override fun setProfileKey(context: Context, recipient: Recipient, profileKey: ByteArray) {
|
||||
val database = DatabaseFactory.getRecipientDatabase(context)
|
||||
database.setProfileKey(recipient, profileKey)
|
||||
// New API
|
||||
val sessionID = recipient.address.serialize()
|
||||
val contactDatabase = DatabaseFactory.getSessionContactDatabase(context)
|
||||
var contact = contactDatabase.getContactWithSessionID(sessionID)
|
||||
if (contact == null) contact = Contact(sessionID)
|
||||
if (!contact.profilePictureEncryptionKey.contentEquals(profileKey)) {
|
||||
contact.profilePictureEncryptionKey = profileKey
|
||||
contactDatabase.setContact(contact)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setUnidentifiedAccessMode(context: Context, recipient: Recipient, unidentifiedAccessMode: Recipient.UnidentifiedAccessMode) {
|
||||
|
@ -3,6 +3,7 @@ package org.session.libsession.messaging
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import org.session.libsession.messaging.contacts.Contact
|
||||
import org.session.libsession.messaging.jobs.AttachmentUploadJob
|
||||
import org.session.libsession.messaging.jobs.Job
|
||||
import org.session.libsession.messaging.jobs.MessageSendJob
|
||||
@ -146,9 +147,12 @@ interface StorageProtocol {
|
||||
fun getSessionRequestProcessedTimestamp(publicKey: String): Long?
|
||||
fun setSessionRequestProcessedTimestamp(publicKey: String, newValue: Long)
|
||||
|
||||
// Loki User
|
||||
// Session Contact (Loki User)
|
||||
fun getDisplayName(publicKey: String): String?
|
||||
fun getProfilePictureURL(publicKey: String): String?
|
||||
fun getContactWithSessionID(sessionID: String): Contact?
|
||||
fun getAllContacts(): Set<Contact>
|
||||
fun setContact(contact: Contact)
|
||||
|
||||
// Recipient
|
||||
fun getRecipientSettings(address: Address): RecipientSettings?
|
||||
|
@ -10,7 +10,7 @@ class Contact(val sessionID: String) {
|
||||
// The key with which the profile picture is encrypted.
|
||||
var profilePictureEncryptionKey: ByteArray? = null
|
||||
// The ID of the thread associated with this contact.
|
||||
var threadID: String? = null
|
||||
var threadID: Int? = null
|
||||
// This flag is used to determine whether we should auto-download files sent by this contact.
|
||||
var isTrusted = false
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user