Added code to migrate from SQLCipher 3 to 4

This commit is contained in:
Morgan Pretty 2023-01-05 16:56:52 +11:00
parent cdd2559839
commit 1a28fd2a9e
24 changed files with 129 additions and 71 deletions

View File

@ -95,7 +95,8 @@ dependencies {
implementation 'com.takisoft.fix:colorpicker:1.0.1' implementation 'com.takisoft.fix:colorpicker:1.0.1'
implementation 'com.codewaves.stickyheadergrid:stickyheadergrid:0.9.4' implementation 'com.codewaves.stickyheadergrid:stickyheadergrid:0.9.4'
implementation 'com.github.dmytrodanylyk.circular-progress-button:library:1.1.3-S2' implementation 'com.github.dmytrodanylyk.circular-progress-button:library:1.1.3-S2'
implementation 'org.signal:android-database-sqlcipher:3.5.9-S3' implementation 'androidx.sqlite:sqlite-ktx:2.2.0'
implementation 'net.zetetic:sqlcipher-android:4.5.2@aar'
implementation ('com.googlecode.ez-vcard:ez-vcard:0.9.11') { implementation ('com.googlecode.ez-vcard:ez-vcard:0.9.11') {
exclude group: 'com.fasterxml.jackson.core' exclude group: 'com.fasterxml.jackson.core'
exclude group: 'org.freemarker' exclude group: 'org.freemarker'

View File

@ -8,7 +8,7 @@ import androidx.annotation.WorkerThread
import com.annimon.stream.function.Consumer import com.annimon.stream.function.Consumer
import com.annimon.stream.function.Predicate import com.annimon.stream.function.Predicate
import com.google.protobuf.ByteString import com.google.protobuf.ByteString
import net.sqlcipher.database.SQLiteDatabase import net.zetetic.database.sqlcipher.SQLiteDatabase
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.session.libsession.avatars.AvatarHelper import org.session.libsession.avatars.AvatarHelper
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId

View File

@ -5,7 +5,7 @@ import android.content.ContentValues
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import androidx.annotation.WorkerThread import androidx.annotation.WorkerThread
import net.sqlcipher.database.SQLiteDatabase import net.zetetic.database.sqlcipher.SQLiteDatabase
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.session.libsession.avatars.AvatarHelper import org.session.libsession.avatars.AvatarHelper
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId

View File

@ -33,7 +33,7 @@ import androidx.annotation.VisibleForTesting;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;

View File

@ -23,7 +23,7 @@ import android.database.Cursor;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import org.session.libsession.utilities.WindowDebouncer; import org.session.libsession.utilities.WindowDebouncer;
import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.ApplicationContext;

View File

@ -19,7 +19,7 @@ package org.thoughtcrime.securesms.database;
import android.content.Context; import android.content.Context;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.dependencies.DatabaseComponent;

View File

@ -1,9 +1,9 @@
package org.thoughtcrime.securesms.database package org.thoughtcrime.securesms.database
import android.content.ContentValues import android.content.ContentValues
import android.database.Cursor
import androidx.core.database.getStringOrNull import androidx.core.database.getStringOrNull
import net.sqlcipher.Cursor import net.zetetic.database.sqlcipher.SQLiteDatabase
import net.sqlcipher.database.SQLiteDatabase
import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.Base64
fun <T> SQLiteDatabase.get(table: String, query: String?, arguments: Array<String>?, get: (Cursor) -> T): T? { fun <T> SQLiteDatabase.get(table: String, query: String?, arguments: Array<String>?, get: (Cursor) -> T): T? {

View File

@ -6,7 +6,7 @@ import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import network.loki.messenger.R; import network.loki.messenger.R;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;

View File

@ -1,6 +1,5 @@
package org.thoughtcrime.securesms.database; package org.thoughtcrime.securesms.database;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
@ -12,7 +11,7 @@ import androidx.annotation.Nullable;
import com.annimon.stream.Stream; import com.annimon.stream.Stream;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.session.libsession.utilities.Address; import org.session.libsession.utilities.Address;

View File

@ -1,13 +1,12 @@
package org.thoughtcrime.securesms.database; package org.thoughtcrime.securesms.database;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import org.session.libsession.utilities.Address; import org.session.libsession.utilities.Address;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;

View File

@ -5,7 +5,7 @@ import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import org.thoughtcrime.securesms.jobmanager.persistence.ConstraintSpec; import org.thoughtcrime.securesms.jobmanager.persistence.ConstraintSpec;

View File

@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.database
import android.content.ContentValues import android.content.ContentValues
import android.content.Context import android.content.Context
import net.sqlcipher.database.SQLiteDatabase.CONFLICT_REPLACE import net.zetetic.database.sqlcipher.SQLiteDatabase.CONFLICT_REPLACE
import org.session.libsignal.database.LokiMessageDatabaseProtocol import org.session.libsignal.database.LokiMessageDatabaseProtocol
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper

View File

@ -7,7 +7,7 @@ import android.database.Cursor;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment; import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment;
import org.session.libsession.utilities.Address; import org.session.libsession.utilities.Address;

View File

@ -5,7 +5,7 @@ import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.text.TextUtils; import android.text.TextUtils;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import org.session.libsession.utilities.Address; import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.Document; import org.session.libsession.utilities.Document;

View File

@ -22,8 +22,8 @@ import android.database.Cursor;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import net.sqlcipher.database.SQLiteQueryBuilder; import net.zetetic.database.sqlcipher.SQLiteQueryBuilder;
import org.session.libsession.utilities.Address; import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.Util; import org.session.libsession.utilities.Util;

View File

@ -6,7 +6,7 @@ import android.database.Cursor;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.session.libsignal.utilities.Log; import org.session.libsignal.utilities.Log;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import org.session.libsignal.utilities.Base64; import org.session.libsignal.utilities.Base64;

View File

@ -11,7 +11,7 @@ import androidx.annotation.Nullable;
import com.annimon.stream.Stream; import com.annimon.stream.Stream;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import org.session.libsession.utilities.Address; import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.MaterialColor; import org.session.libsession.utilities.MaterialColor;

View File

@ -1,13 +1,13 @@
package org.thoughtcrime.securesms.database; package org.thoughtcrime.securesms.database;
import android.content.Context; import android.content.Context;
import android.database.Cursor;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.annimon.stream.Stream; import com.annimon.stream.Stream;
import net.sqlcipher.Cursor; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import net.sqlcipher.database.SQLiteDatabase;
import org.session.libsession.utilities.Util; import org.session.libsession.utilities.Util;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;

View File

@ -3,7 +3,7 @@ package org.thoughtcrime.securesms.database
import android.content.ContentValues import android.content.ContentValues
import android.content.Context import android.content.Context
import androidx.core.database.getStringOrNull import androidx.core.database.getStringOrNull
import net.sqlcipher.Cursor import android.database.Cursor
import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.contacts.Contact
import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.Base64
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
@ -75,21 +75,6 @@ class SessionContactDatabase(context: Context, helper: SQLCipherOpenHelper) : Da
} }
fun contactFromCursor(cursor: Cursor): Contact { fun contactFromCursor(cursor: Cursor): Contact {
val sessionID = cursor.getString(sessionID)
val contact = Contact(sessionID)
contact.name = cursor.getStringOrNull(name)
contact.nickname = cursor.getStringOrNull(nickname)
contact.profilePictureURL = cursor.getStringOrNull(profilePictureURL)
contact.profilePictureFileName = cursor.getStringOrNull(profilePictureFileName)
cursor.getStringOrNull(profilePictureEncryptionKey)?.let {
contact.profilePictureEncryptionKey = Base64.decode(it)
}
contact.threadID = cursor.getLong(threadID)
contact.isTrusted = cursor.getInt(isTrusted) != 0
return contact
}
fun contactFromCursor(cursor: android.database.Cursor): Contact {
val sessionID = cursor.getString(cursor.getColumnIndexOrThrow(sessionID)) val sessionID = cursor.getString(cursor.getColumnIndexOrThrow(sessionID))
val contact = Contact(sessionID) val contact = Contact(sessionID)
contact.name = cursor.getStringOrNull(cursor.getColumnIndexOrThrow(name)) contact.name = cursor.getStringOrNull(cursor.getColumnIndexOrThrow(name))

View File

@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.database
import android.content.ContentValues import android.content.ContentValues
import android.content.Context import android.content.Context
import net.sqlcipher.Cursor import android.database.Cursor
import org.session.libsession.messaging.jobs.AttachmentUploadJob import org.session.libsession.messaging.jobs.AttachmentUploadJob
import org.session.libsession.messaging.jobs.BackgroundGroupAddJob import org.session.libsession.messaging.jobs.BackgroundGroupAddJob
import org.session.libsession.messaging.jobs.GroupAvatarDownloadJob import org.session.libsession.messaging.jobs.GroupAvatarDownloadJob

View File

@ -28,8 +28,8 @@ import androidx.annotation.Nullable;
import com.annimon.stream.Stream; import com.annimon.stream.Stream;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import net.sqlcipher.database.SQLiteStatement; import net.zetetic.database.sqlcipher.SQLiteStatement;
import org.session.libsession.messaging.calls.CallMessageType; import org.session.libsession.messaging.calls.CallMessageType;
import org.session.libsession.messaging.messages.signal.IncomingGroupMessage; import org.session.libsession.messaging.messages.signal.IncomingGroupMessage;

View File

@ -32,7 +32,7 @@ import androidx.annotation.Nullable;
import com.annimon.stream.Stream; import com.annimon.stream.Stream;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.sqlcipher.SQLiteDatabase;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.session.libsession.utilities.Address; import org.session.libsession.utilities.Address;

View File

@ -1,14 +1,16 @@
package org.thoughtcrime.securesms.database.helpers; package org.thoughtcrime.securesms.database.helpers;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import net.sqlcipher.database.SQLiteDatabase; import net.zetetic.database.DatabaseErrorHandler;
import net.sqlcipher.database.SQLiteDatabaseHook; import net.zetetic.database.DatabaseUtils;
import net.sqlcipher.database.SQLiteOpenHelper; import net.zetetic.database.sqlcipher.SQLiteConnection;
import net.zetetic.database.sqlcipher.SQLiteDatabase;
import net.zetetic.database.sqlcipher.SQLiteDatabaseHook;
import net.zetetic.database.sqlcipher.SQLiteOpenHelper;
import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsignal.utilities.Log; import org.session.libsignal.utilities.Log;
@ -36,6 +38,8 @@ import org.thoughtcrime.securesms.database.SessionJobDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase;
import java.io.File;
public class SQLCipherOpenHelper extends SQLiteOpenHelper { public class SQLCipherOpenHelper extends SQLiteOpenHelper {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -78,37 +82,116 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
// Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes // Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes
private static final int DATABASE_VERSION = lokiV38; private static final int DATABASE_VERSION = lokiV38;
private static final String DATABASE_NAME = "signal.db"; private static final String CIPHER3_DATABASE_NAME = "signal.db";
private static final String DATABASE_NAME = "signal_v4.db";
private final Context context; private final Context context;
private final DatabaseSecret databaseSecret; private final DatabaseSecret databaseSecret;
public SQLCipherOpenHelper(@NonNull Context context, @NonNull DatabaseSecret databaseSecret) { public SQLCipherOpenHelper(@NonNull Context context, @NonNull DatabaseSecret databaseSecret) {
super(context, DATABASE_NAME, null, DATABASE_VERSION, new SQLiteDatabaseHook() { super(context, DATABASE_NAME, databaseSecret.asString(), null, DATABASE_VERSION, DATABASE_VERSION, null, new SQLiteDatabaseHook() {
@Override @Override
public void preKey(SQLiteDatabase db) { public void preKey(SQLiteConnection connection) {
db.rawExecSQL("PRAGMA cipher_default_kdf_iter = 1;"); connection.execute("PRAGMA cipher_default_kdf_iter = 256000;", null, null);
db.rawExecSQL("PRAGMA cipher_default_page_size = 4096;"); connection.execute("PRAGMA cipher_default_page_size = 4096;", null, null);
} }
@Override @Override
public void postKey(SQLiteDatabase db) { public void postKey(SQLiteConnection connection) {
db.rawExecSQL("PRAGMA kdf_iter = '1';"); connection.execute("PRAGMA kdf_iter = '256000';", null, null);
db.rawExecSQL("PRAGMA cipher_page_size = 4096;"); connection.execute("PRAGMA cipher_page_size = 4096;", null, null);
// if not vacuumed in a while, perform that operation // if not vacuumed in a while, perform that operation
long currentTime = System.currentTimeMillis(); long currentTime = System.currentTimeMillis();
// 7 days // 7 days
if (currentTime - TextSecurePreferences.getLastVacuumTime(context) > 604_800_000) { if (currentTime - TextSecurePreferences.getLastVacuumTime(context) > 604_800_000) {
db.rawExecSQL("VACUUM;"); connection.execute("VACUUM;", null, null);
TextSecurePreferences.setLastVacuumNow(context); TextSecurePreferences.setLastVacuumNow(context);
} }
} }
}); }, true);
this.context = context.getApplicationContext(); this.context = context.getApplicationContext();
this.databaseSecret = databaseSecret; this.databaseSecret = databaseSecret;
} }
public static void migrateSqlCipher3To4IfNeeded(@NonNull Context context, @NonNull DatabaseSecret databaseSecret) {
String oldDbPath = context.getDatabasePath(CIPHER3_DATABASE_NAME).getPath();
File oldDbFile = new File(oldDbPath);
// If the old SQLCipher3 database file doesn't exist then just return early
if (!oldDbFile.exists()) { return; }
// If the new database file already exists then we probably had a failed migration and it's likely in
// an invalid state so should delete it
String newDbPath = context.getDatabasePath(DATABASE_NAME).getPath();
File newDbFile = new File(newDbPath);
if (newDbFile.exists()) { newDbFile.delete(); }
try {
newDbFile.createNewFile();
}
catch (Exception e) {
// TODO: Communicate the error somehow???
return;
}
try {
// Open the old database
SQLiteDatabase oldDb = SQLiteDatabase.openOrCreateDatabase(oldDbPath, databaseSecret.asString(), null, null, new SQLiteDatabaseHook() {
@Override
public void preKey(SQLiteConnection connection) {
connection.execute("PRAGMA cipher_compatibility = 3;", null, null);
connection.execute("PRAGMA kdf_iter = '1';", null, null);
connection.execute("PRAGMA cipher_page_size = 4096;", null, null);
}
@Override
public void postKey(SQLiteConnection connection) {
connection.execute("PRAGMA cipher_compatibility = 3;", null, null);
connection.execute("PRAGMA kdf_iter = '1';", null, null);
connection.execute("PRAGMA cipher_page_size = 4096;", null, null);
}
});
// Export the old database to the new one (will have the default 'kdf_iter' and 'page_size' settings)
int oldDbVersion = oldDb.getVersion();
oldDb.rawExecSQL(
String.format("ATTACH DATABASE '%s' AS sqlcipher4 KEY '%s'", newDbPath, databaseSecret.asString())
);
Cursor cursor = oldDb.rawQuery("SELECT sqlcipher_export('sqlcipher4')");
cursor.moveToLast();
cursor.close();
oldDb.rawExecSQL("DETACH DATABASE sqlcipher4");
oldDb.close();
// TODO: Performance testing
SQLiteDatabase newDb = SQLiteDatabase.openDatabase(newDbPath, databaseSecret.asString(), null, SQLiteDatabase.OPEN_READWRITE, new SQLiteDatabaseHook() {
@Override
public void preKey(SQLiteConnection connection) {
connection.execute("PRAGMA cipher_default_kdf_iter = 256000;", null, null);
connection.execute("PRAGMA cipher_default_page_size = 4096;", null, null);
}
@Override
public void postKey(SQLiteConnection connection) {
connection.execute("PRAGMA cipher_default_kdf_iter = 256000;", null, null);
connection.execute("PRAGMA cipher_default_page_size = 4096;", null, null);
}
});
newDb.setVersion(oldDbVersion);
newDb.close();
// TODO: Delete 'CIPHER3_DATABASE_NAME'
// TODO: What do we do if the deletion fails??? (The current logic will end up re-migrating...)
// oldDbFile.delete();
}
catch (Exception e) {
// TODO: Communicate the error somehow???
}
}
@Override @Override
public void onCreate(SQLiteDatabase db) { public void onCreate(SQLiteDatabase db) {
db.execSQL(SmsDatabase.CREATE_TABLE); db.execSQL(SmsDatabase.CREATE_TABLE);
@ -195,9 +278,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
@Override @Override
public void onConfigure(SQLiteDatabase db) { public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db); super.onConfigure(db);
// Loki - Enable write ahead logging mode and increase the cache size.
// This should be disabled if we ever run into serious race condition bugs.
db.enableWriteAheadLogging();
db.execSQL("PRAGMA cache_size = 10000"); db.execSQL("PRAGMA cache_size = 10000");
} }
@ -420,14 +501,6 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
} }
} }
public SQLiteDatabase getReadableDatabase() {
return getReadableDatabase(databaseSecret.asString());
}
public SQLiteDatabase getWritableDatabase() {
return getWritableDatabase(databaseSecret.asString());
}
public void markCurrent(SQLiteDatabase db) { public void markCurrent(SQLiteDatabase db) {
db.setVersion(DATABASE_VERSION); db.setVersion(DATABASE_VERSION);
} }

View File

@ -6,7 +6,7 @@ import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import net.sqlcipher.database.SQLiteDatabase import net.zetetic.database.sqlcipher.SQLiteDatabase
import org.session.libsession.database.MessageDataProvider import org.session.libsession.database.MessageDataProvider
import org.thoughtcrime.securesms.attachments.DatabaseAttachmentProvider import org.thoughtcrime.securesms.attachments.DatabaseAttachmentProvider
import org.thoughtcrime.securesms.crypto.AttachmentSecret import org.thoughtcrime.securesms.crypto.AttachmentSecret
@ -22,7 +22,7 @@ object DatabaseModule {
@JvmStatic @JvmStatic
fun init(context: Context) { fun init(context: Context) {
SQLiteDatabase.loadLibs(context) System.loadLibrary("sqlcipher")
} }
@Provides @Provides
@ -33,6 +33,7 @@ object DatabaseModule {
@Singleton @Singleton
fun provideOpenHelper(@ApplicationContext context: Context): SQLCipherOpenHelper { fun provideOpenHelper(@ApplicationContext context: Context): SQLCipherOpenHelper {
val dbSecret = DatabaseSecretProvider(context).orCreateDatabaseSecret val dbSecret = DatabaseSecretProvider(context).orCreateDatabaseSecret
SQLCipherOpenHelper.migrateSqlCipher3To4IfNeeded(context, dbSecret)
return SQLCipherOpenHelper(context, dbSecret) return SQLCipherOpenHelper(context, dbSecret)
} }