# Provision devices

There are several ways to provision devices. Your customers' business
requirements determine which provisioning methods you'll want to use.

## Device provisioning basics

The device provisioning deployment scenarios that your customers want to
support (such as BYOD or company-owned) determine the modes of operation you'll
use (such as device owner mode or profile owner mode). Similarly, the modes of
operation and Android releases you need to support determine which provisioning
methods you'll implement.

### Deployment scenarios

In a **company-owned** deployment scenario, the enterprise owns and
fully controls the devices its employees use. Typically, organizations deploy
company-owned devices when they need to strictly monitor and manage the whole
device.

Companies that support a **BYOD** deployment scenario allow their
employees to bring personally-owned devices to work, and to use those devices to
access privileged company information and applications.

### Modes of operation

Company-owned deployments are supported by the **device owner** mode
of operation. In Android, your management app is called the device policy
controller (DPC). The DPC enforces policies on an Android-powered device and
when it acts as the device owner, it manages the entire device. As device owner,
the DPC can perform device-wide actions, such as configure device-wide
connectivity, configure global settings, and perform a factory reset.

BYOD deployments are supported by the **profile owner** mode of
operation. Through the DPC, the enterprise enables personal devices for work use
by adding a work profile to the primary user account on the device. The work
profile is associated with the primary user, but as a separate profile. As
profile owner, the DPC manages only the work profile on the device and has
limited control outside of the work profile.

## Device owner provisioning methods

You must provision the device owner mode of operation during the initial setup
of a new device or after a factory reset. Device owner mode can't be provisioned
on a device at any other time.

Depending on the use case, there are 2 main types of provisioning methods for
provisioning device owner mode.

- In a *device-driven* flow, IT admins can use **NFC** to provision large numbers of devices. This flow can be used for managed Google Play Account or Google Workspace scenarios.
- In a *user-driven* flow, the options depend on whether the organization uses Google Workspace.
  - In a Google Workspace scenario, the user adds their **Google Account** during initial device setup, and the DPC must guide the user through the steps to set up the device owner. A user-driven flow can help end users set up new devices and also is an alternative when devices don't support NFC.
  - When an organization doesn't use Google Workspace, you should use the **managed Google Play Accounts** method.

**Note:** If you limit distribution of your app to specific countries in
[Play](https://support.google.com/googleplay/android-developer/answer/7550024),
these restrictions are ignored during device owner provisioning.
The DPC will be downloaded even if the device is not in a targeted country.

### Profile owner provisioning methods

The recommended method to provision the profile owner mode of operation depends
on whether the organization uses Google Workspace.

- In the Google Workspace case, the recommended method is a user-driven flow where the user adds their user **Google Account**, and the DPC guides the user through the steps to set up the profile owner.
- When an organization doesn't use Google Workspace, the recommended method is the **managed Google Play Accounts** method.

The traditional method, where the user is instructed to
**manually install the DPC**, is also supported.
It relies on the user to download your DPC from Google Play and install it,
and then the DPC guides the user through the rest of the process to set up the
profile owner.

### Key provisioning differences across Android versions

| **Deployment scenario** | **Mode of operation** | **Provisioning method** | 5.0, 5.1 | 6.0 | 7.0 | 8.0 | 11 | 12+ |
|---|---|---|---|---|---|---|---|---|
| Company-owned | Device Owner | [QR code](https://developers.google.com/android/work/play/emm-api/prov-devices#qr_code_method) |   |   | ✓ | ✓ | ✓ | ✓ |
|   |   | [Managed Google Play Accounts](https://developers.google.com/android/work/play/emm-api/prov-devices#managed_google_play_accounts_method) |   | ✓ | ✓ | ✓ | ✓ | ✓ |
|   |   | [Google Account](https://developers.google.com/android/work/play/emm-api/prov-devices#google_account_method) |   | ✓ | ✓ | ✓ | ✓ | ✓ |
|   |   | [NFC](https://developers.google.com/android/work/play/emm-api/prov-devices#nfc_method) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|   |   | [Zero Touch](https://developers.google.com/android/work/play/emm-api/zero-touch-iframe) |   |   |   | ✓ | ✓ | ✓ |
| Company-owned | Profile Owner | [QR code](https://developers.google.com/android/work/play/emm-api/prov-devices#qr_code_method) |   |   |   |   | ✓ | ✓ |
|   |   | [Managed Google Play Accounts](https://developers.google.com/android/work/play/emm-api/prov-devices#managed_google_play_accounts_method) |   |   |   |   | ✓ | ✓ |
|   |   | [Google Account](https://developers.google.com/android/work/play/emm-api/prov-devices#google_account_method) |   |   |   |   | ✓ | ✓ |
|   |   | [NFC](https://developers.google.com/android/work/play/emm-api/prov-devices#nfc_method) |   |   |   |   |   | ✓ |
|   |   | [Zero Touch](https://developers.google.com/android/work/play/emm-api/zero-touch-iframe) |   |   |   |   | ✓ | ✓ |
| BYOD | Profile Owner | [Managed Google Play Accounts](https://developers.google.com/android/work/play/emm-api/prov-devices#managed_google_play_accounts_method) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|   |   | [Google Account](https://developers.google.com/android/work/play/emm-api/prov-devices#google_account_method) | 5.1^[1](https://developers.google.com/android/work/play/emm-api/prov-devices#fn1)^ | ✓ | ✓ | ✓ | ✓ | ✓ |
|   |   | [Manual DPC install](https://developers.google.com/android/work/play/emm-api/prov-devices#manual_dpc_install_method) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|   |   | [Zero Touch](https://developers.google.com/android/work/play/emm-api/zero-touch-iframe) |   |   |   | ✓ | ✓ | ✓ |

## General implementation considerations

Here are some things to consider as you
[write your DPC](https://developer.android.com/work/dpc/build-dpc.html),
regardless of which mode of operation you implement.

### Google Play services compatibility

The
[Google Play services APK guide](https://developers.google.com/android/guides/setup#ensure_devices_have_the_google_play_services_apk)
instructs developers to perform a version check of Google Play services before
performing API transactions. Because attempting to update Google Play services
causes serious disruptions in the device setup process, your DPC must *not*
attempt to update Google Play services before device provisioning is complete.

Key points about DPC compatibility with Google Play services are:

- The DPC should run using the Google Play services that shipped with a particular device.
- The DPC shouldn't rely on new features in future versions of Google Play services being available at the time of device provisioning.

When device provisioning is complete, the DPC can prompt the user to update
Google Play services so the DPC can use the latest features. However, if a
feature isn't available for some reason, the DPC must fall back gracefully to
the version that shipped with the device.

### Retrieve device details

Due to propagation delays, it may take up to 2 minutes before a call to
devices.get for a newly-enrolled device will return the details of the device.

If your workflow requires the details before the end user can use the device or
work profile, we suggest using a progress screen in your DPC and waiting until
the call succeeds.

> [!NOTE]
> **Note:** You can call devices.update immediately after enrolling the device. You don't need to wait for devices.get to return the device details.

## Implementation considerations for profile owner mode

Here are some things to consider as you
[write your DPC](https://developers.google.com/android/work/dpc/build-dpc) to implement the profile owner
mode of operation.

### Remove or disable the personal DPC

When provisioning the profile owner mode of operation, the DPC starts running
in the personal profile and initiates the process to create a work profile.
Once the work profile is created, the DPC is also running inside the work
profile. The DPC in the work profile completes the provisioning process. At
that point, the DPC in the personal profile should disable itself or the device
user should remove it.

#### User removes the personal DPC

1. The personal DPC listens for [`ACTION_MANAGED_PROFILE_PROVISIONED`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_MANAGED_PROFILE_PROVISIONED). (For Android 5.1 devices, the personal DPC should instead listen for [`ACTION_MANAGED_PROFILE_ADDED`](http://developer.android.com/reference/android/content/Intent.html#ACTION_MANAGED_PROFILE_ADDED)).
2. The personal DPC initiates an uninstall request [`ACTION_UNINSTALL_PACKAGE`](http://developer.android.com/reference/android/content/Intent.html#ACTION_UNINSTALL_PACKAGE). This prompts the user to uninstall the personal DPC. For the best user experience, the uninstall process should happen during the provisioning flow.

#### Personal DPC disables itself

1. The personal DPC listens for [`ACTION_MANAGED_PROFILE_PROVISIONED`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_MANAGED_PROFILE_PROVISIONED). (For Android 5.1 devices, the personal DPC should instead listen for [`ACTION_MANAGED_PROFILE_ADDED`](http://developer.android.com/reference/android/content/Intent.html#ACTION_MANAGED_PROFILE_ADDED)).
2. If applicable, the personal DPC should release device admin privileges before disabling itself.
3. The personal DPC initiates a [`setApplicationEnabledSetting`](http://developer.android.com/reference/android/content/pm/PackageManager.html#setApplicationEnabledSetting(java.lang.String,%20int,%20int)) disable request with the [`COMPONENT_ENABLED_STATE_DISABLED`](http://developer.android.com/reference/android/content/pm/PackageManager.html#COMPONENT_ENABLED_STATE_DISABLED) parameter.
4. The user can re-enable the personal DPC from Google Play.

## Implementation considerations for device owner mode

Here are some things to consider as you [write your DPC](https://developers.google.com/android/work/dpc/build-dpc)
to implement the device owner mode of operation.

### Device must be new or factory reset

You must provision the device owner mode of operation during the initial setup
of a new device or after a factory reset. Device owner mode can't be
provisioned on a device at any other time.

Device owner mode gives the DPC complete control over a device. If provisioning
device owner mode *after* initial setup were allowed:

- Malware could potentially create a device owner and take over the device.
- Privacy issues could result if there were already some user data or apps on the device.

### Set up device owner mode only on company-owned devices

You should provision device owner mode only on devices that you identify as
being owned by your customer's company. You can verify this by detecting a
unique device identifier (such as a serial number), or by using a dedicated
set of accounts that are authorized for device enrollment through your EMM
policy.

If you can't verify company ownership of a device, you must create a fail-safe
mechanism so that device owner mode is not provisioned by mistake. For example,
you could prompt the device user to confirm or take some affirmative action
before provisioning device owner mode.

### Enable system apps

When the DPC provisions a work profile, any system apps without launcher icons
are assumed to be critical to the device and are automatically allowed to run
in the work profile. System apps that have launcher icons are considered to be
optional, and you can decide whether to enable them.

#### Enable system apps through Google Play

Users can enable system apps using [Google Play](https://support.google.com/googleplay/answer/113410) to get app updates as get
app updates as they're available.

#### Enable system apps using Android framework APIs

If you want users to see system apps as soon as they start using their devices,
enable system apps as part of the device provisioning process. The DPC enables
system apps by package name or by intent using
[`DevicePolicyManager.enableSystemApp()`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#enableSystemApp(android.content.ComponentName,%20android.content.Intent)).

There are a few ways to identify the system apps you want to enable and present
in your EMM console to IT admins.

**Create system app catalogs**

In this method, each device determines which apps are on the device and sends
this data back to the EMM console. The EMM console dynamically displays this
data when creating device policy, which allows the IT admin to manage
apps on a per-app basis.

1. If the work profile isn't provisioned yet on the device, pull a list of
   all apps with launcher icons on a device using
   [`queryIntentActivities()`](http://developer.android.com/reference/android/content/pm/PackageManager.html#queryIntentActivities(android.content.Intent,%20int)):

       private List<ResolveInfo> getAppsWithLauncher() {
         Intent i = new Intent(Intent.ACTION_MAIN);
         i.addCategory(Intent.CATEGORY_LAUNCHER);
         return getPackageManager().queryIntentActivities(i, 0);
       }

2. If the work profile is already provisioned on the device, pull a list of
   all apps in the work profile using
   [`PackageManager.GET_DISABLED_COMPONENTS`](https://developer.android.com/reference/android/content/pm/PackageManager.html#GET_DISABLED_COMPONENTS)
   and
   [`PackageManager.GET_UNINSTALLED_PACKAGES`](https://developer.android.com/reference/android/content/pm/PackageManager.html#GET_UNINSTALLED_PACKAGES).

3. Find system apps in the apps list by checking
   [`FLAG_SYSTEM`](http://developer.android.com/reference/android/content/pm/ApplicationInfo.html#FLAG_SYSTEM),
   which indicates if an app is installed in the device's system image.

Advantages:

- Provides IT admins with a complete picture of the apps on all devices.
- Provides granular control over which apps are enabled.

Disadvantages:

- Because each device has a different app catalog, it's hard to apply a model of single policy configuration to multiple device types.
- It can be challenging to present the volume of OEM-specific apps in a meaningful way for IT admins.

**Categorize system apps by functionality**

When an IT admin wants to enable a system app for a group of devices,
they select a generic app based on functionality; for example, "System
Browser." The DPC then allows all system apps for that intent.

Advantages:

- Simple, functionality-based enablement for IT admins.
- Ensures consistent functionality across a variety of devices (at least for common use cases).

Disadvantages:

- Limits system apps to those that are supported across all device types.
- IT admins might want to push one OEM version of an app (such as a Samsung® browser), but not another (such as an LG® browser).
- IT admins might not want to push multiple apps, but they can't prevent it when there are multiple intent handlers.

**Support only approved system apps**

You work with the OEM to identify specific OEM packages and support only those
packages within the EMM console. This also lets you catalog the managed
configurations for the OEM app, which you wouldn't know otherwise because the
OEM app isn't hosted on Google Play.

Advantages:

- Vastly simplifies the integration workflow, and eliminates the edge cases that are problematic in the first two options.
- You can catalog the managed configurations for the OEM app and present them in the EMM console for IT admins.
- Enables close relationships with OEMs for supporting flagship devices.

Disadvantages:

- Less scalable and reduces consumer choice as a result.

## Test scenarios for your DPC

[Test DPC](http://github.com/googlesamples/android-testdpc/) is an open source
app provided by Google for testing enterprise capabilities in your DPC app.
Test DPC is available from
[github](http://github.com/googlesamples/android-testdpc/) or
[Google Play](https://play.google.com/store/apps/details?id=com.afwsamples.testdpc).
You can use Test DPC to:

- Simulate features in Android
- Set and enforce policies
- Set app and intent restrictions
- Set up work profiles
- Set up fully managed Android devices

While Test DPC is intended primarily as a vehicle to test your enterprise
solution for Android, you can also use it as a source of sample code for Android
features.

## Customize provisioning

During device provisioning, the system user interface shows a default color in
the status bar and a default logo at the top of the screen. Set custom colors
and logos to provide a consistent visual transition between your DPC and the
system interface, or allow admins to do so using your EMM console. For example,
an admin might upload a company logo or customize the look of screens that show
notifications.

Your DPC enforces the color and logo choices using the
[`DevicePolicyManager.EXTRA_PROVISIONING_MAIN_COLOR`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_MAIN_COLOR)
and
[`DevicePolicyManager.EXTRA_PROVISIONING_LOGO_URI`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_LOGO_URI)
extras.

**To set a custom color** , use
[`EXTRA_PROVISIONING_MAIN_COLOR`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_MAIN_COLOR)
to set an integer that indicates the predominant color to show during device
provisioning. Put the extra (constant) in an intent with
[`ACTION_PROVISION_MANAGED_PROFILE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE)
or
[`ACTION_PROVISION_MANAGED_DEVICE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_DEVICE).

To see how the integers are represented, see
[Color](https://developer.android.com/reference/android/graphics/Color.html).
For an example, see
[`MAIN_COLOR`](https://github.com/googlesamples/android-testdpc/blob/ab4b9bab0baee2322d1b6706d19f7d2c15091710/src/main/java/com/afwsamples/testdpc/SetupManagementFragment.java)
in the TestDPC app.

**To set a custom logo** , use
[`EXTRA_PROVISIONING_LOGO_URI`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_LOGO_URI)
to set an image that's displayed at the top of the screen during device
provisioning. Put the extra (constant) in an intent with
[`ACTION_PROVISION_MANAGED_PROFILE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE)
or
[`ACTION_PROVISION_MANAGED_DEVICE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_DEVICE).
Make sure the image has a reasonable pixel density for the device.

For an example, see
[`LOGO_URI`](https://github.com/googlesamples/android-testdpc/blob/ab4b9bab0baee2322d1b6706d19f7d2c15091710/src/main/java/com/afwsamples/testdpc/SetupManagementFragment.java)
in the TestDPC app.

## QR Code method

The QR Code provisioning method sets up and configures device owner mode by
scanning a QR Code from the setup wizard. The QR Code contains a payload of
key-value pairs with all the information that's needed for the DPC to provision
a device.

Your EMM console should provide a way for IT admins to create QR codes
for the devices they want to provision. The IT admin sends the QR codes
to their end users, and the end users provision their devices by scanning the
QR codes.

### Use cases for QR Code provisioning

Some devices, such as tablets, don't support NFC. QR Code provisioning is an
convenient way to provision a distributed fleet of devices that don't support
NFC. An IT admin can send QR codes to their users to allow user-driven
provisioning.

QR Code provisioning doesn't require a Google identity, such as a Google domain
or Google Account. Organizations that use Android, but don't use Google
Workspace, don't have a Google identity.

Like NFC, QR Code provisioning enables kiosk and single-use deployments where a
Google identity (or any identity) isn't needed or desirable. For example, a
kiosk device in a store belongs to no one and shouldn't have an end user
identity.

### Create a QR Code

A valid QR Code for QR Code provisioning is a UTF-8 encoded JavaScript® Object
Notation (JSON) string. You can include these properties in valid QR Code:

**Always required**

- [`EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME)

**Required if a DPC isn't already installed on the device**

- [`EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION)
- [`EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM)

**Recommended if the device isn't already connected to Wi-Fi**

- [`EXTRA_PROVISIONING_WIFI_SSID`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_WIFI_SSID)
- [`EXTRA_PROVISIONING_WIFI_PASSWORD`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_WIFI_PASSWORD)

**Optional**

- [`EXTRA_PROVISIONING_LOCALE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_LOCALE)
- [`EXTRA_PROVISIONING_TIME_ZONE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_TIME_ZONE)
- [`EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE)
- [`EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER)
- [`EXTRA_PROVISIONING_LOCAL_TIME`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_LOCAL_TIME)
- [`EXTRA_PROVISIONING_WIFI_HIDDEN`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_WIFI_HIDDEN)
- [`EXTRA_PROVISIONING_WIFI_SECURITY_TYPE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_WIFI_SECURITY_TYPE)
- [`EXTRA_PROVISIONING_WIFI_PROXY_HOST`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_WIFI_PROXY_HOST)
- [`EXTRA_PROVISIONING_WIFI_PROXY_PORT`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_WIFI_PROXY_PORT)
- [`EXTRA_PROVISIONING_WIFI_PROXY_BYPASS`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_WIFI_PROXY_BYPASS)
- [`EXTRA_PROVISIONING_WIFI_PAC_URL`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_WIFI_PAC_URL)
- [`EXTRA_PROVISIONING_SKIP_ENCRYPTION`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_SKIP_ENCRYPTION)

This sample builds a valid QR Code:

    {
    "android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME":
    "com.emm.android/com.emm.android.DeviceAdminReceiver",

    "android.app.extra.PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM":
    "gJD2YwtOiWJHkSMkkIfLRlj-quNqG1fb6v100QmzM9w=",

    "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION":
    "https://path.to/dpc.apk",
        "android.app.extra.PROVISIONING_SKIP_ENCRYPTION": false,
        "android.app.extra.PROVISIONING_WIFI_SSID": "GuestNetwork",
        "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE": {
            "dpc_company_name": "Acme Inc.",
            "emm_server_url": "https://server.emm.biz:8787",
            "another_custom_dpc_key": "dpc_custom_value"
        }
    }

### QR Code provisioning process

1. The setup wizard prompts the user to tap the Welcome screen 6 times. The taps have to be done in the same place on the screen.
2. The setup wizard prompts the user to connect to the Internet so the setup wizard can download a QR Code reader.
3. Google Play services downloads a module that contains a QR Code recognition engine.
4. The user scans the QR Code provided by their IT admin.
5. The setup wizard downloads your DPC app and initiates the device owner provisioning process using [`ACTION_PROVISION_MANAGED_DEVICE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_DEVICE).

## Managed Google Play Accounts method

A DPC can use the managed Google Play Accounts provisioning method to set up
device owner mode or profile owner mode. This provisioning method is targeted
at organizations that aren't using Google Workspace.

The managed Google Play Accounts provisioning method uses the
[DPC Support Library](https://developer.android.com/work/dpc/build-dpc.html#a_library_for_provisioning_android_for_work_accounts).
This client library ensures the smooth operation of managed Google Play
Accounts. It also maintains compatibility with future updates to the managed
Google Play Accounts provisioning process.

### Prerequisites to provisioning devices

- The enterprise ID is created and enrolled with an EMM identity and the ESA is set, as described in [Create and Enroll an Enterprise](https://developers.google.com/android/work/play/emm-api/create-enterprise).
- The user's corporate identity is known to your EMM console.
- The user can sign in to the DPC app using credentials accepted by your EMM console, typically corporate email credentials.

### Set up profile owner mode

You can provision the profile owner mode of operation on a device that's being
used in a BYOD scenario as a personal device.

1. The user manually downloads your DPC from Google Play and launches it.
2. The DPC provisions the work profile using [`ACTION_PROVISION_MANAGED_PROFILE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE).
3. Complete [the final setup steps](https://developers.google.com/android/work/play/emm-api/prov-devices#final_setup_steps_for_all_modes_of_operation).

### Set up device owner mode

You must provision the device owner mode of operation during initial setup of a
new device or after a factory reset. Device owner mode can't be provisioned on
a device at any other time.

During device setup, the user enters a special DPC-specific token when they are
prompted to add an account. A token is in the format `afw#DPC_IDENTIFIER`. For
an EMM named ACME, `afw#acme` would install the default DPC of the ACME EMM.
Each EMM must request a specific DPC identifier from Google before they can use
it in the provisioning process.

1. The user turns on a new or factory reset device and the setup wizard launches.
2. When prompted to add an account, the user enters a special token in the format `afw#DPC_IDENTIFIER` that identifies the DPC for your EMM.
3. Using the DPC identifier in the token, the setup wizard adds a temporary Google Account to the device. This temporary account is only used to download the DPC for your EMM from Google Play, and is removed in [the final setup steps](https://developers.google.com/android/work/play/emm-api/prov-devices#final_setup_steps_for_all_modes_of_operation).
4. The DPC provisions the device using [`ACTION_PROVISION_MANAGED_DEVICE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_DEVICE).
5. Complete [the final setup steps](https://developers.google.com/android/work/play/emm-api/prov-devices#final_setup_steps_for_all_modes_of_operation).

#### Final setup steps for all modes of operation

Perform these steps only *after* the initial steps for setting up
profile owner mode or device owner mode are complete.

1. The DPC makes sure that the device can support managed Google Play Accounts
   by initializing the DPC Support Library:

       AndroidForWorkAccountSupport androidForWorkAccountSupport =
         new AndroidForWorkAccountSupport(context, admin);
       androidForWorkAccountSupport.ensureWorkingEnvironment(callback);

   If you're setting up device owner mode on a device, this step removes the
   temporary Google Account that was added to download the DPC.
2. The user signs into the DPC using their EMM credentials. These are
   typically corporate email credentials.

3. The DPC requests managed Google Play Account credentials for the
   authenticated corporate user from the EMM console.

4. If the EMM console doesn't have a Google Play `userId` for the user, it
   creates a new user by calling
   [`Users.insert()`](https://developers.google.com/android/work/play/emm-api/v1/users/insert).
   If you are provisioning device owner mode, specify a device account (for
   dedicated device deployments) or a user account (for company-owned deployments).

   > [!NOTE]
   > **Note:** Because user IDs are EMM-specific, they can't be reused if the enterprise is unenrolled and re-enrolled with a different EMM.

5. Set the Device's policy by calling
   [`Devices.update`](https://developers.google.com/android/work/play/emm-api/v1/devices/update).
   You should set the policy before adding the managed Google Play Account to
   the device, otherwise the policy will not be applied for a short period of
   time after adding the account to the device.

6. The EMM console requests the account credentials for the `userId` by
   calling
   [`Users.generateAuthenticationToken()`](https://developers.google.com/android/work/play/emm-api/v1/users/generateAuthenticationToken).
   This authentication token is short-lived and can't be reused. The DPC should
   use the token to add the account programmatically (it's of no use to the end
   user).

7. The Google Play EMM API returns the authentication token to the EMM console.

8. The EMM console forwards the authentication token to the DPC.

9. The DPC adds the managed Google Play Account to the device using

       androidForWorkAccountSupport.addAndroidForWorkAccount(token,
         accountAddedCallback);

## Google Account method

A DPC can use the Google Account provisioning method to set up device owner
mode or profile owner mode. With the Google Account provisioning method, the
DPC guides the user through the provisioning steps after the user adds their
Google Account during the initial device setup.

When a user enters their Google Account credentials:

- The Google authentication server authenticates the user account.
- The authentication server then communicates with the enterprise server to see if the account's domain is registered as either a Google Workspace domain or an EMM-managed domain.
- If so, the system automatically downloads the DPC associated with the domain from Google Play and installs it.

### Set up profile owner mode

You can provision the profile owner mode of operation during initial setup of a
device or when the user is adding an account using **Settings \> Add account**.

1. Account authentication is started by a user from the setup wizard or from **Settings \> Add account**.
2. GMSCore initiates work profile provisioning using [`ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/app/admin/DevicePolicyManager.java?q=ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE).
3. The DPC is automatically downloaded to the device and launched using the [`ACTION_GET_PROVISIONING_MODE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#ACTION_GET_PROVISIONING_MODE) handler to verify that work profile provisioning is supported by the DPC.
   - [`EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE) **---** Extra information for the work profile such as email address. The DPC will also receive is_setup_wizard here as part of this bundle. This bundle will be included in [`ACTION_GET_PROVISIONING_MODE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#ACTION_GET_PROVISIONING_MODE) and [`ACTION_ADMIN_POLICY_COMPLIANCE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#ACTION_ADMIN_POLICY_COMPLIANCE) handlers.
   - [`EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE) **---** Name of the authenticated account to be migrated into the new work profile.
4. The platform carries out work profile provisioning.
5. When the work profile is provisioned, the DPC receives the broadcast [`ACTION_PROFILE_PROVISIONING_COMPLETE`](http://developer.android.com/reference/android/app/admin/DeviceAdminReceiver.html#ACTION_PROFILE_PROVISIONING_COMPLETE). The DPC's [`ACTION_ADMIN_POLICY_COMPLIANCE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#ACTION_ADMIN_POLICY_COMPLIANCE) handler is launched in the work profile. Once the work profile is created, the DPC is also running inside the work profile. The DPC pushes policies for that managed Google Account, ensures that the device isn't in a compromised state, and verifies that the policies are enforced (such as requiring a password).
6. The DPC in the personal profile [disables itself or the user removes it](https://developers.google.com/android/work/play/emm-api/prov-devices#remove_personal_dpc).

![](https://developers.google.com/static/android/work/images/post-suw.png)

### Set up device owner mode or COPE

You must provision the device owner mode of operation during initial setup of a
new device or after a factory reset. Device owner mode can't be added to a
device at any other time.

1. Account authentication is started by a user from the setup wizard.
2. GMSCore initiates device owner provisioning using [`ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/app/admin/DevicePolicyManager.java?q=ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE). 3.The DPC is automatically downloaded to the device and is launched using the [`GET_PROVISIONING_MODE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#ACTION_GET_PROVISIONING_MODE) handler to pick the desired provisioning mode.
   - [`EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE)**---** Extra information for the work profile such as locale, Wi-Fi, email address. The DPC will also receive is_setup_wizard here as part of this bundle. This bundle will be included in [`ACTION_GET_PROVISIONING_MODE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#ACTION_GET_PROVISIONING_MODE) and [`ACTION_ADMIN_POLICY_COMPLIANCE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#ACTION_ADMIN_POLICY_COMPLIANCE) handlers.
3. The platform provisions the device to the desired provisioning mode.
4. When the device is provisioned, the DPC receives these broadcasts and the DPC's [`ACTION_ADMIN_POLICY_COMPLIANCE`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#ACTION_ADMIN_POLICY_COMPLIANCE) handler is launched:
   - [`ACTION_READY_FOR_USER_INITIALIZATION`](http://developer.android.com/reference/android/app/admin/DeviceAdminReceiver.html#onReadyForUserInitialization(android.content.Context,%20android.content.Intent))
   - [`ACTION_PROFILE_PROVISIONING_COMPLETE`](http://developer.android.com/reference/android/app/admin/DeviceAdminReceiver.html#ACTION_PROFILE_PROVISIONING_COMPLETE).
5. The DPC uses the value of [`Global.DEVICE_PROVISIONED`](http://developer.android.com/reference/android/provider/Settings.Global.html#DEVICE_PROVISIONED) to verify that the device is new or factory reset (unprovisioned):
   - 0 **---** Unprovisioned.
   - 1 **---** Provisioned.
6. The DPC completes the provisioning process by pushing policies for that managed device, ensuring that the device isn't in a compromised state, and verifying that the policies are enforced (such as requiring a password).

![](https://developers.google.com/static/android/work/images/in-suw.png)

### Implementation considerations for the Google Account method

- The DPC should detect the Google Account authentication flow by looking for
  specific extras in the launch intent that was used (see
  [`LaunchIntentUtil`](https://github.com/googlesamples/android-testdpc/blob/ba1789073334d9ab9e70ac98b49dd0621cae3467/app/src/main/java/com/afwsamples/testdpc/common/LaunchIntentUtil.java)):

  - Account of type `android.accounts.Account` **---** Indicates that the account was added from the setup wizard or from **Settings \> Add account**, which requires the launched DPC to manage the device or profile.
  - `is_setup_wizard` of type Boolean **---** If true, the DPC was launched in the setup wizard before the setup wizard completed, otherwise from **Settings \> Add account** or another flow.

  A check for whether the DPC was launched as part of the Google Account method
  is:

      boolean isSynchronousAuthLaunch(Intent launchIntent) {
        return launchIntent.hasExtra("is_setup_wizard");
      }

- The DPC shouldn't call [`finish()`](http://developer.android.com/reference/android/app/Activity.html#finish())
  before it has finished setup. It should also return a positive result code
  (such as `RESULT_OK`) as the DPC is launched with
  [`startActivityForResult()`](http://developer.android.com/reference/android/app/Activity.html#startActivityForResult(android.content.Intent,%20int))
  and waits for a result.

  The DPC should wait for a result code from the provisioning process before
  calling `finish()` if the DPC setup flow reaches the point of sending an
  `ACTION_PROVISION_*` intent. Use the
  [`startActivityForResult()`](http://developer.android.com/reference/android/app/Activity.html#startActivityForResult(android.content.Intent,%20int))
  and [`onActivityResult()`](http://developer.android.com/reference/android/app/Activity.html#onActivityResult(int,%20int,%20android.content.Intent))
  callbacks when launching `ACTION_PROVISION_*` intents. (See
  [`LaunchActivity`](https://github.com/googlesamples/android-testdpc/blob/ba1789073334d9ab9e70ac98b49dd0621cae3467/app/src/main/java/com/afwsamples/testdpc/LaunchActivity.java)
  and [`SetupSyncAuthManagement`](https://github.com/googlesamples/android-testdpc/blob/ba1789073334d9ab9e70ac98b49dd0621cae3467/app/src/main/java/com/afwsamples/testdpc/syncauth/SetupSyncAuthManagement.java)
  for examples).

  Due to the potentially asynchronous nature of the setup process, the DPC
  can't rely on a result code of `RESULT_OK` to indicate that provisioning
  succeeded. The only guaranteed way is to rely on
  [`DeviceAdminReceiver`](http://developer.android.com/reference/android/app/admin/DeviceAdminReceiver.html)
  callbacks on provisioning success. `RESULT_CANCELED` indicates that the user
  backed out in a synchronous part of the setup flow, and the DPC should react
  to this.

  In this example, the DPC launches provisioning and waits for the result code from an activity:

      Intent intent = new Intent(ACTION_PROVISION_MANAGED_PROFILE);
      startActivityForResult(intent, REQUEST_MANAGED_PROFILE);
      ...

      @Override
      public void onActivityResult(int req, int res, Intent i) {
          if (req == REQUEST_MANAGED_PROFILE) {
              if (res == Activity.RESULT_OK) {
                  setResult(Activity.RESULT_OK);
                  finish();
              } else {
                  Toast.makeText(this, "Provisioning failed",
                          Toast.LENGTH_SHORT).show();
              }
          }
      }

- The DPC shouldn't attempt to set up the device owner mode of operation if
  the device is already provisioned (see
  [`ProvisioningStateUtil.isDeviceProvisioned()`](https://github.com/googlesamples/android-testdpc/blob/ba1789073334d9ab9e70ac98b49dd0621cae3467/app/src/main/java/com/afwsamples/testdpc/common/ProvisioningStateUtil.java#L47)).
  In this example, the DPC checks if the device is provisioned:

      public static boolean isDeviceProvisioned(Context context) {
      ContentResolver cr = context.getContentResolver();
          return
      Settings.Global.getInt(cr, DEVICE_PROVISIONED, 0) != 0;
      }

- Optional. The DPC can use the
  [`EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE)
  extra when launching provisioning to pass state information back to its
  [`DeviceAdminReceiver`](https://github.com/googlesamples/android-testdpc/blob/ab4b9bab0baee2322d1b6706d19f7d2c15091710/src/main/java/com/afwsamples/testdpc/DeviceAdminReceiver.java)
  (which in the profile owner case is running inside the work profile).
  [TestDPC](http://github.com/googlesamples/android-testdpc/) uses this extra
  to enter a different set of activities in the Google Account flow after
  provisioning completes. For details see
  [`DeviceAdminReceiver`](https://github.com/googlesamples/android-testdpc/blob/ab4b9bab0baee2322d1b6706d19f7d2c15091710/src/main/java/com/afwsamples/testdpc/DeviceAdminReceiver.java).

      public class DeviceAdminReceiver extends android.app.admin.DeviceAdminReceiver
      {
        @Override
        public void onProfileProvisioningComplete(Context context, Intent intent) {
          // Retrieve the admin extras bundle, which we can use to determine the original context for
          // Test DPC's launch.
          PersistableBundle extras = intent.getParcelableExtra(
                  EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE);
          ...

- To set up a work profile, the DPC must migrate the added account into the
  new work profile. To do this, the DPC should pass the account provided in the
  launch intent for
  [`ACTION_PROVISION_MANAGED_PROFILE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE).

- The DPC should provide the user with a clear call to action (such as a
  Finish button) to exit the app at the end of setup so the user doesn't think
  they've reached a dead end in the flow.

- The DPC should use the setup wizard theme or layout library so the user
  experience is smooth and feels well integrated.

## NFC method

A DPC can use the NFC provisioning method to set up device owner mode. In the
NFC provisioning method, or NFC Tag, you create an NFC programmer app that
contains the initial policies and Wi-Fi configuration, settings, and
provisioning details required by your customer to configure the device owner
mode of operation. When your or your customer install the NFC programmer app on
an Android-powered device, that device becomes the programmer device.

To provision a device, the IT admin takes a new device out of the box
and bumps it against the programmer device or NFC Tag. The bump transfers
configurations to the device so it connects to the Internet and downloads the
appropriate policies and settings. The device is then managed by your DPC.

After a device is provisioned, for a short time Google Play displays unmanaged
consumer content instead of the approved apps and collections that should
display. This delay can last from a few minutes up to an hour.

### Create the NFC programmer app and programmer device

For devices using Android 10 or older it is possible to use Android Beam to
complete an NFC provisioning:

1. Download the [NFC programmer sample app](https://github.com/googlearchive/android-NfcProvisioning). You can use the sample as is without additions or you can modify it for your default values.
2. Install the programmer app on the chosen device.
3. Launch the NFC programmer app and select **Load Defaults** for `com.example.android.apis`. (This text can vary depending on the default parameters that you set.)

### Provision a customer device

1. Bump the programmer device or NFC Tag with a new device or one that has been factory reset.
2. Verify that the device remains on the initial **Welcome** screen that's displayed when it starts. The text is specified in `Ready to send:{...}` in the programmer app.
3. Wait while the DPC:
   1. Encrypts the device.
   2. If it's a Code-Division Multiple Access (CDMA) device: Activates the phone while a telephony user interface is shown (no interaction required).
   3. Sets up the Wi-Fi connection.
   4. Downloads the APK file for com.example.android.apis.
   5. Installs com.example.android.apis.
   6. Sets the Sample Device Admin in com.example.android.apis as the device owner.
   7. Shows a success "toast" when the device owner is activated.
4. After returning to the home page (setup wizard is skipped automatically), check that com.example.android.apis is set as the device owner:
   1. In **Settings \> Security \> Device admins**, make sure that Sample Device Admin can't be removed.
   2. In **Settings \> Users \> Users \& profiles \> You (owner)**, make sure that Owner is the only account available (a device can have only one active device owner at a time).

### Additional resources

[Advanced NFC](http://developer.android.com/guide/topics/connectivity/nfc/advanced-nfc.html)
describes topics such as working with various tag technologies, writing to NFC
tags, and foreground dispatching.

## Manual DPC install method

To set up profile owner mode using the manual DPC install provisioning method,
the user downloads your DPC from Google Play and installs it. Then the DPC
guides the user through the rest of the process to set up the profile owner for
the managed Google Account.

The DPC can add the managed Google Account before or after creating
the work profile. For example, the DPC can create a work profile based on a
user's EMM credentials instead of prompting for the managed Google Account
first.

### Set up profile owner mode

#### Add the managed Google Account first

1. The user downloads your DPC from Google Play and installs it.
2. The DPC adds the managed Google Account before creating the work profile using [`AccountManager.addAccount()`](http://developer.android.com/reference/android/accounts/AccountManager.html).
3. The DPC starts running in the personal profile and initiates the process to create a work profile using:
   - [`ACTION_PROVISION_MANAGED_PROFILE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE) **---** Provisions the work profile.
   - [`EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE) **---** Extra information for the work profile such as locale, Wi-Fi, email address.
   - [`EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE) **---** Name of the authenticated account to be migrated into the new work profile.
4. The DPC in the work profile completes the provisioning process. Once the work profile is created, the DPC is also running inside the work profile. The DPC in the work profile completes the provisioning process by pushing policies for that managed Google Account, ensuring that the device isn't in a compromised state, and verifying that the policies are enforced (such as requiring a password).
5. When the work profile is provisioned, the DPC receives the broadcast [`ACTION_PROFILE_PROVISIONING_COMPLETE`](http://developer.android.com/reference/android/app/admin/DeviceAdminReceiver.html#ACTION_PROFILE_PROVISIONING_COMPLETE).
6. The DPC in the personal profile [disables itself or the user removes it](https://developers.google.com/android/work/play/emm-api/prov-devices#remove_personal_dpc).

![](https://developers.google.com/static/android/work/images/google_acct_first.png)

#### Create the work profile first

1. The user downloads your DPC from Google Play and installs it.
2. The DPC starts running in the personal profile and initiates the process to create a work profile using:
   - [`ACTION_PROVISION_MANAGED_PROFILE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE) **---** Provisions the work profile.
   - [`EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE) **---** Extra information for the work profile such as locale, Wi-Fi, email address.
3. The DPC adds the managed Google Account using [`AccountManager.addAccount()`](http://developer.android.com/reference/android/accounts/AccountManager.html).
4. The DPC receives the broadcast [`ACTION_PROFILE_PROVISIONING_COMPLETE`](http://developer.android.com/reference/android/app/admin/DeviceAdminReceiver.html#ACTION_PROFILE_PROVISIONING_COMPLETE) and reads [`EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE).
5. The DPC in the work profile completes the provisioning process. Once the work profile is created, the DPC is also running inside the work profile. The DPC in the work profile completes the provisioning process by pushing policies for that managed Google Account, ensuring that the device isn't in a compromised state, and verifying that the policies are enforced (such as requiring a password).
6. The DPC enables the work profile using [`DevicePolicyManager.setProfileEnabled()`](http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setProfileEnabled(android.content.ComponentName)).
7. The DPC in the personal profile [disables itself or the user removes it](https://developers.google.com/android/work/play/emm-api/prov-devices#remove_personal_dpc).

![](https://developers.google.com/static/android/work/images/work_profile_first.png)

*** ** * ** ***

1. The Google Account method in Android 5.1 supports only the profile owner mode of operation, and the user can configure it only from **Settings \> Add account** . [↩](https://developers.google.com/android/work/play/emm-api/prov-devices#fnref1)