Open-source project
googlesamples/android-testdpc avatar
googlesamples/android-testdpc

Test DPC: a device policy controller built to be tested against

Test DPC is a sample device policy controller for use with Android Enterprise. It gives developers the ability to see how their app will behave in a managed context such as device owner or within a managed profile. Users can set up a work profile, enable work apps, set applications restrictions, manage security polices, and much more. The app also serves as a implementation reference for other DPCs

1,063 stars424 forksJavaApache-2.0

At a glance

What is it?
Test DPC is Google's sample Android Enterprise device policy controller, an app that puts a device or a profile into a managed state so you can see how your own app behaves under device owner, work profile and management role rules. The interesting parts are the provisioning paths, which decide what kind of owner TestDPC becomes, and the fact that the whole project builds with Bazel.
Who is it for?
Test DPC fits an Android developer who has to know how their app behaves under Android enterprise management before an enterprise customer deploys it, and it fits an EMM or ISV team validating a policy flow. It does not fit anyone who wants a production device management product, since the README describes it as a sample and a testing application.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 32 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A sample whose job is to be the thing you test against

Test DPC is described as an app designed to help EMMs, ISVs and OEMs to test their applications and platforms in an Android enterprise managed profile, that is a work profile. It serves as both a sample Device Policy Controller and a testing application to flex the APIs available for Android enterprise, and the app also serves as an implementation reference for other DPCs.

That last role is the one that makes it worth a repository rather than a script. Android enterprise is a large API surface, and a team writing a real device policy controller needs to see how a reference implementation handles the parts that are easy to get wrong, from the admin receiver to the policy setters. The repository description puts it plainly: it gives developers the ability to see how their app will behave in a managed context such as device owner or within a managed profile.

The capabilities the app exposes are the practical ones a tester wants. Users can set up a work profile, enable work apps, set application restrictions, and manage security policies, among other things. The app is Java, published under the Apache 2.0 licence, and it supports devices running Android 5.0 Lollipop or later.

It is also on the Play Store under com.afwsamples.testdpc, so the fastest way to try it is to install the published app rather than to build the source. The source build is there for the case where you need to modify the policy behaviour, and the README's own framing is that this is both a sample and a reference implementation.

The role you provision determines what you can test

Test DPC can hold several different roles on Android, and the difference between them decides which behaviours you are able to exercise.

A device owner is the full thing. The device is managed by Test DPC, and the policies apply to the whole device, which is the configuration to use when you want to test a fully managed deployment. A profile owner is the work profile case, where the management is scoped to a set of work apps and the user's personal space is untouched. That is the configuration that matters for bring your own device, and the one most consumer facing applications are affected by.

A profile owner on a corporate owned device is a third case, where the device belongs to the organisation and the profile is marked as such with an adb command rather than being created in the normal personal flow.

The fourth is the device management role holder, which Test DPC v9.0.5 and later can be set up as, using the platform role APIs:

console
adb shell cmd role set-bypassing-role-qualification true
adb shell cmd role add-role-holder android.app.role.DEVICE_POLICY_MANAGEMENT com.afwsamples.testdpc

The README flags the catch: unlike device owner and profile owner, this change is not persisted, so Test DPC needs to be marked as role holder again if the device reboots. That is a small detail with a large practical consequence, because a test rig that reboots overnight will come back unconfigured and the failure will look like a policy problem.

Three provisioning routes, and the personal device is not among them

Getting Test DPC onto a device is the part with the most moving pieces, and the README points at the general provisioning documentation before giving examples.

The AFW# code path is for a device owner on Android M and later. You factory reset the device, set up Wi-Fi, and when prompted to sign in, enter afw#testdpc, then follow the onscreen instructions and choose 'Use for work only' for a fully managed setup.

The QR code path is also device owner only, and only on Android N and later. You factory reset the device and tap the welcome screen in the setup wizard six times. On Android O or older the wizard then asks the user to connect to the internet so it can download a QR code reader, while Android P and newer devices already have one.

The adb path is the one that works on a device you are already using, and it is the one to reach for on a personal device. For a device owner:

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

For a profile owner on a personal device, the README does not use adb at all. You launch the Set up TestDPC app, and skip adding an account at the end of the flow. On a corporate owned device you do the same and then run:

console
adb shell dpm mark-profile-owner-on-organization-owned-device --user 10 com.afwsamples.testdpc/.DeviceAdminReceiver

The difference in approach between the two families is worth noting. The setup wizard routes and the QR code require a factory reset, because the provisioning happens during first-run. The adb route and the app route do not, which is why they are what a developer uses on a machine they do not want to wipe.

The QR payload is a signature checksum and a download location

The QR code in the README is not a link to a web page. It carries a JSON document with three provisioning extras, and each one has a job:

json
{
 "android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME": "com.afwsamples.testdpc/com.afwsamples.testdpc.DeviceAdminReceiver",
 "android.app.extra.PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM": "gJD2YwtOiWJHkSMkkIfLRlj-quNqG1fb6v100QmzM9w=",
 "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION": "https://testdpc-latest-apk.appspot.com"
}

The component name tells the platform which receiver to promote. The signature checksum tells the platform that the APK it is about to install is the one it expects, which is what stops a provisioning QR code from installing a different application that happens to claim the same component name.

The download location is where the platform fetches the APK from, and this is where the README's troubleshooting note bites. If using this QR code your device is stuck on the configuring screen, it may be due to a problem connecting to the appspot.com domain. In those cases you can use the latest release available on GitHub, or upload that version to your own server and use it as the download location. The README then says to replace the link used for PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION with a link to your APK, and to regenerate the QR code afterwards.

That is the practical advice for anyone running this on a locked down corporate network, and the checksum is the detail to keep in mind: change the APK and the checksum has to match it, so the pre-made QR code is only valid for the pre-made build.

Building it needs Bazel, ed on the path and ANDROID_HOME

This sample uses the Bazel build system, and the README gives the build command in one line: bazel build testdpc.

The environment has two requirements that are easy to miss. The first is ANDROID_HOME, because Bazel requires that you set the ANDROID_HOME environment variable to the path of your Android SDK, and the README suggests adding this to your .bashrc on Linux:

bash
export ANDROID_HOME=<Path to the Android SDK>

The second is the ed command line utility. The repository includes a build.sh script to build the application, and the required setupdesign library is now imported and patched dynamically using the command line utility ed, which needs to be available on the path to successfully build the project. That is an unusual build dependency, and it exists because the setupdesign library has to be patched at import time rather than consumed as published.

The repository layout reflects the Bazel setup. There is a BUILD file at the root, a MODULE.bazel and a WORKSPACE file, a .bazelversion file that pins the Bazel version, and two files whose names describe the patching step, setupcompat.BUILD and setupdesign.BUILD. The application source is under src, the scripts directory holds the import configuration, and the QR code image is committed as qrcode.png.

There is also a PRIVACY file and a CONTRIB file, and the README asks that contributions follow the steps in CONTRIB.

Android Studio import is a plugin and a project view file

Importing the repository into Android Studio needs one thing the IDE does not have by default, which is why the README gives a specific plugin.

You need to use the Bazel for Android Studio plugin. When importing the project you have to select the folder containing the Bazel's BUILD file, and when prompted to select a project view you can choose the option Copy external and choose the scripts/ij.bazelproject available in this repository.

That project view file is what makes the import work. A plain Android Studio import of a Bazel project produces a source tree it cannot resolve, and ij.bazelproject tells the plugin which directories are external dependencies and how the workspace is laid out, so the generated project matches what Bazel itself would build.

Once Bazel has completed the import operation and the first sync of the project, you can create a Run Configuration. Select Bazel Command as the configuration type and add //:testdpc as the target expression, and you can then run the project from inside Android Studio.

The target expression is worth being precise about. It is the label of the same target the command line build produces, so the IDE and the command line build the same artifact, which is the point of the exercise.

Apache-2.0, a 2024 tag, and pushes that continue

The licence is Apache 2.0, with the LICENSE file in the repository, and the README states it directly: licensed under the Apache 2.0 license, see the LICENSE file for details.

The release history is sparse and worth reading carefully. The tagged releases are v9.0.5 from 2024-03-11, v9.0.6 from 2024-03-20 and v9.0.12 from 2024-09-09, while the last push to the repository was on 2026-09-21. So the code is being worked on, but the tagged releases that other people install from are from 2024.

The gap between the two matters for one specific decision. The version number is a capability marker in this project, because the README says Test DPC v9.0.5+ can be set up as Device Management Role Holder. Anyone who wants the role holder route needs at least that version, and the version you get from the Play Store or from a release tag is not necessarily the version in the master branch.

The Play Store listing is the other practical consideration. Because the app is published as com.afwsamples.testdpc, most testers never build it at all, and the ones who do build it are usually doing so to change the policy behaviour or to inspect the implementation as a reference. The repository exists for that second group, and the README's closing notes about filing issues and submitting patches for a fork are aimed at exactly the people who have read the source and want to change it.

Editorial conclusion

Test DPC fits an Android developer who has to know how their app behaves under Android enterprise management before an enterprise customer deploys it, and it fits an EMM or ISV team validating a policy flow. It does not fit anyone who wants a production device management product, since the README describes it as a sample and a testing application. Before you start, pick your provisioning path deliberately, because the AFW# code and the QR code only work for a device owner and the ADB path is the one that works on a personal device, and note that the device management role holder has to be set again after every reboot.

Frequently asked questions

What is Test DPC and who is it for?

It is a sample device policy controller and testing application for Android enterprise, designed to help EMMs, ISVs and OEMs test their applications and platforms in a managed profile, and it also serves as an implementation reference for other DPCs. It supports devices running Android 5.0 Lollipop or later.

How do I set up Test DPC as a device owner with adb?

Run adb shell dpm set-device-owner com.afwsamples.testdpc/.DeviceAdminReceiver. For a profile owner on a corporate owned device you instead launch the Set up TestDPC app, skip adding an account, and run adb shell dpm mark-profile-owner-on-organization-owned-device --user 10 with the same component.

What happens if the Test DPC QR code provisioning gets stuck on the configuring screen?

The README says it may be due to a problem connecting to the appspot.com domain. You can use the latest release available on GitHub, or upload that version to your own server and use it as the download location, then replace the link in PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION and regenerate the QR code.

How do I build Test DPC from source?

The sample uses the Bazel build system, so run bazel build testdpc. The build also needs the ed command line utility on the path, since the setupdesign library is imported and patched dynamically, and Bazel requires the ANDROID_HOME environment variable to point at your Android SDK.

Can Test DPC act as a device management role holder?

Yes, Test DPC v9.0.5 and later can be set up as Device Management Role Holder with adb shell cmd role set-bypassing-role-qualification true followed by adb shell cmd role add-role-holder android.app.role.DEVICE_POLICY_MANAGEMENT com.afwsamples.testdpc. Unlike device owner and profile owner, this is not persisted, so it has to be set again after a reboot.

Official sources

  1. googlesamples/android-testdpc on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/googlesamples-android-testdpc.svg)](https://hysenlabs.com/projects/googlesamples-android-testdpc)

Was this useful?