This page provides an overview of the new enterprise APIs, features, and
behavior changes introduced in Android 10.

## Work profiles for company-owned devices

Android 10 introduces new provisioning and attestation features for
company-owned devices that only require a work profile.

### Improved provisioning tools for work profiles

You can provision work profiles on Android 10 and later devices enrolled using
[QR code](https://developers.google.com/android/work/requirements?api=playemm#14-qr-code-device-provisioning)
or [Zero touch](https://developers.google.com/android/work/requirements?api=playemm#15-zero-touch-enrollment).
During the provisioning of a company-owned device, a new intent extra allows
device policy controller apps (DPCs) to initiate work profile *or* fully managed
setup. After a work profile is created or full management is established, DPCs
must launch policy compliance screens to enforce any initial policies.
| **Important:** This features doesn't affect existing DPC implementations that only support fully managed provisioning---they'll still work on Android 10 and later devices.

In your DPC's manifest file, declare a new intent filter for
[`GET_PROVISIONING_MODE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#ACTION_GET_PROVISIONING_MODE)
in an activity and add the [`BIND_DEVICE_ADMIN`](https://developer.android.com/reference/android/Manifest.permission#BIND_DEVICE_ADMIN)
permission to prevent arbitrary apps from starting the activity. For example:  

    <activity
        android:name=".GetProvisioningModeActivity"
        android:label="@string/app_name"
        android:permission="android.permission.BIND_DEVICE_ADMIN">
        <intent-filter>
            <action
                android:name="android.app.action.GET_PROVISIONING_MODE" />
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>

During provisioning, the system launches the activity associated with the
intent filter. The purpose of this activity is to specify a management mode
(work profile or fully managed).

It may be useful to retrieve provisioning extras before determining the
appropriate management mode for the device. The activity can call
[`getIntent()`](https://developer.android.com/reference/android/app/Activity#getIntent()) to retrieve
the following:

- [`EXTRA_PROVISIONING_IMEI`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_IMEI)
- [`EXTRA_PROVISIONING_SERIAL_NUMBER`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_SERIAL_NUMBER)
- [`EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE)

DPCs can also create a new result intent and add the following extras to it:

- [`EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE): Add to the existing bundle or create a new bundle. This bundle is sent as an intent extra when your DPC launches its policy compliance screens.
- [`EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE): Only specify an account to migrate if adding a work account as part of work profile provisioning.
- [`EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS)

To set the management mode on the device, call
`putExtra(DevicePolicyManager.EXTRA_PROVISIONING_MODE,desiredProvisioningMode)`,
where `desiredProvisioningMode` is:

- Work profile: `PROVISIONING_MODE_MANAGED_PROFILE`
- Fully managed: `PROVISIONING_MODE_FULLY_MANAGED_DEVICE`

Complete work profile or fully managed provisioning by sending provisioning
details back to setup via [`setResult(RESULT_OK,
Intent)`](https://developer.android.com/reference/android/app/Activity#setResult(int,%20android.content.Intent))
and close all active screens with
[`finish()`](https://developer.android.com/reference/android/app/Activity#finish()).
| **Note:** To prevent failed provisioning, don't launch any activities or background services after returning to setup.

After provisioning is complete, a new Intent is available for DPCs to launch
their compliance screens and enforce initial policy settings. On work profile
devices, compliance screens are displayed in the work profile. Your DPC must
ensure that its compliance screens are shown to users, even if a user escapes
the setup flow.

In your DPC's manifest file, declare a new intent filter for
[`ADMIN_POLICY_COMPLIANCE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#ACTION_ADMIN_POLICY_COMPLIANCE)
in an activity and add the [`BIND_DEVICE_ADMIN`](https://developer.android.com/reference/android/Manifest.permission#BIND_DEVICE_ADMIN)
permission to prevent arbitrary apps from starting the activity. For example:  

    <activity
        android:name=".PolicyComplianceActivity"
        android:label="@string/app_name"
        android:permission="android.permission.BIND_DEVICE_ADMIN">
        <intent-filter>
            <action android:name="android.app.action.ADMIN_POLICY_COMPLIANCE" />
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>

Your DPC **must** use this new Intent instead of listening for the
[`ACTION_PROFILE_PROVISIONING_COMPLETE`](https://developer.android.com/reference/android/app/admin/DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE)
broadcast.

The activity associated with the intent filter can call
[`getIntent()`](https://developer.android.com/reference/android/app/Activity#getIntent()) to retrieve
the
[`EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE).
After performing policy compliance, `ADMIN_POLICY_COMPLIANCE` must return [`setResult(RESULT_OK,
Intent)`](https://developer.android.com/reference/android/app/Activity#setResult(int,%20android.content.Intent)) and close all active screens with
[`finish()`](https://developer.android.com/reference/android/app/Activity#finish()).

Fully managed devices return users to the homescreen. Work profile devices
prompt users to add their personal account before returning them to the home
screen.

### Work-profile device-ID attestation

DPCs set as the admin of a work profile provisioned using zero-touch enrollment
can get secure-hardware-attested device IDs, such as an IMEI or manufacturer's
serial number. The device must include secure hardware (such as a trusted
execution environment (TEE) or Secure Element (SE)) and support device-ID
attestation and zero-touch enrollment.

The admin component of a work profile can call [`DevicePolicyManager.generateKeyPair()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#generateKeyPair(android.content.ComponentName,%20java.lang.String,%20android.security.keystore.KeyGenParameterSpec,%20int)), passing one or more of [`ID_TYPE_SERIAL`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#ID_TYPE_SERIAL), [`ID_TYPE_IMEI`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#ID_TYPE_IMEI), or [`ID_TYPE_MEID`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#ID_TYPE_MEID) for the `idAttestationFlags` argument.

To learn more about extracting and validating device IDs, see [Verifying hardware-backed key pairs with Key Attestation](https://developer.android.com/training/articles/security-key-attestation).

## Work profile improvements

New APIs are available for supporting cross-profile calendar visibility and
device-wide blocking of app installations from unknown sources.

### Work profile, device-wide unknown sources

Apps downloaded from sources other than Google Play (or other trusted app
stores) are called apps from unknown sources. In Android 10, admins of work
profiles can prevent any user or profile from installing apps from unknown
sources anywhere on the device by adding the new user restriction
[`DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY`](https://developer.android.com/reference/android/os/UserManager#DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY).
After adding this restriction, however, a person using the device can still
install apps using [adb](https://developer.android.com/studio/command-line/adb).

To prevent users from mistakenly installing apps from unknown sources, we
recommend adding this user restriction because it doesn't require Google Play
services to be installed. If you want to support older Android versions, you can
set a [managed configuration value for Google Play](https://developer.android.com/work/dpc/security#unknown-sources).

### Limit permitted input devices to work profiles

When admins of work profiles call [`DevicePolicyManager.setPermittedInputMethods()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#setPermittedInputMethods(android.content.ComponentName,%20java.util.List%3Cjava.lang.String%3E)), users are only restricted to the permitted input methods inside their work
profile instead of the entire device, giving users full control over input
methods on the personal side of their device.

### Silently wipe work profiles

Added [`WIPE_SILENTLY`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#WIPE_SILENTLY)
flag to [`DevicePolicyManager.wipeData()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#wipeData(int)).
If the flag is set, users won't be notified after their work profile is wiped
using [`wipeData()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#wipeData(int)).

## New features for fully managed devices

Android 10 introduces new features and APIs for fully managed devices,
including manual system updates, extending QR-code and NFC provisioning to
include the credentials for an EAP Wi-Fi network, and support for DNS over TLS.

### Manual system update installation

In Android 10, admins of fully managed devices can install system updates via
a system update file. Manual system updates allow IT admins to do the following:

- Test an update on a small number of devices before installing them widely.
- Avoid duplicate downloads on bandwidth-limited networks.
- Stagger installations, or update devices only when they're not being used.

First, an IT admin sets a [postponed system-update policy](https://developer.android.com/work/dpc/system-updates#set-policy)
to delay automatic installation (if required). Next, a device's DPC calls [`installSystemUpdate()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#installSystemUpdate(android.content.ComponentName,%20android.net.Uri,%20java.util.concurrent.Executor,%20android.app.admin.DevicePolicyManager.InstallUpdateCallback))
with the path to a device manufacturer's system update file. Pass an [`InstallSystemUpdateCallback`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager.InstallSystemUpdateCallback)
object that the system can use to report errors that happen before the device
restarts. If something goes wrong, the system calls [`onInstallUpdateError()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager.InstallUpdateCallback#onInstallUpdateError(int,%20java.lang.String))
with the error code.

After the device restarts, your DPC needs to confirm a successful installation
using a version API, such as
[`Build.FINGERPRINT`](https://developer.android.com/reference/android/os/Build#FINGERPRINT). If the update
fails, report the failure to an IT admin.

### EAP Wi-Fi provisioning

In Android 10, QR codes and NFC data used for device provisioning can contain
EAP config and credentials---including certificates. When a person scans a QR code
or taps an NFC tag, the device automatically authenticates to a local Wi-Fi
network using EAP and starts the provisioning process without any additional
manual input.

To authenticate Wi-Fi using EAP, add an
[`EXTRA_PROVISIONING_WIFI_SECURITY_TYPE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_WIFI_SECURITY_TYPE)
extra with the value `"EAP"`. To specify the EAP authentication, you can add the
following provisioning extras to your intent:

- [`EXTRA_PROVISIONING_WIFI_EAP_METHOD`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_WIFI_EAP_METHOD)
- [`EXTRA_PROVISIONING_WIFI_IDENTITY`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_WIFI_IDENTITY)
- [`EXTRA_PROVISIONING_WIFI_ANONYMOUS_IDENTITY`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_WIFI_ANONYMOUS_IDENTITY)
- [`EXTRA_PROVISIONING_WIFI_DOMAIN`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_WIFI_DOMAIN)
- [`EXTRA_PROVISIONING_WIFI_PHASE2_AUTH`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_WIFI_PHASE2_AUTH)
- [`EXTRA_PROVISIONING_WIFI_USER_CERTIFICATE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_WIFI_USER_CERTIFICATE)
- [`EXTRA_PROVISIONING_WIFI_CA_CERTIFICATE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PROVISIONING_WIFI_CA_CERTIFICATE)

### Private DNS support

Organizations can use [DNS over TLS](https://android-developers.googleblog.com/2018/04/dns-over-tls-support-in-android-p.html)
(called *Private DNS* on Android devices) to avoid leaking DNS queries,
including those of internal hostnames. Admin components of fully managed devices
can control the Private DNS settings of the device. To set the Private DNS mode,
call:

- [`setGlobalPrivateDnsModeOpportunistic()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#setGlobalPrivateDnsModeOpportunistic(android.content.ComponentName)) for the device to use private DNS when the system can discover a supporting name server, or
- [`setGlobalPrivateDnsModeSpecifiedHost()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#setGlobalPrivateDnsModeSpecifiedHost(android.content.ComponentName,%20java.lang.String)) to specify the hostname of a name server that supports [RFC7858](https://tools.ietf.org/html/rfc7858) in the `privateDnsHost` argument.

When your DPC calls either of these methods, the system returns [`PRIVATE_DNS_SET_NO_ERROR`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#PRIVATE_DNS_SET_NO_ERROR) if
the call was successful. Otherwise it returns an error.

To retrieve the Private DNS mode and host set on a device, call [`getGlobalPrivateDnsMode()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#getGlobalPrivateDnsMode(android.content.ComponentName))
and [`getGlobalPrivateDnsHost()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#getGlobalPrivateDnsHost(android.content.ComponentName)).
You can prevent users from changing private DNS settings by adding the
[`DISALLOW_CONFIG_PRIVATE_DNS`](https://developer.android.com/reference/android/os/UserManager#DISALLOW_CONFIG_PRIVATE_DNS)
user restriction.

## VPN lockdown mode exemption

VPN lockdown mode allows a DPC to [block any network
traffic](https://developer.android.com/guide/topics/connectivity/vpn#blocked_connections) that doesn't use
the VPN. [Admins](https://developer.android.com/reference/android/app/admin/DeviceAdminReceiver) of fully
managed devices and work profiles can exempt apps from lockdown mode.
Exempted apps use a VPN by default, but automatically connect to other
networks if the VPN isn't available. Exempted apps that are also [explicitly
denied access the
VPN](https://developer.android.com/reference/android/net/VpnService.Builder#addDisallowedApplication(java.lang.String))
will only use other networks.

To exempt an app from lockdown mode, call the new
[`DevicePolicyManager`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager) method
[`setAlwaysOnVpnPackage()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#setAlwaysOnVpnPackage(android.content.ComponentName,%20java.lang.String,%20boolean,%20java.util.List%3Cjava.lang.String%3E))
that accepts a list of exempted app packages. Any app packages the DPC adds
must be installed on the device when the method is called. If an app is
uninstalled and reinstalled, the app must be exempted again. To get the apps
previously exempted from lockdown mode, call
[`getAlwaysOnVpnLockdownWhitelist()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#getAlwaysOnVpnLockdownWhitelist(android.content.ComponentName)).

To help admins of fully managed devices and work profiles get the lockdown mode
status, Android 10 adds the
[`isAlwaysOnVpnLockdownEnabled()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#isAlwaysOnVpnLockdownEnabled(android.content.ComponentName))
method.

## New delegation scopes

Android 10 extends the list of functions that a DPC can delegate to other, more
specialized apps. Android groups the API methods needed for a task into
*scopes* . To delegate a scope, call
[`setDelegatedScopes()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#setDelegatedScopes(android.content.ComponentName,%20java.lang.String,%20java.util.List%3Cjava.lang.String%3E))
and pass one or more of the following scopes:

- [`DELEGATION_NETWORK_LOGGING`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#DELEGATION_NETWORK_LOGGING) to delegate [network activity logging](https://developer.android.com/work/versions/android-10#network-activity-logging)
- [`DELEGATION_CERT_SELECTION`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#DELEGATION_CERT_SELECTION) to delegate [certificate selection](https://developer.android.com/work/versions/android-10#certificate-selection)

Android 10 introduces the new class
[`DelegatedAdminReceiver`](https://developer.android.com/reference/android/app/admin/DelegatedAdminReceiver)
for delegate apps. The system uses this broadcast receiver to send DPC-like
callbacks to delegate apps. Apps that have been delegated network activity
logging and certificate selection should implement this class. To add this
component to a delegate app, follow these steps:

1. Add a subclass of [`DelegatedAdminReceiver`](https://developer.android.com/reference/android/app/admin/DelegatedAdminReceiver) to the delegate app.
2. Declare the [`<receiver>`](https://developer.android.com/guide/topics/manifest/receiver-element) in the app manifest, adding an intent-filter action for each callback. For example, [`ACTION_NETWORK_LOGS_AVAILABLE`](https://developer.android.com/reference/android/app/admin/DeviceAdminReceiver#ACTION_NETWORK_LOGS_AVAILABLE) or [`ACTION_CHOOSE_PRIVATE_KEY_ALIAS`](https://developer.android.com/reference/android/app/admin/DeviceAdminReceiver#ACTION_CHOOSE_PRIVATE_KEY_ALIAS).
3. Protect the broadcast receiver with the [`BIND_DEVICE_ADMIN`](https://developer.android.com/reference/android/Manifest.permission#BIND_DEVICE_ADMIN) permission.

The following snippet shows the app manifest of a single delegate app that
handles both network logging and certificate selection:  

    <receiver android:name=".app.DelegatedAdminReceiver"
            android:permission="android.permission.BIND_DELEGATED_ADMIN">
        <intent-filter>
            <action android:name="android.app.admin.action.NETWORK_LOGS_AVAILABLE">
            <action android:name="android.app.action.CHOOSE_PRIVATE_KEY_ALIAS">
        </intent-filter>
        </receiver>

### Network activity logging

To help organizations detect and track malware, DPCs can [log TCP connections
and DNS lookups](https://developer.android.com/work/dpc/logging) by the system. In Android 10,
[admins](https://developer.android.com/reference/android/app/admin/DeviceAdminReceiver) of fully managed
devices can delegate network logging to a specialized app.

To [retrieve network logs](https://developer.android.com/work/dpc/logging#retrieve_logs) after the system
makes a batch available, delegate apps should first subclass
[`DelegatedAdminReceiver`](https://developer.android.com/reference/android/app/admin/DelegatedAdminReceiver)
(described previously). In your subclass, implement the
[`onNetworkLogsAvailable()`](https://developer.android.com/reference/android/app/admin/DelegatedAdminReceiver#onNetworkLogsAvailable(android.content.Context,%20android.content.Intent,%20long,%20int))
callback by following the guidance in [Retrieve logs](https://developer.android.com/work/dpc/logging#retrieve_logs).

Delegate apps can call the following
[`DevicePolicyManager`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager) methods
(passing `null` for the `admin` argument):

- [`setNetworkLoggingEnabled()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#setNetworkLoggingEnabled(android.content.ComponentName,%20boolean))
- [`isNetworkLoggingEnabled()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#isNetworkLoggingEnabled(android.content.ComponentName))
- [`retrieveNetworkLogs()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#retrieveNetworkLogs(android.content.ComponentName,%20long))

To avoid losing logs, DPC's shouldn't [enable network logging](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#setNetworkLoggingEnabled(android.content.ComponentName,%20boolean))
if planning to delegate to another app. The delegate app should enable and
collect network logs. After a DPC delegates network logging, it won't receive
any further [`onNetworkLogsAvailable()`](https://developer.android.com/reference/android/app/admin/DeviceAdminReceiver#onNetworkLogsAvailable(android.content.Context,%20android.content.Intent,%20long,%20int))
callbacks.

To learn how to report network activity logging from a delegate app, read the
developer's guide [Network activity logging](https://developer.android.com/work/dpc/logging).

### Certificate selection

In Android 10, [admins](https://developer.android.com/reference/android/app/admin/DeviceAdminReceiver) of
fully managed devices, work profiles, and secondary users can delegate
certificate selection to a specialized app.

To select a certificate alias, delegate apps should first subclass
[`DelegatedAdminReceiver`](https://developer.android.com/reference/android/app/admin/DelegatedAdminReceiver)
(described previously). In your subclass, implement the
[`onChoosePrivateKeyAlias()`](https://developer.android.com/reference/android/app/admin/DelegatedAdminReceiver#onChoosePrivateKeyAlias(android.content.Context,%20android.content.Intent,%20int,%20android.net.Uri,%20java.lang.String)) callback and return an alias for a preferred
certificate or, to prompt the user to select a certificate, return `null`.

## Deprecation of device admin policies

Android 10 prevents apps and DPCs from applying legacy [device
admin](https://developer.android.com/work/device-admin) policies. We recommend customers
and partners transition to fully managed devices or work profiles. The following
policies throw a [`SecurityException`](https://developer.android.com/reference/java/lang/SecurityException)
when invoked by a device admin targeting Android 10:

- [`USES_POLICY_DISABLE_CAMERA`](https://developer.android.com/reference/android/app/admin/DeviceAdminInfo#USES_POLICY_DISABLE_CAMERA)
- [`USES_POLICY_DISABLE_KEYGUARD_FEATURES`](https://developer.android.com/reference/android/app/admin/DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES)
- [`USES_POLICY_EXPIRE_PASSWORD`](https://developer.android.com/reference/android/app/admin/DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD)
- [`USES_POLICY_LIMIT_PASSWORD`](https://developer.android.com/reference/android/app/admin/DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD)

| **Note:** As a replacement for the keyguard and password policies listed above, apps should use the method described in [Screen lock quality check](https://developer.android.com/work/versions/android-10#screen_lock_quality_check).

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

- [`USES_POLICY_WIPE_DATA`](https://developer.android.com/reference/android/app/admin/DeviceAdminInfo#USES_POLICY_WIPE_DATA)
- [`USES_POLICY_FORCE_LOCK`](https://developer.android.com/reference/android/app/admin/DeviceAdminInfo#USES_POLICY_FORCE_LOCK)
- [`USES_POLICY_RESET_PASSWORD`](https://developer.android.com/reference/android/app/admin/DeviceAdminInfo#USES_POLICY_RESET_PASSWORD)

For more information about these changes, read [Device admin
deprecation](https://developers.google.com/android/work/device-admin-deprecation).

## New features for apps

Apps targeting Android 10 can query the screen lock complexity set on a device
before displaying confidential data or launching critical features. Apps calling
the [`KeyChain`](https://developer.android.com/reference/android/security/KeyChain) API benefit from
behavior improvements, while new features are also available for VPN apps.

### Screen lock quality check

Starting in Android 10, apps with critical features that require a screen lock
can query a device or work profile's screen lock complexity. Apps needing a
stronger screen lock can direct the user to the system screen lock settings,
allowing them to update their security settings.

To check screen lock quality:

- Add the new `REQUEST_PASSWORD_COMPLEXITY` permission to your app's manifest.
- Call [`DevicePolicyManager.getPasswordComplexity()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#getPasswordComplexity()). Complexity is divided into four categories:
  - [`PASSWORD_COMPLEXITY_NONE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#PASSWORD_COMPLEXITY_NONE)
  - [`PASSWORD_COMPLEXITY_LOW`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#PASSWORD_COMPLEXITY_LOW)
  - [`PASSWORD_COMPLEXITY_MEDIUM`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#PASSWORD_COMPLEXITY_MEDIUM)
  - [`PASSWORD_COMPLEXITY_HIGH`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#PASSWORD_COMPLEXITY_HIGH)

To launch system screen lock settings, use
[`ACTION_SET_NEW_PASSWORD`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#ACTION_SET_NEW_PASSWORD)
with extra [`EXTRA_PASSWORD_COMPLEXITY`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#EXTRA_PASSWORD_COMPLEXITY)---options that don't
meet the complexity specified in the intent extra are grayed out. Users can
choose from the available screen lock options or exit the screen.

**Best practice:** Display a message in your app before launching the system
screen lock page. When your app resumes, call
[`DevicePolicyManager.getPasswordComplexity()`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#getPasswordComplexity())
again. If a stronger screen lock is still required, restrict access rather than
repeatedly prompting users to update their security settings.

### HTTP proxy support in VPN apps

In Android 10, [VPN apps](https://developer.android.com/guide/topics/connectivity/vpn) can set an HTTP proxy
for their VPN connection. To add an HTTP proxy, a VPN app must configure a
[`ProxyInfo`](https://developer.android.com/reference/android/net/ProxyInfo) instance with a host and port,
before calling
[`VpnService.Builder.setHttpProxy()`](https://developer.android.com/reference/android/net/VpnService.Builder#setHttpProxy(android.net.ProxyInfo)).
The system and many networking libraries use this proxy setting but the system
doesn't force apps to proxy HTTP requests.

For sample code that shows how to set an HTTP proxy, see the
[ToyVPN](https://android.googlesource.com/platform/development/+/master/samples/ToyVpn/src/com/example/android/toyvpn/ToyVpnConnection.java#349)
sample app.

### VPN service modes

VPN apps can discover if the service is running because of [always-on
Vpn](https://developer.android.com/guide/topics/connectivity/vpn#always-on) and if [lockdown
mode](https://developer.android.com/guide/topics/connectivity/vpn#blocked_connections) is active. New methods
added in Android 10 can help you adjust your user interface. For example, you
might disable your disconnect button when always-on VPN controls the lifecycle
of your service.

VPN apps can call the following [`VpnService`](https://developer.android.com/reference/android/net/VpnService)
methods after [connecting to the service](https://developer.android.com/guide/topics/connectivity/vpn#connect_a_service)
and establishing the local interface:

- [`isAlwaysOn()`](https://developer.android.com/reference/android/net/VpnService#isAlwaysOn()) to find out if the system started the service because of always-on VPN
- [`isLockdownEnabled()`](https://developer.android.com/reference/android/net/VpnService#isLockdownEnabled()) to find out if the system is blocking connections that don't use the VPN

The always-on status remains the same while your service is running but the
lockdown-mode status might change.

### Keychain improvements

Android 10 introduces several improvements related to the
[`KeyChain`](https://developer.android.com/reference/android/security/KeyChain) API.

When an app calls `KeyChain.choosePrivateKeyAlias()`, Android 10 and later
devices filter the list of certificates a user can choose from based on the
issuers and key algorithms specified in the call.

For example, when a TLS server sends a [Certificate Request](https://tools.ietf.org/html/rfc8446#section-4.3.2)
message as part of a TLS handshake and the browser calls
`KeyChain.choosePrivateKeyAlias()`, the certificate selection prompt only
includes options that match the issuers parameter. If no matching options are
available or there are no certificates installed on the device, then the
selection prompt won't be displayed to the user.

Additionally, [`KeyChain`](https://developer.android.com/reference/android/security/KeyChain) no longer
requires a device to have a screen lock before keys or CA certificates can be
imported.