| page.title=Supporting Direct Boot | |
| page.keywords=direct boot | |
| @jd:body | |
| <div id="tb-wrapper"> | |
| <div id="tb"> | |
| <h2>In this document</h2> | |
| <ol> | |
| <li><a href="#run">Requesting Access to Run During Direct Boot</a></li> | |
| <li><a href="#access">Accessing Device Encrypted Storage</a></li> | |
| <li><a href="#notification">Getting Notified of User Unlock</a></li> | |
| <li><a href="#migrating">Migrating Existing Data</a></li> | |
| <li><a href="#testing">Testing Your Encryption Aware App</a></li> | |
| <li><a href="#dpm">Checking Device Policy Encryption Status</a></li> | |
| </ol> | |
| </div> | |
| </div> | |
| <p>Android 7.0 runs in a secure, <i>Direct Boot</i> mode | |
| when the device has been powered on but the user has not unlocked the | |
| device. To support this, the system provides two storage locations for data:</p> | |
| <ul> | |
| <li><i>Credential encrypted storage</i>, which is the default storage location | |
| and only available after the user has unlocked the device.</li> | |
| <li><i>Device encrypted storage</i>, which is a storage location available both | |
| during Direct Boot mode and after the user has unlocked the device.</li> | |
| </ul> | |
| <p>By default, apps do not run during Direct Boot mode. | |
| If your app needs to take action during Direct Boot mode, you can register | |
| app components that should be run during this mode. Some common use cases | |
| for apps needing to run during Direct Boot mode include:</p> | |
| <ul> | |
| <li>Apps that have scheduled notifications, such as alarm clock | |
| apps.</li> | |
| <li>Apps that provide important user notifications, like SMS apps.</li> | |
| <li>Apps that provide accessibility services, like Talkback.</li> | |
| </ul> | |
| <p>If your app needs to access data while running in Direct Boot mode, use | |
| device encrypted storage. Device encrypted storage contains data | |
| encrypted with a key that is only available after a device has performed a | |
| successful verified boot.</p> | |
| <p>For data that should be encrypted with a key associated with user | |
| credentials, such as a PIN or password, use credential encrypted storage. | |
| Credential encrypted storage is only available after the user has successfully | |
| unlocked the device, up until when the user restarts the device again. If the | |
| user enables the lock screen after unlocking the device, this doesn't lock | |
| credential encrypted storage.</p> | |
| <h2 id="run">Requesting Access to Run During Direct Boot</h2> | |
| <p>Apps must register their components with the system before they | |
| can run during Direct Boot mode or access device encrypted | |
| storage. Apps register with the system by marking components as | |
| <i>encryption aware</i>. To mark your component as encryption aware, set the | |
| <code>android:directBootAware</code> attribute to true in your manifest.<p> | |
| <p>Encryption aware components can register to receive a | |
| {@link android.content.Intent#ACTION_LOCKED_BOOT_COMPLETED | |
| ACTION_LOCKED_BOOT_COMPLETED} broadcast message from the | |
| system when the device has been restarted. At this point device encrypted | |
| storage is available, and your component can execute tasks that need to be | |
| run during Direct Boot mode, such as triggering a scheduled alarm.</p> | |
| <p>The following code snippet is an example of how to register a | |
| {@link android.content.BroadcastReceiver} as encryption aware, and add an | |
| intent filter for {@link android.content.Intent#ACTION_LOCKED_BOOT_COMPLETED | |
| ACTION_LOCKED_BOOT_COMPLETED}, in the app manifest:</p> | |
| <pre> | |
| <receiver | |
| android:directBootAware="true" > | |
| ... | |
| <intent-filter> | |
| <action android:name="android.intent.action.ACTION_LOCKED_BOOT_COMPLETED" /> | |
| </intent-filter> | |
| </receiver> | |
| </pre> | |
| <p>Once the user has unlocked the device, all components can access both the | |
| device encrypted storage as well as credential encrypted storage.</p> | |
| <h2 id="access">Accessing Device Encrypted Storage</h2> | |
| <p>To access device encrypted storage, create a second | |
| {@link android.content.Context} instance by calling | |
| {@link android.content.Context#createDeviceProtectedStorageContext | |
| Context.createDeviceProtectedStorageContext()}. All storage API | |
| calls made using this context access the device encrypted storage. The | |
| following example accesses the device encrypted storage and opens an existing | |
| app data file:</p> | |
| <pre> | |
| Context directBootContext = appContext.createDeviceProtectedStorageContext(); | |
| // Access appDataFilename that lives in device encrypted storage | |
| FileInputStream inStream = directBootContext.openFileInput(appDataFilename); | |
| // Use inStream to read content... | |
| </pre> | |
| <p>Use device encrypted storage only for | |
| information that must be accessible during Direct Boot mode. | |
| Don't use device encrypted storage as a general-purpose encrypted store. | |
| For private user information, or encrypted data that isn't needed during | |
| Direct Boot mode, use credential encrypted storage.</p> | |
| <h2 id="notification">Getting Notified of User Unlock</h2> | |
| <p>When the user unlocks the device after restart, your app can switch to | |
| accessing credential encrypted storage and use regular system services that | |
| depend on user credentials.</p> | |
| <p>To get notified when the user unlocks the device after a reboot, | |
| register a {@link android.content.BroadcastReceiver} from a running component | |
| to listen for unlock notification messages. When the user unlocks the device | |
| after boot: | |
| </p> | |
| <ul> | |
| <li>If your app has foreground processes that need immediate notification, | |
| listen for the {@link android.content.Intent#ACTION_USER_UNLOCKED | |
| ACTION_USER_UNLOCKED} message.</li> | |
| <li>If your app only uses background processes that can act on a delayed | |
| notification, listen for the | |
| {@link android.content.Intent#ACTION_BOOT_COMPLETED ACTION_BOOT_COMPLETED} | |
| message.</li> | |
| </ul> | |
| <p>If the user has unlocked the device, you can find out by calling | |
| {@link android.os.UserManager#isUserUnlocked UserManager.isUserUnlocked()}. | |
| </p> | |
| <h2 id="migrating">Migrating Existing Data</h2> | |
| <p>If a user updates their device to use Direct Boot mode, you might have | |
| existing data that needs to get migrated to device encrypted storage. Use | |
| {@link android.content.Context#moveSharedPreferencesFrom | |
| Context.moveSharedPreferencesFrom()} and | |
| {@link android.content.Context#moveDatabaseFrom | |
| Context.moveDatabaseFrom()} to migrate preference and database | |
| data between credential encrypted storage and device encrypted storage.</p> | |
| <p>Use your best judgment when deciding what data to migrate from credential | |
| encrypted storage to device encrypted storage. 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.</p> | |
| <h2 id="testing">Testing Your Encryption Aware App</h2> | |
| <p>Test your encryption aware app with Direct Boot mode enabled. There are | |
| two ways to enable Direct Boot.</p> | |
| <p class="caution"><strong>Caution:</strong> Enabling Direct Boot | |
| wipes all user data on the device.</p> | |
| <p>On supported devices with Android 7.0 installed, enable | |
| Direct Boot by doing one of the following:</p> | |
| <ul> | |
| <li>On the device, enable <b>Developer options</b> if you haven't already by | |
| going to <b>Settings > About phone</b>, and tapping <b>Build number</b> | |
| seven times. Once the developer options screen is available, go to | |
| <b>Settings > Developer options</b> and select | |
| <b>Convert to file encryption</b>.</li> | |
| <li>Use the following adb shell commands to enable Direct Boot mode: | |
| <pre class="no-pretty-print"> | |
| $ adb reboot-bootloader | |
| $ fastboot --wipe-and-use-fbe | |
| </pre> | |
| </li> | |
| </ul> | |
| <p>An emulated Direct Boot mode is also available, in case you need to switch | |
| modes on your test devices. Emulated mode should only be used during | |
| development and may cause data loss. To enable emulated Direct Boot mode, | |
| set a lock pattern on the device, choose "No thanks" if prompted for a | |
| secure start-up screen when setting a lock pattern, and then use the | |
| following adb shell command:</p> | |
| <pre class="no-pretty-print"> | |
| $ adb shell sm set-emulate-fbe true | |
| </pre> | |
| <p>To turn off emulated Direct Boot mode, use the following command:</p> | |
| <pre class="no-pretty-print"> | |
| $ adb shell sm set-emulate-fbe false | |
| </pre> | |
| <p>Using these commands causes the device to reboot.</p> | |
| <h2 id="dpm">Checking Device Policy Encryption Status</h2> | |
| <p>Device administration apps can use | |
| {@link android.app.admin.DevicePolicyManager#getStorageEncryptionStatus | |
| DevicePolicyManager.getStorageEncryptionStatus()} to check the current | |
| encryption status of the device. If your app is targeting an API level | |
| lower than 24.0 (Android 7.0), | |
| {@link android.app.admin.DevicePolicyManager#getStorageEncryptionStatus | |
| getStorageEncryptionStatus()} will return | |
| {@link android.app.admin.DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE | |
| ENCRYPTION_STATUS_ACTIVE} if the device is either using full-disk encryption, | |
| or file-based encryption with Direct Boot. In both of these cases, data is | |
| always stored encrypted at rest. If your app is targeting an API level of | |
| 24.0 or higher, | |
| {@link android.app.admin.DevicePolicyManager#getStorageEncryptionStatus | |
| getStorageEncryptionStatus()} will return | |
| {@link android.app.admin.DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE | |
| ENCRYPTION_STATUS_ACTIVE} if the device is using full-disk encryption. It will | |
| return | |
| {@link android.app.admin.DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE_PER_USER | |
| ENCRYPTION_STATUS_ACTIVE_PER_USER} if the device is using file-based encryption | |
| with Direct Boot.</p> | |
| <p>If you build a device administration app | |
| that targets Android 7.0, make sure to check for both | |
| {@link android.app.admin.DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE | |
| ENCRYPTION_STATUS_ACTIVE} and | |
| {@link android.app.admin.DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE_PER_USER | |
| ENCRYPTION_STATUS_ACTIVE_PER_USER} to determine if the device is | |
| encrypted.</p> |