Merge "Prevent DPCs from requesting INTERACT_ACROSS_PROFILES" into rvc-dev am: 5d6cf38cd1 am: 3fb3ffeda8 am: 39bca2cdec
Change-Id: I6670634d6f78a68a02613cd42c8e0f310fdd8723
This commit is contained in:
@@ -217,4 +217,9 @@ public abstract class DevicePolicyManagerInternal {
|
||||
*/
|
||||
public abstract void broadcastIntentToCrossProfileManifestReceiversAsUser(Intent intent,
|
||||
UserHandle parentHandle, boolean requiresPermission);
|
||||
|
||||
/**
|
||||
* Returns the profile owner component for the given user, or {@code null} if there is not one.
|
||||
*/
|
||||
public abstract ComponentName getProfileOwnerAsUser(int userHandle);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.app.AppOpsManager;
|
||||
import android.app.AppOpsManager.Mode;
|
||||
import android.app.IApplicationThread;
|
||||
import android.app.admin.DevicePolicyEventLogger;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.admin.DevicePolicyManagerInternal;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@@ -256,6 +257,9 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
|
||||
if (enabledProfileIds.length < 2) {
|
||||
return false;
|
||||
}
|
||||
if (isProfileOwner(packageName, enabledProfileIds)) {
|
||||
return false;
|
||||
}
|
||||
return hasRequestedAppOpPermission(
|
||||
AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName);
|
||||
}
|
||||
@@ -575,6 +579,9 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
|
||||
if (profileIds.length < 2) {
|
||||
return false;
|
||||
}
|
||||
if (isProfileOwner(packageName, profileIds)) {
|
||||
return false;
|
||||
}
|
||||
return hasRequestedAppOpPermission(
|
||||
AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName)
|
||||
&& !isPlatformSignedAppWithNonUserConfigurablePermission(packageName, profileIds);
|
||||
@@ -698,6 +705,25 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
|
||||
packageName);
|
||||
}
|
||||
|
||||
private boolean isProfileOwner(String packageName, int[] userIds) {
|
||||
for (int userId : userIds) {
|
||||
if (isProfileOwner(packageName, userId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isProfileOwner(String packageName, final @UserIdInt int userId) {
|
||||
final ComponentName profileOwner =
|
||||
mInjector.withCleanCallingIdentity(() ->
|
||||
mInjector.getDevicePolicyManagerInternal().getProfileOwnerAsUser(userId));
|
||||
if (profileOwner == null) {
|
||||
return false;
|
||||
}
|
||||
return profileOwner.getPackageName().equals(packageName);
|
||||
}
|
||||
|
||||
private static class InjectorImpl implements Injector {
|
||||
private Context mContext;
|
||||
|
||||
|
||||
@@ -12730,6 +12730,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentName getProfileOwnerAsUser(int userHandle) {
|
||||
return DevicePolicyManagerService.this.getProfileOwnerAsUser(userHandle);
|
||||
}
|
||||
}
|
||||
|
||||
private Intent createShowAdminSupportIntent(ComponentName admin, int userId) {
|
||||
|
||||
@@ -37,7 +37,9 @@ import android.annotation.UserIdInt;
|
||||
import android.app.ActivityManagerInternal;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.AppOpsManager.Mode;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.admin.DevicePolicyManagerInternal;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
@@ -97,6 +99,7 @@ public class CrossProfileAppsServiceImplRoboTest {
|
||||
private static final int WORK_PROFILE_USER_ID = 10;
|
||||
private static final int WORK_PROFILE_UID = 3333;
|
||||
private static final int OTHER_PROFILE_WITHOUT_CROSS_PROFILE_APP_USER_ID = 20;
|
||||
private static final int OUTSIDE_PROFILE_GROUP_USER_ID = 30;
|
||||
|
||||
private final ContextWrapper mContext = ApplicationProvider.getApplicationContext();
|
||||
private final UserManager mUserManager = mContext.getSystemService(UserManager.class);
|
||||
@@ -226,6 +229,7 @@ public class CrossProfileAppsServiceImplRoboTest {
|
||||
PERSONAL_PROFILE_USER_ID,
|
||||
WORK_PROFILE_USER_ID,
|
||||
OTHER_PROFILE_WITHOUT_CROSS_PROFILE_APP_USER_ID);
|
||||
shadowUserManager.addProfileIds(OUTSIDE_PROFILE_GROUP_USER_ID);
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -503,6 +507,36 @@ public class CrossProfileAppsServiceImplRoboTest {
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canUserAttemptToConfigureInteractAcrossProfiles_profileOwnerWorkProfile_returnsFalse() {
|
||||
when(mDevicePolicyManagerInternal.getProfileOwnerAsUser(WORK_PROFILE_USER_ID))
|
||||
.thenReturn(buildCrossProfileComponentName());
|
||||
assertThat(mCrossProfileAppsServiceImpl
|
||||
.canUserAttemptToConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canUserAttemptToConfigureInteractAcrossProfiles_profileOwnerOtherProfile_returnsFalse() {
|
||||
// Normally, the DPC would not be a profile owner of the personal profile, but for the
|
||||
// purposes of this test, it is just a profile owner of any profile within the profile
|
||||
// group.
|
||||
when(mDevicePolicyManagerInternal.getProfileOwnerAsUser(PERSONAL_PROFILE_USER_ID))
|
||||
.thenReturn(buildCrossProfileComponentName());
|
||||
assertThat(mCrossProfileAppsServiceImpl
|
||||
.canUserAttemptToConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canUserAttemptToConfigureInteractAcrossProfiles_profileOwnerOutsideProfileGroup_returnsTrue() {
|
||||
when(mDevicePolicyManagerInternal.getProfileOwnerAsUser(OUTSIDE_PROFILE_GROUP_USER_ID))
|
||||
.thenReturn(buildCrossProfileComponentName());
|
||||
assertThat(mCrossProfileAppsServiceImpl
|
||||
.canUserAttemptToConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canUserAttemptToConfigureInteractAcrossProfiles_returnsTrue() {
|
||||
assertThat(mCrossProfileAppsServiceImpl
|
||||
@@ -607,6 +641,10 @@ public class CrossProfileAppsServiceImplRoboTest {
|
||||
.hideAsParsed()).hideAsFinal());
|
||||
}
|
||||
|
||||
private ComponentName buildCrossProfileComponentName() {
|
||||
return new ComponentName(CROSS_PROFILE_APP_PACKAGE_NAME, "testClassName");
|
||||
}
|
||||
|
||||
private class TestInjector implements CrossProfileAppsServiceImpl.Injector {
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user