Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ec3cbac authored by Kholoud Mohamed's avatar Kholoud Mohamed Committed by Android (Google) Code Review
Browse files

Merge "Remove platform-signed apps from configurable cross profile apps" into rvc-dev

parents 50361212 9bbab6a6
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -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.
     *
+3 −0
Original line number Diff line number Diff line
@@ -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) {
+38 −1
Original line number Diff line number Diff line
@@ -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) {
+5 −0
Original line number Diff line number Diff line
@@ -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.
         *
+24 −0
Original line number Diff line number Diff line
@@ -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)) {