Courtesy: GitHub

Test Device Policy Control (Test DPC) App

Test DPC is an app designed to help EMMs, ISVs, and OEMs to test their applications and platforms in a Android for Work managed profile (i.e. work profile). It serves as both a sample Device Policy Controller and a testing application to flex the APIs available for Android for Work. It supports devices running Android 5.0 Lollipop or later. As of Mar 24, 2017, it also includes support for devices running API level 26.

See the documentation to learn more about Android for Work.

Getting Started

This sample uses the Gradle build system. To build this project, use the "gradlew assemble" command or use "Import Project" in Android Studio.


You can find various kinds of provisioning methods here. Let's take a few of them as an example.

QR code provisioing (Device Owner N+ only)

  1. Factory reset your device and tap the welcome screen in setup wizard 6 times.
  2. The setup wizard prompts the user to connect to the Internet so the setup wizard can download a QR code reader.
  3. Modify (if needed) and scan [this QR code] (
  4. Follow onscreen instructions

NFC provisioning (Device Owner)

The NFC Provisioning app is used for device owner provisioning.

  1. Push the nfcprovisioning.txt file to your device: adb push nfcprovisioning.txt /sdcard/
  2. Open the NFC Provisioning app and ensure that com.afwsamples.testdpc is auto-populated.
  3. Bump the devices and touch to beam.
  4. Follow onscreen instructions on the target device.

adb command (Device Owner)

adb shell dpm set-device-owner com.afwsamples.testdpc/.DeviceAdminReceiver

Work profile

The easiest way is to launch the Test DPC app in launcher and follow the onscreen instructions.


Setup Policy Management Manage App Restrictions Work Profile Management Network Data Usage Stats


If you've found an error in this sample, please file an issue:

Patches are encouraged, and may be submitted by forking this project and submitting a pull request through GitHub.


Licensed under the Apache 2.0 license. See the LICENSE file for details.

How to make contributions?

Please read and follow the steps in the CONTRIB file.

compileSdkVersion 26

applicationId "com.afwsamples.testdpc"

minSdkVersion 21

targetSdkVersion 26

versionCode versionMajor * 1000 + versionMinor * 100 + versionBuild

versionName "${versionMajor}.${versionMinor}.${versionBuild}"

package com.afwsamples.testdpc


  • android.permission.GET_ACCOUNTS
  • android.permission.MANAGE_ACCOUNTS
  • android.permission.PACKAGE_USAGE_STATS
  • android.permission.ACCESS_WIFI_STATE
  • android.permission.CHANGE_WIFI_STATE
  • android.permission.INTERNET
  • android.permission.RECEIVE_BOOT_COMPLETED
  • android.permission.ACCESS_NETWORK_STATE


Application launch activity that decides the most appropriate initial activity for the user. *

Options include:

  1. If TestDPC is already managing the device or profile, forward to the policy management activity.
  2. If TestDPC was launched as part of synchronous authentication, forward all intent extras to the setup activities and wait for that activity to finish; allows in-line management setup immediately after an account is added (before the end of the Add Account or Setup Wizard flows).
  3. Otherwise, present the non-sync-auth setup options.



An entry activity that shows a profile setup fragment if the app is not a profile or device owner. Otherwise, a policy management fragment is shown.


This activity is started after provisioning is complete in {@link DeviceAdminReceiver}. It is responsible for adding an account to the managed profile (Profile Owner) or managed device (Device Owner).


This activity is started after managed profile provisioning is complete in {@link DeviceAdminReceiver}. There could be two cases:

  1. If we are not going to add account now, we will then enable profile immediately.
  2. If we have just added account, we need to wait for the FIRST_ACCOUNT_READY broadcast before enabling the profile. The broadcast indicates that the account has been synced with Google and is ready for use.


This activity is started after device owner provisioning is complete in {@link DeviceAdminReceiver}.


This activity is started after provisioning is complete in {@link DeviceAdminReceiver} for COSU devices. It loads a config file and downloads, install, hides and enables apps according to the data in the config file.

Start the actual COSU mode and drop the user into different screens depending on the value of mode. default: Launch the home screen with a default launcher custom: Launch KioskModeActivity (custom launcher) with only the kiosk apps present single: Launch the first of the kiosk apps


Shows the list of apps passed in the {@link #LOCKED_APP_PACKAGE_LIST} extra (or previously saved in shared preferences if the extra is not found) in single app mode:

  • The status bar and keyguard are disabled
  • Several user restrictions are set to prevent the user from escaping this mode (e.g. safe boot mode and factory reset are disabled)
  • This activity is set as the Home intent receiver

If the user taps on one of the apps, it is launched in lock tack mode. Tapping on the back or home buttons will bring the user back to the app list. The list also contains a row to exit single app mode and finish this activity.


Activity that gets launched by the {@link} intent.



Before N, only the DPC has permission to set application restrictions via {@link DevicePolicyManager#setApplicationRestrictions(ComponentName, String, Bundle)}. To enable the another package to manage the application restrictions, a bound service is used to pass them to {@link AppRestrictionsProxy}. From N onwards, a given package can be granted permission to manage application restrictions, which removes the need for the proxy code.


Handle cross user call from a DPC instance in other side. @see {@link DevicePolicyManager#bindDeviceAdminServiceAsUser( ComponentName, Intent, ServiceConnection, int, UserHandle)}



To allow DPC process to be persistent and foreground. * @see {@link}



Handles events related to the managed profile.

@param context The context of the application. @return The component name of this component in the given context.


Receiver for FIRST_ACCOUNT_READY_ACTION from Google Play Service. Receiver only matters for Managed Profile flow, so we ignore the broadcast in other cases.

Enable profile anyway if we cannot receive the broadcast after certain amount time.