Checking if there is already a work profile, who owns it and if it is active
Asked Answered
H

2

5

What I need feels fairly straightforward and it's so frustrating that the Android for Work API doesn't appear to provide it out-of-the-box.

I am trying to create an Android DPC app to own and manage the Work Profile. (NOT device owner). When you provision the work profile, you get two instances of your application. One badged running under the Work Profile and the other unbadged running under the Primary Profile. enter image description here

I am trying to find out some three things:

  • Is the Work Profile already provisioned on the device?
  • If so, is it my app that owns the profile? If not which app does?
  • Is the Work Profile active?

The reason is, even in Google's own sample app (see image) it doesn't try to establish this and initiates provisioning even when there is already a work profile and the app is actually the owner!

Heartbreaking answered 13/6, 2018 at 10:42 Comment(0)
O
6

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;
    }
}
Orangewood answered 15/6, 2018 at 5:6 Comment(3)
Thank you for your answer. I have tried 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
Miscovetz please see this answer for more info: https://mcmap.net/q/726409/-android-for-work-how-to-check-if-my-application-is-running-in-the-work-profileHeartbreaking
Added an edit to my post that will hopefully help on Android N and above.Orangewood
S
1
  1. Create an activity with a special intent filter and set android:enabled="false". Override onCreate in order to set a result and then immediately finish.
  2. Within your implementation of DeviceAdminReceiver::onProfileProvisioningComplete, enable your special activity with PackageManager::setComponentEnabledSetting and add a cross-profile intent filter so it can be called from the primary profile.
  3. When your main activity opens:
    1. If DeviceProfileManager::isProfileOwnerApp returns true, you're running in your managed profile.
    2. Otherwise, use startActivityForResult to start an Intent that matches your cross-profile intent filter. Use Intent::setPackage to ensure that only your package can respond to it.
    3. If startActivityForResult throws an exception, your managed profile is not set up. If UserManager::getUserProfiles returns only one profile, no managed profile is setup; otherwise, some other app's managed profile is setup.
    4. If your managed profile is setup, you'll get a call to onActivityResult including any data you send to yourself, such as the UserHandle for the managed profile.
Sawhorse answered 14/5, 2019 at 1:3 Comment(3)
This is the right answer, and I can confirm it works. However I'm only using PackageManager.resolveActivity to know if the managed profile activity exists or not.Cannon
If you only need to know whether it exists, that might be good enough, but if you need the UserHandle, you should follow this procedure. In particular, note that Google has been working on support for having multiple work profiles at the same time, so disambiguation may be required.Sawhorse
Actually a cross-profile intent filter may be used in both directions, so having an activity with a no-display theme that receives responses from a work profile app may be used to discover apps in multiple profiles.Cannon

© 2022 - 2024 — McMap. All rights reserved.