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.
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:
- 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. - Call
getProfileSwitchingIconDrawable()
to get an icon that you can use to represent another profile. - Call
getProfileSwitchingLabel()
to get localized text that prompts the user to switch profiles. - 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:
- Call
DevicePolicyManager.setLockTaskPackages()
to allowlist apps for lock task mode. - 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:
LOCK_TASK_FEATURE_NONE
LOCK_TASK_FEATURE_SYSTEM_INFO
LOCK_TASK_FEATURE_HOME
LOCK_TASK_FEATURE_NOTIFICATIONS
can only be used in combination withLOCK_TASK_FEATURE_HOME
.LOCK_TASK_FEATURE_KEYGUARD
LOCK_TASK_FEATURE_OVERVIEW
can only be used in combination withLOCK_TASK_FEATURE_HOME
.LOCK_TASK_FEATURE_GLOBAL_ACTIONS
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:
- Set the
MAKE_USER_EPHEMERAL
flag when callingDevicePolicyManager.createAndManageUser()
. - 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:
onUserStarted()
: Called when a user starts.onUserSwitched()
: Called when a user switch is completed.onUserStopped()
: Called along withonUserRemoved()
when a user stops or logs out.
Display event messages to users
Device owners can configure the messages that are displayed to users when they start and end their sessions:
- Use
DevicePolicyManager.setStartUserSessionMessage()
to set the message that's displayed to a user when the user's session begins. To retrieve the message, callDevicePolicyManager.getStartUserSessionMessage()
. - Use
DevicePolicyManager.setEndUserSessionMessage()
to set the message that's displayed to the user when the user's session ends. To retrieve the message, callDevicePolicyManager.getEndUserSessionMessage()
.
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:
Call
DevicePolicyManager.setKeepUninstalledPackages()
to specify the list of packages to keep as APKs. To retrieve a list of these packages, callDevicePolicyManager.getKeepUninstalledPackages()
.Call
DevicePolicyManager.installExistingPackage()
to install a package that has been kept after removal viasetKeepUninstalledPackages()
.
Additional methods and constants
Android 9 also includes the following methods and constants to further support user sessions on shared devices:
DevicePolicyManager.getSecondaryUsers()
gets a list of all secondary users on a device.DISALLOW_USER_SWITCH
is a user restriction you can enable by callingDevicePolicyManager.addUserRestriction()
to block user switching.LEAVE_ALL_SYSTEM_APPS_ENABLED
is a flag available forDevicePolicyManager.createAndManageUser()
. When set, system apps aren't disabled during user provisioning.UserManager.UserOperationException
is thrown byDevicePolicyManager.createAndManageUser()
when a user can't be created—the exception contains the reason for the failure.
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:
addOverrideApn()
updateOverrideApn()
removeOverrideApn()
getOverrideApns()
setOverrideApnEnabled()
isOverrideApnEnabled()
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:
DISALLOW_AIRPLANE_MODE
DISALLOW_AMBIENT_DISPLAY
DISALLOW_CONFIG_BRIGHTNESS
DISALLOW_CONFIG_DATE_TIME
DISALLOW_CONFIG_LOCATION
DISALLOW_CONFIG_SCREEN_TIMEOUT
DISALLOW_PRINTING
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:
- 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.
- The source DPC calls
transferOwnership()
to start the transfer. - The system makes the target DPC the active admin and sets it as the owner of the managed device or work profile.
- The target DPC receives the callback
onTransferOwnershipComplete()
and can configure itself using values from thebundle
argument. - 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:
- First, transfer ownership of the work profile.
- Wait for the
DeviceAdminReceiver
callbackonTransferAffiliatedProfileOwnershipComplete()
to confirm that the work profile was transferred to the target DPC. - 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:
- Generate keys and certificates in the secure hardware (such as a trusted
execution environment (TEE) or Secure Element (SE)) of the Android device. The
generated keys never leave the secure hardware and can be used from the Android
KeyChain. Call
DevicePolicyManager.generateKeyPair()
supplying the algorithm (seeKeyPairGenerator
) and any hardware IDs you want attested, such as the serial number or IMEI. To learn more about secure hardware changes, see the Android 9 Security enhancements. - Associate a certificate with an existing device-generated key. Call
DevicePolicyManager.setKeyPairCertificate()
supplying the alias of the existing key and the certificate chain—starting with the leaf certificate and including the chain of trust in order. - Confirm that the secure hardware protects the key before using it. To check which mechanisms protect the key, follow the steps in Key Attestation.
- Device owners and delegated certificate installers can receive a signed
statement of the devices' hardware IDs with Android system versions. Call
DevicePolicyManager.generateKeyPair()
passing one or more ofID_TYPE_BASE_INFO
,ID_TYPE_SERIAL
,ID_TYPE_IMEI
, orID_TYPE_MEID
in theidAttestationFlags
argument. The returned certificate includes the hardware IDs in the attestation record. If you don't want the hardware IDs included, pass0
. Profile owners can only receive manufacturer information (by passingID_TYPE_BASE_INFO
). To check that the device can attest IDs, callisDeviceIdAttestationSupported()
. - Prevent device users from misusing enterprise keys (in non-enterprise tasks)
by making the key certificates unselectable. The system doesn't include
unselectable certificates in the picker panel. In your
DeviceAdminReceiver.onChoosePrivateKeyAlias()
callback method, return the alias to your enterprise key so that the system automatically selects the certificate on behalf of the user. To make a key unselectable, call the followingDevicePolicyManager
methods:setKeyPairCertificate()
and passfalse
for theisUserSelectable
argument.installKeyPair (ComponentName, PrivateKey, Certificate[], String, int)
and omitINSTALLKEY_SET_USER_SELECTABLE
from theflags
argument.
By combining these APIs, enterprises can securely identify devices and confirm their integrity before providing access:
- The Android device generates a new private key in the secure hardware. Because the private key never leaves the secure hardware, it remains secret.
- 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.
- The server validates the certificate chain (rooted to a Google certificate) and extracts the device metadata from the attestation record.
- 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.
- The server generates a certificate from the CSR and sends the certificate to the device.
- 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.
USES_POLICY_DISABLE_CAMERA
USES_POLICY_DISABLE_KEYGUARD_FEATURES
USES_POLICY_EXPIRE_PASSWORD
USES_POLICY_LIMIT_PASSWORD
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:
EXTRA_PROVISIONING_WIFI_HIDDEN
EXTRA_PROVISIONING_WIFI_PAC_URL
EXTRA_PROVISIONING_WIFI_PASSWORD
EXTRA_PROVISIONING_WIFI_PROXY_BYPASS
EXTRA_PROVISIONING_WIFI_PROXY_HOST
EXTRA_PROVISIONING_WIFI_PROXY_PORT
EXTRA_PROVISIONING_WIFI_SECURITY_TYPE
EXTRA_PROVISIONING_WIFI_SSID
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:
DevicePolicyManager.setKeyguardDisabled()
DevicePolicyManager.setStatusBarDisabled()
PackageInstaller.createSession()