Merge "Remove platform-signed apps from configurable cross profile apps" into rvc-dev am: 5ec3cbac4c

Change-Id: I190c4e382efa6f421f660cf2e316807766dfa9d3
This commit is contained in:
Kholoud Mohamed
2020-04-07 09:56:52 +00:00
committed by Automerger Merge Worker
5 changed files with 85 additions and 4 deletions

View File

@@ -176,18 +176,30 @@ public abstract class DevicePolicyManagerInternal {
* for cross-profile communication, via {@link * for cross-profile communication, via {@link
* DevicePolicyManager#setCrossProfilePackages(ComponentName, Set)}.</li> * DevicePolicyManager#setCrossProfilePackages(ComponentName, Set)}.</li>
* <li>The default package names that are allowed to request user consent for cross-profile * <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 * communication without being explicitly enabled by the admin, via
* DevicePolicyManager#setDefaultCrossProfilePackages(ComponentName, UserHandle, Set)}.</li> * {@link com.android.internal.R.array#cross_profile_apps} and
* {@link com.android.internal.R.array#vendor_cross_profile_apps}.</li>
* </ul> * </ul>
* *
* @return the combined set of whitelisted package names set via * @return the combined set of whitelisted package names set via
* {@link DevicePolicyManager#setCrossProfilePackages(ComponentName, Set)} and * {@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 * @hide
*/ */
public abstract List<String> getAllCrossProfilePackages(); 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. * Sends the {@code intent} to the packages with cross profile capabilities.
* *

View File

@@ -435,6 +435,9 @@ public class CrossProfileApps {
* <p>This differs from {@link #canConfigureInteractAcrossProfiles(String)} since it will * <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. * 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 * @hide
*/ */
public boolean canUserAttemptToConfigureInteractAcrossProfiles(String packageName) { public boolean canUserAttemptToConfigureInteractAcrossProfiles(String packageName) {

View File

@@ -294,6 +294,12 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
.getAllCrossProfilePackages().contains(packageName)); .getAllCrossProfilePackages().contains(packageName));
} }
private boolean isCrossProfilePackageWhitelistedByDefault(String packageName) {
return mInjector.withCleanCallingIdentity(() ->
mInjector.getDevicePolicyManagerInternal()
.getDefaultCrossProfilePackages().contains(packageName));
}
private List<UserHandle> getTargetUserProfilesUnchecked( private List<UserHandle> getTargetUserProfilesUnchecked(
String packageName, @UserIdInt int userId) { String packageName, @UserIdInt int userId) {
return mInjector.withCleanCallingIdentity(() -> { return mInjector.withCleanCallingIdentity(() -> {
@@ -528,6 +534,9 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
@Override @Override
public boolean canConfigureInteractAcrossProfiles(String packageName) { public boolean canConfigureInteractAcrossProfiles(String packageName) {
if (!canUserAttemptToConfigureInteractAcrossProfiles(packageName)) {
return false;
}
if (!hasOtherProfileWithPackageInstalled(packageName, mInjector.getCallingUserId())) { if (!hasOtherProfileWithPackageInstalled(packageName, mInjector.getCallingUserId())) {
return false; return false;
} }
@@ -546,7 +555,35 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
return false; return false;
} }
return hasRequestedAppOpPermission( 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) { private boolean hasOtherProfileWithPackageInstalled(String packageName, @UserIdInt int userId) {

View File

@@ -12459,6 +12459,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
return DevicePolicyManagerService.this.getAllCrossProfilePackages(); return DevicePolicyManagerService.this.getAllCrossProfilePackages();
} }
@Override
public List<String> getDefaultCrossProfilePackages() {
return DevicePolicyManagerService.this.getDefaultCrossProfilePackages();
}
/** /**
* Sends the {@code intent} to the packages with cross profile capabilities. * Sends the {@code intent} to the packages with cross profile capabilities.
* *

View File

@@ -199,6 +199,12 @@ public class CrossProfileAppsServiceImplRoboTest {
CROSS_PROFILE_APP_PACKAGE_NAME, PERSONAL_PROFILE_UID, PERSONAL_PROFILE_USER_ID); CROSS_PROFILE_APP_PACKAGE_NAME, PERSONAL_PROFILE_UID, PERSONAL_PROFILE_USER_ID);
ShadowApplicationPackageManager.setPackageUidAsUser( ShadowApplicationPackageManager.setPackageUidAsUser(
CROSS_PROFILE_APP_PACKAGE_NAME, WORK_PROFILE_UID, WORK_PROFILE_USER_ID); 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 @Before
@@ -455,6 +461,19 @@ public class CrossProfileAppsServiceImplRoboTest {
.isTrue(); .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 @Test
public void canUserAttemptToConfigureInteractAcrossProfiles_returnsTrue() { public void canUserAttemptToConfigureInteractAcrossProfiles_returnsTrue() {
assertThat(mCrossProfileAppsServiceImpl assertThat(mCrossProfileAppsServiceImpl
@@ -528,6 +547,11 @@ public class CrossProfileAppsServiceImplRoboTest {
.thenReturn(new ArrayList<>()); .thenReturn(new ArrayList<>());
} }
private void mockCrossProfileAppNotWhitelistedByOem() {
when(mDevicePolicyManagerInternal.getDefaultCrossProfilePackages())
.thenReturn(new ArrayList<>());
}
private boolean receivedManifestCanInteractAcrossProfilesChangedBroadcast() { private boolean receivedManifestCanInteractAcrossProfilesChangedBroadcast() {
final UserHandle userHandle = UserHandle.of(PERSONAL_PROFILE_USER_ID); final UserHandle userHandle = UserHandle.of(PERSONAL_PROFILE_USER_ID);
if (!mSentUserBroadcasts.containsKey(userHandle)) { if (!mSentUserBroadcasts.containsKey(userHandle)) {