summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/admin/DevicePolicyManagerInternal.java18
-rw-r--r--core/java/android/content/pm/CrossProfileApps.java3
-rw-r--r--services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java39
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java5
-rw-r--r--services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java24
5 files changed, 85 insertions, 4 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java
index 80fa87152d78..41f04f73aa87 100644
--- a/core/java/android/app/admin/DevicePolicyManagerInternal.java
+++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java
@@ -176,19 +176,31 @@ 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.
*
* <p>This means the application must have the {@code crossProfile} property and the
diff --git a/core/java/android/content/pm/CrossProfileApps.java b/core/java/android/content/pm/CrossProfileApps.java
index 7578ede2648d..144a07eb4ea3 100644
--- a/core/java/android/content/pm/CrossProfileApps.java
+++ b/core/java/android/content/pm/CrossProfileApps.java
@@ -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) {
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
index 40876754eae8..28c8642d3e60 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
@@ -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) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index d1c47d9feed7..67e83bad154f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -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.
*
diff --git a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
index 138f9829c088..f8d197acf883 100644
--- a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
+++ b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
@@ -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
@@ -456,6 +462,19 @@ public class CrossProfileAppsServiceImplRoboTest {
}
@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
.canUserAttemptToConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME))
@@ -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)) {