Is there a way to migrate Realm databases to device encrypted storage to use Android's Direct Boot mode?


#1

Hello,

Is there a way to migrate Realm databases to device encrypted storage, as needed for Android’s Direct Boot mode?

To migrate SharedPreferences between credential encrypted storage and device encrypted storage,
use the following:

 **Context.moveSharedPreferencesFrom()**

And for SQLite databases, use:

 **Context.moveDatabaseFrom()**

It doesn’t seem that Context.moveDatabaseFrom() works for Realm databases.

Is there a way to use Context.moveDatabaseFrom(), or is there any other method?

Thanks!


#2

I’m not familiar with the Direct Boot API’s but looking briefly at them it doesn’t look like it is directly possible to move arbitrary files. Judging from the API’s though. If you place the Realm file in <datadir>/databases I expect you to be able to use the moveDatabaseFrom API.


#3

Thanks Christian, that helped.

Moving the .json file to the database folder won’t work though, because the file won’t be accessible using openFileInput() in that folder, in order to do things like checking the checksum. I’ve tried moving it there, and it turns out there’s no way to access it, as that’s not an expected place to store files, and using openFileInput() will result in “No such file or directory” errors.

I’ve tried leaving the .json file in the raw resource folder, and using Context.moveDatabaseFrom(mContext, file.json) to move it to device encrypted storage, and when I run the code, it seems to work (no error reported), but the app is still not able to work when the device is in direct boot mode. Going to have to investigate, which is hard because testing direct boot is difficult without proper devices.

Thanks again Christian.

So far, this is how I’m handling it, and it works without error, but I’m not sure it’s working how I think it is.

NOTE: The migration must be done when the user is using app and the device is unlocked, in order to access the data in credential encrypted storage that is to be moved to device encrypted storage.

Since the Realm needs to use the direct boot Context for this case, the Realm needs to be initialized using the direct boot Context:

===========================================================================

if (Build.VERSION.SDK_INT >= 24) {
     // migrate existing .json into new device encrypted storage area
     storageContext = getApplicationContext().createDeviceProtectedStorageContext();
     if (!storageContext.moveDatabaseFrom(getApplicationContext(), "file.json")) {
          Log.e(TAG, "======== Failed to migrate file.json =======");
          Realm.init(getApplicationContext()); //initialize using app context due to error
     }
     else {
          Realm.init(storageContext);
     }
}
else { //SDK < 24
     Realm.init(getApplicationContext()); 
}

Realm realm = Realm.getDefaultInstance();

============================================================================

Here’s the Realm.Java code, showing how the Context passed into Realm.init() is the context used by Realm.getDefaultInstance()

Has anyone else out there dealt with Realm and direct boot mode in Android?