Copy the device manager role holder to the other profile during
provisioning

Bug: 217179880
Test: manual
Test: CTS test not viable yet, tracked in b/213151315
Change-Id: Icfe12335e8007d8c57e40194843a76dff01f47c9
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index ee64a73..302ab239 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -214,6 +214,7 @@
 import android.app.admin.UnsafeStateException;
 import android.app.backup.IBackupManager;
 import android.app.compat.CompatChanges;
+import android.app.role.RoleManager;
 import android.app.trust.TrustManager;
 import android.app.usage.UsageStatsManagerInternal;
 import android.compat.annotation.ChangeId;
@@ -10855,6 +10856,8 @@
         final int userHandle = user.getIdentifier();
         final long id = mInjector.binderClearCallingIdentity();
         try {
+            maybeInstallDeviceManagerRoleHolderInUser(userHandle);
+
             manageUserUnchecked(admin, profileOwner, userHandle, adminExtras,
                     /* showDisclaimer= */ true);
 
@@ -17676,6 +17679,9 @@
             }
 
             final long startTime = SystemClock.elapsedRealtime();
+
+            onCreateAndProvisionManagedProfileStarted(provisioningParams);
+
             final Set<String> nonRequiredApps = provisioningParams.isLeaveAllSystemAppsEnabled()
                     ? Collections.emptySet()
                     : mOverlayPackagesProvider.getNonRequiredApps(
@@ -17687,6 +17693,7 @@
                     Slogf.i(LOG_TAG, "Disallowed package [" + packageName + "]");
                 }
             }
+
             userInfo = mUserManager.createProfileForUserEvenWhenDisallowed(
                     provisioningParams.getProfileName(),
                     UserManager.USER_TYPE_PROFILE_MANAGED,
@@ -17705,7 +17712,7 @@
                     startTime,
                     callerPackage);
 
-            onCreateAndProvisionManagedProfileStarted(provisioningParams);
+            maybeInstallDeviceManagerRoleHolderInUser(userInfo.id);
 
             installExistingAdminPackage(userInfo.id, admin.getPackageName());
             if (!enableAdminAndSetProfileOwner(
@@ -17773,6 +17780,43 @@
     private void onCreateAndProvisionManagedProfileCompleted(
             ManagedProfileProvisioningParams provisioningParams) {}
 
+    private void maybeInstallDeviceManagerRoleHolderInUser(int targetUserId) {
+        String deviceManagerRoleHolderPackageName = getDeviceManagerRoleHolderPackageName(mContext);
+        if (deviceManagerRoleHolderPackageName == null) {
+            Slogf.d(LOG_TAG, "No device manager role holder specified.");
+            return;
+        }
+        try {
+            if (mIPackageManager.isPackageAvailable(
+                    deviceManagerRoleHolderPackageName, targetUserId)) {
+                Slogf.d(LOG_TAG, "The device manager role holder "
+                        + deviceManagerRoleHolderPackageName + " is already installed in "
+                        + "user " + targetUserId);
+                return;
+            }
+            Slogf.d(LOG_TAG, "Installing the device manager role holder "
+                    + deviceManagerRoleHolderPackageName + " in user " + targetUserId);
+            mIPackageManager.installExistingPackageAsUser(
+                    deviceManagerRoleHolderPackageName,
+                    targetUserId,
+                    PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+                    PackageManager.INSTALL_REASON_POLICY,
+                    /* whiteListedPermissions= */ null);
+        } catch (RemoteException e) {
+            // Does not happen, same process
+        }
+    }
+
+    private String getDeviceManagerRoleHolderPackageName(Context context) {
+        RoleManager roleManager = context.getSystemService(RoleManager.class);
+        List<String> roleHolders =
+                roleManager.getRoleHolders(RoleManager.ROLE_DEVICE_MANAGER);
+        if (roleHolders.isEmpty()) {
+            return null;
+        }
+        return roleHolders.get(0);
+    }
+
     private void resetInteractAcrossProfilesAppOps() {
         mInjector.getCrossProfileApps().clearInteractAcrossProfilesAppOps();
         pregrantDefaultInteractAcrossProfilesAppOps();