What’s in Android 9 for enterprise apps

This page provides an overview of the enterprise APIs, features, and behavior changes that are available in the Android 9.

Work profile user interface

Android 9 (API level 28) includes user interface changes in the default launcher to help users separate personal and work apps. Device manufacturers supporting this can present users' apps in separate work and personal tabs. We've also made it easier for device users to turn the work profile on and off by including a switch in the launcher's work tab.

Figure 1. The default launcher's personal tab and work tab with work profile switch

When provisioning work profiles and managed devices, Android 9 includes animated illustrations to help device users understand these features.

Switch apps across profiles

Android 9 includes APIs to launch another instance of an app in a different profile to help users switch between accounts. For example, an email app can provide a UI that lets the user switch between the personal profile and the work profile to access two email accounts. All apps can call these APIs to launch the main activity of the same app if it's already installed in the other profile. To add cross-profile account switching to your app, follow the steps below calling methods of the CrossProfileApps class:

  1. Call getTargetUserProfiles() to get a list of profiles you can launch another instance of the app in. This method checks that the app is installed in the profiles.
  2. Call getProfileSwitchingIconDrawable() to get an icon that you can use to represent another profile.
  3. Call getProfileSwitchingLabel() to get localized text that prompts the user to switch profiles.
  4. Call startMainActivity() to launch an instance of your app in another profile.

Check that the main activity you want to launch is declared in your app's manifest file, with an ACTION_MAIN intent action, and includes a CATEGORY_LAUNCHER intent category.

Programmatically turn work profiles on or off

The default launcher (or apps that have the permission MANAGE_USERS or MODIFY_QUIET_MODE) can turn the work profile on or off by calling UserManager.requestQuietModeEnabled(). You can inspect the return value to know if the user needs to confirm their credentials before the state changes. Because the change might not happen instantly, listen for the ACTION_MANAGED_PROFILE_AVAILABLE or ACTION_MANAGED_PROFILE_UNAVAILABLE broadcast to know when to update the user interface.

Your app can check the status of the work profile by calling UserManager.isQuietModeEnabled().

Lock down any app to a device

Starting in Android 9, device owners and profile owners (of secondary users) can lock any app to a device’s screen by putting the app into lock task mode. Previously, app developers had to add support for lock task mode in their apps. Android 9 also extends the lock task APIs to profile owners of non-affiliated secondary users. Follow the steps below to lock an app to the screen:

  1. Call DevicePolicyManager.setLockTaskPackages() to allowlist apps for lock task mode.
  2. Call ActivityOptions.setLockTaskEnabled() to launch an allowlisted app into lock task mode.

To stop an app in lock task mode, remove the app from the lock task mode allowlist using DevicePolicyManager.setLockTaskPackages().

Enable system UI features

When lock task mode is enabled, device owners and profile owners can enable certain system UI features on the device by calling DevicePolicyManager.setLockTaskFeatures() and passing a bit field of the following feature flags:

You can call DevicePolicyManager.getLockTaskFeatures() to get the list of features available on a device when lock task mode is enabled. When a device exits lock task mode, it returns to the state mandated by other device policies.

Suppress error dialogs

In some environments, such as retail demonstrations or public information displays, you might not want to show error dialogs to users. A device policy controller (DPC) can suppress system error dialogs for crashed or unresponsive apps by adding the DISALLOW_SYSTEM_ERROR_DIALOGS user restriction. This restriction affects all dialogs when applied by a device owner but only the error dialogs shown in the primary or secondary user are suppressed when the restriction is applied by profile owners. This restriction doesn't affect work profiles.

In Android 9, apps running in immersive full-screen mode don't show the reminder bubble when in lock task mode. The reminder bubble is a panel shown to users (on first launch) that explains how to exit the immersive mode.

Support multiple users on dedicated devices

Android 9 introduces the concept of an ephemeral user for dedicated devices (previously called COSU devices). Ephemeral users are short-term users intended for cases where multiple users share a single dedicated device. This includes public user sessions on devices such as library or hospitality check-in kiosks, as well as persistent sessions between a fixed set of users on devices, for example, shift workers.

Ephemeral users should be created in the background. They are created as secondary users on a device and are removed (along with associated apps and data) when they are stopped, switched, or the device reboots. To create an ephemeral user, device owners can:

  1. Set the MAKE_USER_EPHEMERAL flag when calling DevicePolicyManager.createAndManageUser().
  2. Call DevicePolicyManager.startUserInBackground() to start the ephemeral user in the background.

Note, apps targeting Android 9 should catch UserManager.UserOperationException when calling createAndManageUser(). Call the exception's getUserOperationResult() method to find out why the user wasn't created.

Receive event notifications

The DeviceAdminReceiver receives notifications for the following events:

Display event messages to users

Device owners can configure the messages that are displayed to users when they start and end their sessions:

Log out and stop users

Device owners can use DevicePolicyManager.setLogoutEnabled() to specify whether logout is enabled for secondary users. To check if logout is enabled, call DevicePolicyManager.isLogoutEnabled().

Profile owners of secondary users can call DevicePolicyManager.logoutUser() to stop the secondary user and switch back to the primary user.

Device owners can use DevicePolicyManager.stopUser() to stop a specified secondary user.

Package caching

To streamline user provisioning on shared devices with a fixed set of users, such as devices for shift workers, it's possible to cache packages that are needed for multi-user sessions:

  1. Call DevicePolicyManager.setKeepUninstalledPackages() to specify the list of packages to keep as APKs. To retrieve a list of these packages, call DevicePolicyManager.getKeepUninstalledPackages().

  2. Call DevicePolicyManager.installExistingPackage() to install a package that has been kept after removal via setKeepUninstalledPackages().

Additional methods and constants

Android 9 also includes the following methods and constants to further support user sessions on shared devices:

Clear package data and remove accounts

Device owners and profile owners can call clearApplicationUserData() to clear the user data for a given package. To remove an account from the AccountManager, device and profile owners can call removeAccount().

User restrictions and increased control over settings

Android 9 introduces a set of user restrictions for DPCs, as well as the ability to configure APNs, time and timezone, and system settings on a device.

Configure APNs

Device owners can use the following methods in the DevicePolicyManager class to configure APNs on a device:

Configure time and timezone

Device owners can use the following methods in the DevicePolicyManager class to set the time and timezone on a device:

Enforce user restrictions on important settings

Android 9 adds user restrictions to disable system features and settings. To add a restriction, call DevicePolicyManager.addUserRestriction() with one of the following UserManager constants:

If DISALLOW_CONFIG_BRIGHTNESS and DISALLOW_CONFIG_SCREEN_TIMEOUT are enforced on a device, device owners can still set the screen brightness, screen brightness mode, and screen timeout settings on the device using the API DevicePolicyManager.setSystemSetting().

Metered data

Device owners and profile owners can prevent apps from using a device's metered-data networks. A network is considered metered when when the user is sensitive to heavy data usage because of cost, data limits, or battery and performance issues. To prevent apps from using metered networks, call DevicePolicyManager.setMeteredDataDisabledPackages() passing a list of package names. To retrieve the currently restricted apps, call DevicePolicyManager.getMeteredDataDisabledPackages().

To learn more about metered data in Android, read Optimizing Network Data Usage.

Migrate DPCs

Device policy controllers (DPCs) can transfer their ownership of a device or work profile to another DPC. You might transfer ownership to move some features to the Android Management API, to migrate devices from your legacy DPC, or to help IT admins migrate to your EMM. Because you're just changing the DPC ownership, you can't use this feature to change the type of management, for example, migrating from a managed device to a work profile or vice-versa.

You can use the device admin policies XML resource to indicate that this version of your DPC supports migration. A target DPC indicates it can receive ownership by including a element named <support-transfer-ownership>. The example below shows how you might do this in your DPC's device admin XML file:

<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
    <support-transfer-ownership />
    <uses-policies>
        <limit-password />
        <watch-login />
        <reset-password />
    </uses-policies>
</device-admin>

DPCs that want to migrate ownership to new DPC app can check if a target DPC's version supports migration by calling the DeviceAdminInfo method supportsTransferOwnership(). Before transferring ownership, it's the source DPC's responsibility to verify the target DPC by comparing app signatures. The PackageManager class includes methods to work with code-sign signatures.

Android maintains the source DPC's system and user policies through an ownership transfer—DPCs don't need to migrate these. A source DPC can pass custom data to the target DPC using key-value pairs in a PersistableBundle. After a successful transfer, the target DPC can retrieve this data by calling DevicePolicyManager.getTransferOwnershipBundle().

The steps to transfer ownership of a managed device or a work profile are the same:

  1. The source DPC checks that the target DPC's version supports migration and confirms that the target DPC's app signature matches an expected value.
  2. The source DPC calls transferOwnership() to start the transfer.
  3. The system makes the target DPC the active admin and sets it as the owner of the managed device or work profile.
  4. The target DPC receives the callback onTransferOwnershipComplete() and can configure itself using values from the bundle argument.
  5. If something goes wrong with the transfer, the system reverts ownership to the source DPC. If your source DPC needs to confirm that the ownership transfer succeeded, call isAdminActive() to check that the source DPC is no longer the active admin.

All apps running in the work profile receive the ACTION_PROFILE_OWNER_CHANGED broadcast when the profile owner changes. Apps running on a managed device receive the ACTION_DEVICE_OWNER_CHANGED broadcast when the device owner changes.

Work profiles on fully managed devices

Transferring two instances of a DPC running as device owner and profile owner happens in two stages. When the personal profile and work profile are affiliated, complete the transfer in the following order:

  1. First, transfer ownership of the work profile.
  2. Wait for the DeviceAdminReceiver callback onTransferAffiliatedProfileOwnershipComplete() to confirm that the work profile was transferred to the target DPC.
  3. Finally, transfer ownership of the managed device to the target DPC.

Postpone Over-the-air (OTA) updates

Device owners can postpone OTA system updates to devices for up to 90 days to freeze the OS version running on these devices over critical periods (such as holidays). The system enforces a mandatory 60-day buffer after any defined freeze period to prevent freezing the device indefinitely.

During a freeze period:

  • Devices don't receive any notifications about pending OTA updates.
  • Devices don't install any OTA updates to the OS.
  • Device users aren't able to manually check for OTA updates in Settings.

To set a freeze period, call SystemUpdatePolicy.setFreezePeriods(). Because the freeze period repeats annually, the start and end dates of the period are represented by integers counting the number of days since year start. The start day must begin at least 60 days after the end of any previous freeze period. Device owners can call SystemUpdatePolicy.getFreezePeriods() to get a list of freeze periods previously set on the system update policy object. DevicePolicyManager.getSystemUpdatePolicy() has been updated to return any freeze periods set by the device owner.

Restrict sharing into a work profile

Profile owners can prevent users from sharing personal data into a work profile on the device by adding the user restriction DISALLOW_SHARE_INTO_MANAGED_PROFILE. This restriction prevents the following intent handling and sharing:

  • Personal profile apps sharing data and files with work profile apps.
  • Work profile apps picking items from the personal profile—for example, pictures or files.

After setting this restriction, your DPC can still permit cross-profile Activity intents by calling addCrossProfileIntentFilter().

Hardware-secured keys and machine certificates

Android 9 adds APIs to help you work with keys and certificates that you can combine to securely identify devices. A DPC running in profile owner or device owner modes, or a delegated certificate installer, can complete the following tasks:

By combining these APIs, enterprises can securely identify devices and confirm their integrity before providing access:

  1. The Android device generates a new private key in the secure hardware. Because the private key never leaves the secure hardware, it remains secret.
  2. The device uses the key to create and send a certificate signing request (CSR) to the server. The CSR includes the attestation record containing the device IDs.
  3. The server validates the certificate chain (rooted to a Google certificate) and extracts the device metadata from the attestation record.
  4. The server confirms that the secure hardware protects the private key and that the device IDs match the enterprise's records. The server can also check that the Android system and patch versions meet any requirements.
  5. The server generates a certificate from the CSR and sends the certificate to the device.
  6. The device pairs the certificate with the private key (that's remained in the secure hardware) enabling apps to connect to enterprise services.

More security APIs, features, and changes

IDs for security logs and network logs

Android 9 includes IDs in security and network activity logs. The numeric ID monotonically increases for each event, making it easier for IT admins to spot gaps in their logs. Because security logs and network logs are separate collections, the system maintains separate ID values.

Call SecurityEvent.getId(), DnsEvent.getId(), or ConnectEvent.getId() to get the ID value. The system resets the ID whenever a DPC enables logging or when the device restarts. Security logs fetched by calling DevicePolicyManager.retrievePreRebootSecurityLogs() don't include these IDs.

Security logging

Security logging assigns each SecurityEvent a log level. To get the log level, call getLogLevel(). This method returns a log level value that can be one of: LEVEL_INFO, LEVEL_WARNING, or LEVEL_ERROR.

Android 9 logs the events listed in the table below into security logs. To check an event's tag, call getTag(). To retrieve the event data, call getData().

Tag Event description
TAG_CERT_AUTHORITY_INSTALLED An attempt to install a new root certificate into the system's credential storage.
TAG_CERT_AUTHORITY_REMOVED An attempt to remove a root certificate from the system's credential storage.
TAG_CERT_VALIDATION_FAILURE A Wi-Fi certificate failed a validation check during connection.
TAG_CRYPTO_SELF_TEST_COMPLETED The system completed the cryptographic self test.
TAG_KEYGUARD_DISABLED_FEATURES_SET An admin app disabled features of a device or work profile lock screen.
TAG_KEY_DESTRUCTION An attempt to delete a cryptographic key.
TAG_KEY_GENERATED An attempt to generate a new cryptographic key.
TAG_KEY_IMPORT An attempt to import a new cryptographic key.
TAG_KEY_INTEGRITY_VIOLATION Android detected a damaged encryption or authentication key.
TAG_LOGGING_STARTED Security logging started recording.
TAG_LOGGING_STOPPED Security logging stopped recording.
TAG_LOG_BUFFER_SIZE_CRITICAL The security log buffer reached 90% of its capacity.
TAG_MAX_PASSWORD_ATTEMPTS_SET An admin app set the number of allowed incorrect-password attempts.
TAG_MAX_SCREEN_LOCK_TIMEOUT_SET An admin app set a maximum screen-lock timeout.
TAG_MEDIA_MOUNT The device mounted removable storage media.
TAG_MEDIA_UNMOUNT The device unmounted removable storage media.
TAG_OS_SHUTDOWN The Android system shut down.
TAG_OS_STARTUP The Android system started up.
TAG_PASSWORD_COMPLEXITY_SET An admin app set password complexity requirements.
TAG_PASSWORD_EXPIRATION_SET An admin app set a password expiry duration.
TAG_PASSWORD_HISTORY_LENGTH_SET An admin app set a password history length, preventing users from reusing old passwords.
TAG_REMOTE_LOCK An admin app locked the device or work profile.
TAG_USER_RESTRICTION_ADDED An admin app set a user restriction.
TAG_USER_RESTRICTION_REMOVED An admin app removed a user restriction.
TAG_WIPE_FAILURE An attempt to wipe a device or work profile failed.

Work profile lock screen challenge

Beginning in Android 9, profile owners can require users to set a separate lock screen challenge for their work profile using the DISALLOW_UNIFIED_PASSWORD user restriction. To check whether a user has the same lock screen challenge set for their device and work profile, call DevicePolicyManager.isUsingUnifiedPassword().

If a device has a separate work profile lock screen, DevicePolicyManager.setMaximumTimeToLock() only sets a lock screen timeout for the work profile instead of for the entire device.

Developer tools access

To help keep work data in the work profile, the Android Debug Bridge (adb) tool can’t access directories and files in the work profile.

Support for more biometric options

Android 9 adds fine-grained control over biometric hardware authentication in a work profile's lock screen. Call the existing DevicePolicyManager.setKeyguardDisabledFeatures() method with KEYGUARD_DISABLE_FACE and KEYGUARD_DISABLE_IRIS. To disable all biometric authentication methods provided by the device, add KEYGUARD_DISABLE_BIOMETRICS.

Deprecation of device admin policies

Android 9 marks the policies listed below as deprecated for DPCs using device admin. The policies continue to function in Android 9 as they have done previously. Starting with the Android 10 release, the same policies will throw a SecurityException when invoked by a device admin.

Some applications use device admin for consumer device administration. For example, locking and wiping a lost device. The following policies will continue to be available to enable this:

For more information about these changes, read Device admin deprecation.

Streamlined QR-code enrollment

Built-in QR library

Android 9 comes bundled with a QR library to streamline QR-code device provisioning. IT admins no longer have to manually enter Wi-Fi details to set up a device. Instead, with Android 9 it's possible to include these Wi-Fi details within a QR code. When an IT admin scans the QR code with a company-owned device, the device automatically connects to Wi-Fi and enters the provisioning process without any additional manual input.

The QR-code provisioning method supports the following provisioning extras to specify Wi-Fi details:

Set date and timezone using provisioning extras

The QR-code provisioning method supports provisioning extras to set the time and timezone on a device:

Wiping data options

Device admins can show a personalized message to users when removing a work profile or secondary user. The message helps device users understand that their IT admin removed the work profile or secondary user. Call wipeData(int, CharSequence) and supply a short explanatory message. When called by the primary user or device owner, the system doesn't show a message and begins a factory reset of the device.

To remove subscription data from an embedded eUICC SIM, call wipeData() and include WIPE_EUICC in the flags argument.

Methods for affiliated profile owners

The following methods are available to affiliated profile owners: