androidandroid-sqlitesqlcipher-android

Room SQLCipher provide an alternative LibraryLoader


I'm wondering if there a way to add an alternative LibraryLoader for SQLCipher.
Some devices as Huawei Enjoy 9s (Android 5.1 rooted) and Nexus 4 (Android 6.0.1 not rooted) produce the next crash:

Fatal Exception: java.lang.UnsatisfiedLinkError dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.application-1/base.apk"], nativeLibraryDirectories=[/data/app/com.application.app-1/lib/arm, /vendor/lib, /system/lib]]] couldn't find "libsqlcipher.so"

If it's possible, how do I find the appropriate library name to load and where to perform the action?
Here is the code from the SQLiteDatabase:

  /**
   * Loads the native SQLCipher library into the application process.
   */
  public static synchronized void loadLibs (Context context, File workingDir, LibraryLoader libraryLoader) {
    libraryLoader.loadLibraries("sqlcipher");

    // System.loadLibrary("stlport_shared");
    // System.loadLibrary("sqlcipher_android");
    // System.loadLibrary("database_sqlcipher");

    // boolean systemICUFileExists = new File("/system/usr/icu/icudt46l.dat").exists();

    // String icuRootPath = systemICUFileExists ? "/system/usr" : workingDir.getAbsolutePath();
    // setICURoot(icuRootPath);
    // if(!systemICUFileExists){
    //     loadICUData(context, workingDir);
    // }
  }

This is how I am creating the DB instance:

import net.sqlcipher.database.SQLiteDatabase
import net.sqlcipher.database.SupportFactory

...

val passphrase: ByteArray = SQLiteDatabase.getBytes((BuildConfig.ROOM_PASSPHRASE + session.getRoomUUID()).toCharArray())
val factory = SupportFactory(passphrase)
val instance = Room.databaseBuilder(context.applicationContext, MyDatabase::class.java, "MyDatabase")
          .openHelperFactory(factory)
          .fallbackToDestructiveMigration()
          .build()

...


Solution

  • It was not obvious but I found a problem. The SupportFactory instance must be used only once per opening a database. So, reset the Dagger component that holds the database instance on the Login screen fixed the issue.

    No need to loadLibraries manually, just reset the DI component in the right place.