lightbulb_outline Help shape the future of the Google Play Console, Android Studio, and Firebase. Start survey

Work profiles on fully managed devices

This document explains how your device policy controller (DPC) can provide work profiles on fully managed devices.

Overview

Work-managed devices allow IT admins to enforce a wide range of mobile policy controls. Work profiles separate work and personal apps and data. Work profiles on fully managed devices combine the advantages of both solutions to offer work and personal separation on a company-owned device.

Figure 1. Two DPC instances manage the profiles on the device
The personal profile and work profile both have DPCs

Two instances of your DPC are active.

  • An instance of your DPC running in device owner mode (sometimes called a device owner) manages device policies and the user's personal profile.
  • A second instance of your DPC running in profile owner mode (sometimes called a profile owner) manages policies and apps for the user's work profile.

A work profile keeps the organization's apps and data secure and separate from the user's personal apps. The organization still manages the device and can enforce a wide range of policies or turn on device-wide features, such as network logging, if required.

System user interface

The system user interface separates the apps and data of the work profile from the personal profile. The profile's label is Work and the system badges app icons and panels using the briefcase icon. The system uses the label Personal to group apps from the personal profile.

Device users with a work profile on a fully managed device can check their organization's access using the Managed device info panel in Settings.

Policy presentation

Work profiles on fully managed devices increase the policy options for organizations. Because the wider choice might appear more complex, we recommend following these best practices when presenting policy options or decisions to organizations and device users.

Simple model

Present a simple settings model to an organization's IT admins. Use your default settings to encourage IT admins to keep work policies, apps, and data in the work profile.

Work policies applied to the work profile
Figure 2. Policies should generally be applied at the most-specific level, and only to the whole device when necessary

Design your EMM console to encourage IT admins to set policies as close as possible to the work data. If an IT admin can apply a policy to just the work profile, then apply it there and not to the whole device. This helps ensure the protection of work data while use of the device isn't unduly restricted. Importantly, it simplifies the task of administering work profiles on fully managed devices. You might need to make an override available if a particular policy must instead apply device-wide.

The following table shows where to apply UserManager restrictions.

Work profile Personal profile
ALLOW_PARENT_PROFILE_APP_LINKING DISALLOW_ADD_USER
DISALLOW_APPS_CONTROL DISALLOW_CONFIG_BLUETOOTH
DISALLOW_CONFIG_CREDENTIALS DISALLOW_CONFIG_CELL_BROADCASTS
DISALLOW_CONFIG_VPN DISALLOW_CONFIG_MOBILE_NETWORKS
DISALLOW_CROSS_PROFILE_COPY_PASTE DISALLOW_CONFIG_TETHERING
DISALLOW_MODIFY_ACCOUNTS DISALLOW_CONFIG_WIFI
DISALLOW_OUTGOING_BEAM DISALLOW_DEBUGGING_FEATURES
DISALLOW_SHARE_LOCATION DISALLOW_FACTORY_RESET
DISALLOW_UNINSTALL_APPS DISALLOW_INSTALL_UNKNOWN_SOURCES
ENSURE_VERIFY_APPS DISALLOW_MOUNT_PHYSICAL_MEDIA
DISALLOW_NETWORK_RESET
DISALLOW_REMOVE_USER
DISALLOW_SAFE_BOOT
DISALLOW_USB_FILE_TRANSFER

Show one DPC

Show one instance of your DPC in the user's launcher. Because the user might add or delete work profiles, show the DPC in the personal profile and hide the DPC in the work profile.

To hide your DPC in the work profile, disable the app's main launcher activity when the DPC runs in the work profile. Call DevicePolicyManager.isManagedProfile() to check for the work profile and disable the activity by calling PackageManager.setComponentEnabledSetting().

Personal accounts

Allow the device user to add accounts in their personal profile. A device owner, in the absence of a work profile, might typically add an account creation restriction. When the user has a work profile, your DPC shouldn't restrict account creation.

Managed apps

As with policy management, organizations should concentrate their app management in the work profile.

An organization that needs to push apps into the personal profile, should use managed Google Play device accounts. These accounts aren't visible to the device users who browse apps in Google Play using their personal Google Account. Using a single managed Google Play store in the work profile avoids any confusion.

To learn more about app management, read MAM (mobile app management).

Provision work profiles

When your DPC provisions a work profile on a fully managed device, some new options are available to make the experience more convenient for users. You provision a work profile on a fully managed device by calling the same APIs used on an unmanaged device. To learn about provisioning a device or a work profile, read Provision Customer Devices.

Accounts

When provisioning a new work profile, a device owner can move Google Accounts from the primary user to a work profile. Moving an account makes it available the new work profile. In some rare circumstances you might need to copy a Google Account to keep it in both profiles—consider this carefully because device users might find a duplicate account in different profiles confusing.

You can copy an account by including EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION in the provisioning intent extras. The example below shows how you might copy an account into a work profile in your own DPC.

// Copy the account to the work profile
Account account = getAccountToCopy();

Intent intent = new Intent(ACTION_PROVISION_MANAGED_PROFILE);
intent.putExtra(EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE, account);
intent.putExtra(EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION, true);

// Continue setting up provisioning and call startActivityForResult()
// ...

Because the user has already given their consent when provisioning the device, your DPC doesn't always have to ask again when provisioning a work profile. Enrolling the work-managed device always asks the user to give consent—your DPC can't skip this.

Use the provisioning intent extra EXTRA_PROVISIONING_SKIP_USER_CONSENT to skip asking the user for consent again. This option only works for device owners. Setup is quicker for the user who might have recently completed the device enrollment. While the system provisions the work profile, the user sees user interface panels explaining what's happening and showing progress.

Affiliate users

If the device owner and a profile owner represent the same organization, affiliate the users as you provision the work profile. To learn more, read Affiliated users below.

Follow the user lifecycle

Your device owner might find it useful to know when secondary users or work profiles change on the device. To run follow-on tasks after adding or deleting new users, override the user callback methods in your DPC's DeviceAdminReceiver subclass:

onUserAdded()
Called when the system adds a new user or profile. Because profile might still be provisioning when your DPC gets the callback, you should listen for the ACTION_MANAGED_PROFILE_PROVISIONED broadcast before using the work profile—the intent's EXTRA_USER value contains a user handle for the profile.
onUserRemoved()
Called when the system deletes a secondary user or profile. Because the user's deleted, you can't access the user represented by the removedUser argument.

Only the device owner receives these user callbacks—they're not sent to profile owners.

Password callbacks

Device owners and profile owners both receive callbacks about changes to the user password. If the password change happens because of the work profile security challenge, only the work profile owner receives the callback. For other password changes, both the device owner and profile owner receive callbacks.

Your DPC might need to check which profile the changes affect—to avoid responding twice. Implement the callbacks that include the user parameter and inspect the user argument to get the target profile. The example below shows a DPC checking the affected profile before showing a notification to the user.

void onPasswordExpiring(Context context, Intent intent, UserHandle user)
// Check the user is this profile before showing a notification
if (user == Process.myUserHandle()) {
  // This is the DPC for the profile. Show a time-remaining notification
  long expiryInterval = getPasswordExpiration(adminName);
  // ...
}

Profile communication

Work profiles on managed devices use two instances of your DPC—one running as device owner and the other as profile owner. Even though the two instances are running under separate users, the device and profile owners can communicate with each other. We recommend one of your DPCs maintaining a network connection to an EMM server, and then share status and settings between profiles. You might also want your DPCs to communicate for other reasons. For example, a profile owner can tell the device owner when the work profile becomes unlocked.

Figure 3.Communication between two DPC instances in affiliated profiles
Two DPCs communicating through service RPCs as the profiles are affiliated

A device owner and profile owner can communicate when:

  • The two DPC instances belong to the same APK.
  • A DPC binds to the other DPC's service as a target user.
  • The two profiles are affiliated (see below).

Bind to a DPC service

Because calling another DPC's service crosses profile boundaries, your DPC can't call bindService(). To bind to a service running in another profile, call DevicePolicyManager.bindDeviceAdminServiceAsUser().

Your DPC can only bind to services running in the users returned by DevicePolicyManager.getBindDeviceAdminTargetUsers(). You can pick the first user because the results contains a single user handle for the other personal profile or work profile. The example below shows how your DPC might bind across instances.

// Get the profile the service is running in
List<UserHandle> targetUsers = getBindDeviceAdminTargetUsers(destinationServiceName);

// If the profiles aren't affiliated the list doesn't contain any users
if (!targetUsers.isEmpty()) {
  UserHandle profile = targetUsers.get(0); // List contains a single user
  Intent intent = new Intent(this, DestinationService.class);

  // Bind to the service
  boolean bindSuccessful = bindDeviceAdminServiceAsUser(this,
      intent,
      mServiceConnection,
      Context.BIND_AUTO_CREATE,
      profile);
}

Provide a service

DPC instances can only bind to approved services in another instance. To provide a service that another DPC instance can bind to, you need to:

  1. Export the service in the app manifest file.
  2. Require BIND_DEVICE_ADMIN permission to use the service.

This example shows how you might declare the service in your DPC's app manifest file:

<manifest ... >
  ...
  <application ... >
      <service android:name=".ExampleService"
        android:exported="true"
        android:permission="android.permission.BIND_DEVICE_ADMIN"/>
      ...
  </application>
</manifest>

To learn more about declaring a service in an app manifest file, read the Android guide <service>.

Service availability in work profiles

A service running in the work profile might not always be available. Your DPC can call remote methods of a service in a locked work profile if your DPC is encryption aware. If you need to check the user has unlocked the work profile, call UserManager.isUserUnlocked(UserHandle) with the work profile as the argument.

If the user turned off work mode, a device owner can't bind to a service or call methods in the work profile. A device owner can check if work mode is on calling UserManager.isUserRunning() with the work profile as an argument. The following snippet shows a device owner checking the work profile's availability after failing to bind to a service.

if (!bindSuccessful) {
  // Didn't bind. Check the work profile before deciding what action to take
  UserManager userManager = (UserManager)context.getSystemService(Context.USER_SERVICE);

  if (!userManager.isUserRunning(profile)) {
    // The user has turned off work mode
    // ...
  }
  if (!userManager.isUserUnlocked(profile)) {
    // Our DPC isn't encryption aware so can't talk to a locked work profile
    // ...
  }
}

Your work profile DPC instance can report its status to the device owner when it becomes unlocked or when the user turns on work mode. The device owner also receives ServiceConnection callbacks, such as onServiceDisconnected(), if it's bound to a service in a work profile that becomes unavailable.

Affiliated users

Some enterprise features can work across profiles when a device owner and a profile owner represent the same organization. Your DPC can declare this relationship by affiliating the profiles. Features for affiliated profiles include:

  • Device owner and profile owner DPCs can communicate with each other if they're from the same APK.
  • Device-wide features, such as logging, bug reporting, or whitelisting lock task mode, are available when all users become affiliated.

Affiliation IDs

Affiliation IDs, attached to a profile or user, identify an organization. When users' affiliation IDs match, the users become affiliated. While each profile can have many affiliation IDs, a single ID match can affiliate users.

Device and profile owners use setAffiliationIds() to set their affiliation IDs. Use getAffiliationIds() to fetch any affiliation IDs your DCP might have set.

Your DPC needs a single affiliation ID to link the profiles on a device. The DPC can generate a shared value or you could fetch an ID from a server. You can avoid coincidental matches with other profiles by generating long, difficult to guess ID strings to represent an organization. The example below shows setting a new affiliation ID and using the provisioning intent extras to pass it to the new work profile.

// Begin creating a new work profile
DevicePolicyManager dpm = getDpm();
ComponentName admin = DeviceAdminReceiver.getComponentName(getActivity());

// Create a new affiliate ID
String affiliationID = UUID.randomUUID().toString();

// Add a new ID to any existing IDs for this device owner
Set<String> identifiers = dpm.getAffiliationIDs(admin);
identifiers.add(affiliationID);
dpm.setAffiliationIds(admin, identifiers);

// Setup the intent to provision a new work profile
Intent intent = new Intent(dpm.ACTION_PROVISION_MANAGED_PROFILE);

// Pass the affiliation ID to the work profile
PersistableBundle adminExtras = new PersistableBundle();
adminExtras.putString(MyConstants.AFFILIATION_ID, affiliationID);
intent.putExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, adminExtras);

// Continue configuring the provisioning intent
// ...

Affiliate new users straightaway

Because adding a new user deactivates some device-wide features, you should affiliate new profiles as soon as you create them. Security and network logging, bug reporting, and whitelisting apps for lock task mode don't work with an unaffiliated user on the device. The system continues these services after you affiliate the user. The snippet below shows a work profile affiliating the user in its completion callback. You'll need to add checks to handle missing affiliation IDs in your app.

public void onProfileProvisioningComplete(Context context, Intent intent) {
  DevicePolicyManager dpm =
                (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
  ComponentName adminComponent = getComponentName(context);
  PersistableBundle adminExtras = intent.getParcelableExtra(
                dpm.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE);

  // Set the affiliation ID for the work profile
  String affiliationID = adminExtras.getString(MyConstants.AFFILIATION_ID);
  dpm.setAffiliationIds(adminComponent, new HashSet<String>().add(affiliationID));

  // Continue setup of the work profile
  // ...

  dpm.setProfileEnabled(adminComponent);
}

Work profiles for other DPCs

By default, only the device owner can provision a new work profile in Android 8.0 or later. The DISALLOW_ADD_MANAGED_PROFILE user restriction prevents other installed DPCs from provisioning a work profile unless explicitly lifted by the device owner. The example below shows how a device owner might remove the restriction.

// Clear the add managed profile restriction
UserManager userManager = (UserManager)context.getSystemService(Context.USER_SERVICE);
userManager.clearUserRestriction(mAdminComponent, UserManager.DISALLOW_ADD_MANAGED_PROFILE);

// Now other DPCs can create a work profile

Your DPC can use DISALLOW_REMOVE_MANAGED_PROFILE to help keep a work profile on the device.