Merge "Remove platform-signed apps from configurable cross profile apps" into rvc-dev am: 5ec3cbac4c
Change-Id: Ie42fa91d493e743921990cf1e3b2387b4699037d
This commit is contained in:
@@ -176,18 +176,30 @@ public abstract class DevicePolicyManagerInternal {
|
||||
* for cross-profile communication, via {@link
|
||||
* DevicePolicyManager#setCrossProfilePackages(ComponentName, Set)}.</li>
|
||||
* <li>The default package names that are allowed to request user consent for cross-profile
|
||||
* communication without being explicitly enabled by the admin , via {@link
|
||||
* DevicePolicyManager#setDefaultCrossProfilePackages(ComponentName, UserHandle, Set)}.</li>
|
||||
* communication without being explicitly enabled by the admin, via
|
||||
* {@link com.android.internal.R.array#cross_profile_apps} and
|
||||
* {@link com.android.internal.R.array#vendor_cross_profile_apps}.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return the combined set of whitelisted package names set via
|
||||
* {@link DevicePolicyManager#setCrossProfilePackages(ComponentName, Set)} and
|
||||
* {@link DevicePolicyManager#setDefaultCrossProfilePackages(ComponentName, UserHandle, Set)}
|
||||
* {@link com.android.internal.R.array#cross_profile_apps} and
|
||||
* {@link com.android.internal.R.array#vendor_cross_profile_apps}
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public abstract List<String> getAllCrossProfilePackages();
|
||||
|
||||
/**
|
||||
* Returns the default package names set by the OEM that are allowed to request user consent for
|
||||
* cross-profile communication without being explicitly enabled by the admin, via
|
||||
* {@link com.android.internal.R.array#cross_profile_apps} and
|
||||
* {@link com.android.internal.R.array#vendor_cross_profile_apps}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public abstract List<String> getDefaultCrossProfilePackages();
|
||||
|
||||
/**
|
||||
* Sends the {@code intent} to the packages with cross profile capabilities.
|
||||
*
|
||||
|
||||
@@ -435,6 +435,9 @@ public class CrossProfileApps {
|
||||
* <p>This differs from {@link #canConfigureInteractAcrossProfiles(String)} since it will
|
||||
* not return {@code false} if the app is not whitelisted or not installed in the other profile.
|
||||
*
|
||||
* <p>Note that platform-signed apps that are automatically granted the permission and are not
|
||||
* whitelisted by the OEM will not be included in this list.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public boolean canUserAttemptToConfigureInteractAcrossProfiles(String packageName) {
|
||||
|
||||
@@ -294,6 +294,12 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
|
||||
.getAllCrossProfilePackages().contains(packageName));
|
||||
}
|
||||
|
||||
private boolean isCrossProfilePackageWhitelistedByDefault(String packageName) {
|
||||
return mInjector.withCleanCallingIdentity(() ->
|
||||
mInjector.getDevicePolicyManagerInternal()
|
||||
.getDefaultCrossProfilePackages().contains(packageName));
|
||||
}
|
||||
|
||||
private List<UserHandle> getTargetUserProfilesUnchecked(
|
||||
String packageName, @UserIdInt int userId) {
|
||||
return mInjector.withCleanCallingIdentity(() -> {
|
||||
@@ -528,6 +534,9 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
|
||||
|
||||
@Override
|
||||
public boolean canConfigureInteractAcrossProfiles(String packageName) {
|
||||
if (!canUserAttemptToConfigureInteractAcrossProfiles(packageName)) {
|
||||
return false;
|
||||
}
|
||||
if (!hasOtherProfileWithPackageInstalled(packageName, mInjector.getCallingUserId())) {
|
||||
return false;
|
||||
}
|
||||
@@ -546,7 +555,35 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
|
||||
return false;
|
||||
}
|
||||
return hasRequestedAppOpPermission(
|
||||
AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName);
|
||||
AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName)
|
||||
&& !isPlatformSignedAppWithNonUserConfigurablePermission(packageName, profileIds);
|
||||
}
|
||||
|
||||
private boolean isPlatformSignedAppWithNonUserConfigurablePermission(
|
||||
String packageName, int[] profileIds) {
|
||||
return !isCrossProfilePackageWhitelistedByDefault(packageName)
|
||||
&& isPlatformSignedAppWithAutomaticProfilesPermission(packageName, profileIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only platform-signed apps can be granted INTERACT_ACROSS_PROFILES automatically without user
|
||||
* consent.
|
||||
*
|
||||
* Returns true if the app is automatically granted the permission in at least one profile.
|
||||
*/
|
||||
private boolean isPlatformSignedAppWithAutomaticProfilesPermission(
|
||||
String packageName, int[] profileIds) {
|
||||
for (int userId : profileIds) {
|
||||
final int uid = mInjector.getPackageManagerInternal().getPackageUidInternal(
|
||||
packageName, /* flags= */ 0, userId);
|
||||
if (uid == -1) {
|
||||
continue;
|
||||
}
|
||||
if (isPermissionGranted(Manifest.permission.INTERACT_ACROSS_PROFILES, uid)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasOtherProfileWithPackageInstalled(String packageName, @UserIdInt int userId) {
|
||||
|
||||
@@ -12459,6 +12459,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
return DevicePolicyManagerService.this.getAllCrossProfilePackages();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getDefaultCrossProfilePackages() {
|
||||
return DevicePolicyManagerService.this.getDefaultCrossProfilePackages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the {@code intent} to the packages with cross profile capabilities.
|
||||
*
|
||||
|
||||
@@ -199,6 +199,12 @@ public class CrossProfileAppsServiceImplRoboTest {
|
||||
CROSS_PROFILE_APP_PACKAGE_NAME, PERSONAL_PROFILE_UID, PERSONAL_PROFILE_USER_ID);
|
||||
ShadowApplicationPackageManager.setPackageUidAsUser(
|
||||
CROSS_PROFILE_APP_PACKAGE_NAME, WORK_PROFILE_UID, WORK_PROFILE_USER_ID);
|
||||
when(mPackageManagerInternal.getPackageUidInternal(
|
||||
CROSS_PROFILE_APP_PACKAGE_NAME, /* flags= */ 0, PERSONAL_PROFILE_USER_ID))
|
||||
.thenReturn(PERSONAL_PROFILE_UID);
|
||||
when(mPackageManagerInternal.getPackageUidInternal(
|
||||
CROSS_PROFILE_APP_PACKAGE_NAME, /* flags= */ 0, WORK_PROFILE_USER_ID))
|
||||
.thenReturn(WORK_PROFILE_UID);
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -455,6 +461,19 @@ public class CrossProfileAppsServiceImplRoboTest {
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canUserAttemptToConfigureInteractAcrossProfiles_platformSignedAppWithAutomaticPermission_returnsFalse() {
|
||||
mockCrossProfileAppNotWhitelistedByOem();
|
||||
shadowOf(mContext).grantPermissions(
|
||||
Process.myPid(),
|
||||
PERSONAL_PROFILE_UID,
|
||||
Manifest.permission.INTERACT_ACROSS_PROFILES);
|
||||
|
||||
assertThat(mCrossProfileAppsServiceImpl
|
||||
.canUserAttemptToConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canUserAttemptToConfigureInteractAcrossProfiles_returnsTrue() {
|
||||
assertThat(mCrossProfileAppsServiceImpl
|
||||
@@ -528,6 +547,11 @@ public class CrossProfileAppsServiceImplRoboTest {
|
||||
.thenReturn(new ArrayList<>());
|
||||
}
|
||||
|
||||
private void mockCrossProfileAppNotWhitelistedByOem() {
|
||||
when(mDevicePolicyManagerInternal.getDefaultCrossProfilePackages())
|
||||
.thenReturn(new ArrayList<>());
|
||||
}
|
||||
|
||||
private boolean receivedManifestCanInteractAcrossProfilesChangedBroadcast() {
|
||||
final UserHandle userHandle = UserHandle.of(PERSONAL_PROFILE_USER_ID);
|
||||
if (!mSentUserBroadcasts.containsKey(userHandle)) {
|
||||
|
||||
Reference in New Issue
Block a user