Is the Work Profile already provisioned on the device?
If so, is it my app that owns the profile? If not which app does?
This code will work when run under the primary user. A profile owner for a primary user will be the work profile. It will log your own package if your app owns it.
DevicePolicyManager manager =
(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
List<ComponentName> activeAdmins = manager.getActiveAdmins();
if (activeAdmins != null){
for (ComponentName admin : activeAdmins){
String packageName = admin.getPackageName();
if (manager.isProfileOwnerApp(packageName)){
Log.d(TAG, "Work Profile is: " + packageName);
}
}
}
Use this if you just want to check if your app is the profile owner within your app.
manager.isProfileOwnerApp(getApplicationContext().getPackage());
Is the Work Profile active?
If isProfileOwnerApp() returns true for any package under the primary user, the work profile is active and owned by that package.
Secondary users can also be provisioned with a profile owner on a device that supports multi-users, but I have not seen this implemented by an EMM yet. A device owner would need to assign your package's component as the profile owner of a secondary user, so it is probably safe to say that won't happen. But if it does, your app should work just like a work profile, but in the context of a secondary user as a managed profile.
* EDIT (6/15/18) *:
I tested your scenario on an Android O device and I did not get the same behavior. After provisioning a work profile from TestDPC, TestDPC detected that a managed profile had already been provisioned and would not let me provision again.
What version of Android are you developing on?
I dug into TestDPC and found some code, modified for your scenario, that may help you. Unfortunately for Android M and below, TestDPC will not detect that the device had already been provisioned with a work profile and will just attempt it again. Additionally, I didn't find a way to detect who that profile owner is, your app or another app. But I hope this helps!
/**
* @param context Calling activity's context
* @return true, if work profile provisioning is allowed
*/
@TargetApi(Build.VERSION_CODES.N)
public static boolean isProvisioningAllowed(Context context) {
if (BuildCompat.isAtLeastN()) {
DevicePolicyManager dpm = (DevicePolicyManager) context
.getSystemService(Context.DEVICE_POLICY_SERVICE);
return dpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_DEVICE);
}
else {
return true;
}
}
manager.isProfileOwnerApp(getApplicationContext().getPackage());
Unfortunately, it will return true only if called FROM THE MANAGED PROFILE when my app is the profile owner. If called from the primary profile EVEN WHEN MY APP OWNS THE WORK PROFILE, it will return false. I need my app to initiate provisioning ONLY if it is not the owner of the managed profile. – Heartbreaking