Is DirectBoot, what you’re looking for?

Ashutosh Singh Tomar
Bobble Engineering
Published in
5 min readJul 22, 2020

Android brings various features for users and developers, one such feature was added in Android 7, called DirectBoot, but what exactly is DirectBoot? Let’s try to find that in the next few minutes, and also when, why, and how to use it.

Let’s dive into it.

What is DirectBoot?

Starting with Android N, a device that has been powered on can boot into a new mode called Direct Boot before the user has a chance to unlock it for the first time. In this mode, the operating system is fully operational, but access to private app data is limited and only apps that have been updated to be Direct Boot Aware can run, which basically means that you can perform actions even before the user unlocks the device.

Does your app even need the DirectBoot?

Let’s consider a real-world scenario, of an Alarm Clock App. Suppose a user sets an Alarm for 6'o clock in the morning and if the device gets rebooted during the sleep cycle, the user won’t be able to receive the alarm and might miss out on important things for which they scheduled the alarm. So to prevent such scenarios from happening Google included Direct Boot Aware in Android 7.

Any application that schedules alarms like the alarm clock we discussed, provides important and timely notifications like a messaging app or provides services to other apps or the system like a keyboard or a launcher, all these apps need to update to Direct Boot Aware for better user experience and special scenarios.

How does Direct Boot help if the device is rebooted?

To support DirectBoot, the system provides two storage locations for data:

Credential encrypted storage, which is the default storage location and only available after the user has unlocked the device. The data could be found in /user folder in rooted devices.

Device encrypted storage, which is a storage location available both during Direct Boot mode and after the user has unlocked the device. For this mode, all the data is present in the /user_de folder.

So even if the device is rebooted the application can perform actions and use the user data that is present in the Device Encrypted Storage

How to use Direct Boot Aware?

1. Analyze the components of your app, which you would like to make boot-ware. A service launched on boot, for instance, which is responsible for initiating the alarms. Declare those components as boot-aware in manifest

<activity|provider|receiver|service …
android:directBootAware=”true”>

If you implement a custom Application class and register any sub-component as boot-aware, the Application class automatically inherits the boot-aware property.

2. Components that rely on broadcast ACTION_BOOT_COMPLETED as a trigger to start, must switch to the broadcast ACTION_LOCKED_BOOT_COMPLETED. This broadcast is received by all boot-aware components, as soon as the device is booted. At this moment only Device protected storage is accessible.

P.S: ACTION_BOOT_COMPLETED will also be received by boot-aware components but only once the device has been unlocked by the user. At this moment, both Credential protected storage and Device protected storage are accessible.

How do I access the two different storage paths?

Android APIs have made this extremely easy, as the only variable that differentiates between the two storage paths is Context. The default context points to Credential protected storage. A new context can be requested anytime by createDeviceProtectedStorageContext() whose storage APIs point to the Device protected storage.

Context credentialProtectedContext =getApplicationContext();
Context deviceProtectedContext = credentialProtectedStorage.createDeviceProtectedStorageContext();

Worried about the Data already present in Credential Storage?

If the app hasn’t been rolled out to the public yet, you wouldn’t face this issue, because you would, by default, place boot-aware data at device protected storage. But, updating an app that is already available to users, you might consider moving the data which is required by boot-aware components from Credential protected storage to Device protected storage to maintain the integrity of the app after the update. This can be done by moveSharedPreferencesFrom() or moveDatabaseFrom() respectively.

// For Shared Preferences
deviceProtectedContext.moveSharedPreferencesFrom(credentialProtectedContext,SHARED_PREFERENCE_NAME);
//For Databases
deviceProtectedContext.moveDatabaseFrom(credentialProtectedContext,DATABASE_NAME);

To move any other files residing at internal app storage, which may be required by boot-aware components, you can manually copy the file :

File fileAtCredentialStorage= credentialProtectedContext.getFilesDir()+File.seperator+FILE_NAME;
File fileAtDeviceStorage= deviceProtectedContext.getFilesDir()+File.seperator+FILE_NAME; FileUtils.copyFile(fileAtCredentialStorage, fileAtDeviceStorage);

Using 3rd party libraries, we got you covered!!!!

3rd party libraries like Firebase, Crashylitics, AdMob, etc. require to be initialized at app startup. They internally use SharedPreferences and databases, and most of them don’t support device protected storage. So, it’s a good idea to take care of them only after the device has been unlocked else they will throw an exception.

To check at runtime, whether credential protected storage is available or not, this function may help UserManagerCompat.isUserUnlocked()

Things to be taken care of :

A common mistake may arise while moving databases. If a connection to a database is opened, a singleton for the database is persisted by the system. Upon moving the database to another location, the singleton may not be aware of the move and subsequent call to the database may throw an exception:

It is not guaranteed that this exception is thrown for all devices, as it is system dependent, but it is always better to be on a safe side. Make sure that the migration always takes place before opening the database.

Is it safe to use Direct Boot Aware?

You should not migrate private user information, such as passwords or authorization tokens, to device encrypted storage. In some scenarios, you might need to manage separate sets of data in the two encrypted stores. Use this feature wisely and only take advantage of it, when there is a real reason for doing that!

This article is co-authored by RISHABH KHEMKA and Saurabh Tomar.

Until next time, “may the code be with you”.

--

--