From 71613d9db1399b70611c6739485388bec477a692 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Fri, 16 Jul 2021 13:37:03 -0400 Subject: [PATCH] Ensure SQLCipher libraries are loaded. --- .../securesms/ApplicationContext.java | 3 +- .../securesms/database/DatabaseFactory.java | 2 ++ .../database/SqlCipherLibraryLoader.kt | 28 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/database/SqlCipherLibraryLoader.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index aae842422b..e4998d1343 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -39,6 +39,7 @@ import org.signal.core.util.tracing.Tracer; import org.signal.glide.SignalGlideCodecs; import org.signal.ringrtc.CallManager; import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.SqlCipherLibraryLoader; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.dependencies.ApplicationDependencyProvider; @@ -128,7 +129,7 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr Log.i(TAG, "onCreate()"); }) .addBlocking("crash-handling", this::initializeCrashHandling) - .addBlocking("sqlcipher-init", () -> SQLiteDatabase.loadLibs(this)) + .addBlocking("sqlcipher-init", () -> SqlCipherLibraryLoader.load(this)) .addBlocking("rx-init", () -> { RxJavaPlugins.setInitIoSchedulerHandler(schedulerSupplier -> Schedulers.from(SignalExecutors.BOUNDED_IO, true, false)); RxJavaPlugins.setInitComputationSchedulerHandler(schedulerSupplier -> Schedulers.from(SignalExecutors.BOUNDED, true, false)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java index e68f1689f2..39b1c257c2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java @@ -227,6 +227,8 @@ public class DatabaseFactory { } private DatabaseFactory(@NonNull Context context) { + SqlCipherLibraryLoader.load(context); + DatabaseSecret databaseSecret = DatabaseSecretProvider.getOrCreateDatabaseSecret(context); AttachmentSecret attachmentSecret = AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SqlCipherLibraryLoader.kt b/app/src/main/java/org/thoughtcrime/securesms/database/SqlCipherLibraryLoader.kt new file mode 100644 index 0000000000..936b6165e2 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SqlCipherLibraryLoader.kt @@ -0,0 +1,28 @@ +package org.thoughtcrime.securesms.database + +import android.content.Context +import net.sqlcipher.database.SQLiteDatabase + +/** + * A simple wrapper to load SQLCipher libs exactly once. The exact entry point of database access is non-deterministic because content providers run before + * Application#onCreate(). + */ +class SqlCipherLibraryLoader { + + companion object { + private var loaded = false + private val LOCK = Object() + + @JvmStatic + fun load(context: Context) { + if (!loaded) { + synchronized(LOCK) { + if (!loaded) { + SQLiteDatabase.loadLibs(context) + loaded = true + } + } + } + } + } +}