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

Commit 2d535bf2 authored by Nate Myren's avatar Nate Myren
Browse files

Check for fixed permissions when restoring notification permissions

Ensure that REVIEW_REQUIRED is not set on system or policy fixed
permissions, or on GRANTED_BY_DEFAULT and GRANTED_BY_ROLE permissions.
Also removes Droidfooder-only state

Fixes: 218593876
Test: PermissionHelperTest
Change-Id: Ia830aa0fe4e60292d5808f29f126392e52883596
parent f501ad2d
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -178,6 +178,12 @@ public final class PermissionHelper {
            boolean userSet, boolean reviewRequired) {
        assertFlag();
        final long callingId = Binder.clearCallingIdentity();
        // Do not change fixed permissions, and do not change non-user set permissions that are
        // granted by default, or granted by role.
        if (isPermissionFixed(packageName, userId)
                || (isPermissionGrantedByDefaultOrRole(packageName, userId) && !userSet)) {
            return;
        }
        try {
            if (grant && !reviewRequired) {
                mPermManager.grantRuntimePermission(packageName, NOTIFICATION_PERMISSION, userId);
@@ -252,6 +258,24 @@ public final class PermissionHelper {
        }
    }

    boolean isPermissionGrantedByDefaultOrRole(String packageName, @UserIdInt int userId) {
        assertFlag();
        final long callingId = Binder.clearCallingIdentity();
        try {
            try {
                int flags = mPermManager.getPermissionFlags(packageName, NOTIFICATION_PERMISSION,
                        userId);
                return (flags & (PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT
                        | PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE)) != 0;
            } catch (RemoteException e) {
                Slog.e(TAG, "Could not reach system server", e);
            }
            return false;
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
    }

    private void assertFlag() {
        if (!mMigrationEnabled) {
            throw new IllegalStateException("Method called without checking flag value");
+0 −32
Original line number Diff line number Diff line
@@ -3170,44 +3170,12 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
                    inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms, newPerm, ps,
                            pkg);
                }
            } else if (NOTIFICATION_PERMISSIONS.contains(newPerm)) {
                //&& (origPs.getPermissionState(newPerm) == null) {
                // TODO(b/205888750): add back line about origPs once all TODO sections below are
                //  propagated through droidfood
                Permission bp = mRegistry.getPermission(newPerm);
                if (bp == null) {
                    throw new IllegalStateException("Unknown new permission " + newPerm);
                }
                if (!isUserSetOrPregrantedOrFixed(ps.getPermissionFlags(newPerm))) {
                    updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
                    int setFlag = ps.isPermissionGranted(newPerm)
                            ? 0 : FLAG_PERMISSION_REVIEW_REQUIRED;
                    ps.updatePermissionFlags(bp, FLAG_PERMISSION_REVIEW_REQUIRED, setFlag);
                    // TODO(b/205888750): remove if/else block once propagated through droidfood
                    if (ps.isPermissionGranted(newPerm)
                            && pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M) {
                        ps.revokePermission(bp);
                    } else if (!ps.isPermissionGranted(newPerm)
                            && pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
                        ps.grantPermission(bp);
                    }
                } else {
                    // TODO(b/205888750): remove once propagated through droidfood
                    ps.updatePermissionFlags(bp, FLAG_PERMISSION_REVOKE_WHEN_REQUESTED
                            | FLAG_PERMISSION_REVIEW_REQUIRED, 0);
                }
            }
        }

        return updatedUserIds;
    }

    private boolean isUserSetOrPregrantedOrFixed(int flags) {
        return (flags & (FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED
                | FLAG_PERMISSION_POLICY_FIXED | FLAG_PERMISSION_SYSTEM_FIXED
                | FLAG_PERMISSION_GRANTED_BY_DEFAULT | FLAG_PERMISSION_GRANTED_BY_ROLE)) != 0;
    }

    @NonNull
    @Override
    public List<SplitPermissionInfoParcelable> getSplitPermissions() {
+60 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
package com.android.server.notification;

import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
@@ -251,6 +252,39 @@ public class PermissionHelperTest extends UiServiceTestCase {
                FLAG_PERMISSION_REVIEW_REQUIRED, FLAG_PERMISSION_REVIEW_REQUIRED, true, 10);
    }

    @Test
    public void testSetNotificationPermission_pkgPerm_notUserSet_grantedByDefaultPermNotSet()
            throws Exception {
        when(mPermManager.getPermissionFlags(anyString(),
                eq(Manifest.permission.POST_NOTIFICATIONS),
                anyInt())).thenReturn(FLAG_PERMISSION_GRANTED_BY_DEFAULT);
        PermissionHelper.PackagePermission pkgPerm = new PermissionHelper.PackagePermission(
                "pkg", 10, true, false);

        mPermissionHelper.setNotificationPermission(pkgPerm);
        verify(mPermManager, never()).revokeRuntimePermission(
                anyString(), anyString(), anyInt(), anyString());
        verify(mPermManager, never()).updatePermissionFlags(
                anyString(), anyString(), anyInt(), anyInt(), anyBoolean(), anyInt());
    }

    @Test
    public void testSetNotificationPermission_pkgPerm_userSet_grantedByDefaultPermSet()
            throws Exception {
        when(mPermManager.getPermissionFlags(anyString(),
                eq(Manifest.permission.POST_NOTIFICATIONS),
                anyInt())).thenReturn(FLAG_PERMISSION_GRANTED_BY_DEFAULT);
        PermissionHelper.PackagePermission pkgPerm = new PermissionHelper.PackagePermission(
                "pkg", 10, true, true);

        mPermissionHelper.setNotificationPermission(pkgPerm);
        verify(mPermManager).grantRuntimePermission(
                "pkg", Manifest.permission.POST_NOTIFICATIONS, 10);
        verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
                FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_REVIEW_REQUIRED,
                FLAG_PERMISSION_USER_SET, true, 10);
    }

    @Test
    public void testSetNotificationPermission_revokeUserSet() throws Exception {
        mPermissionHelper.setNotificationPermission("pkg", 10, false, true);
@@ -282,6 +316,32 @@ public class PermissionHelperTest extends UiServiceTestCase {
                anyString(), anyString(), anyInt(), anyInt(), anyBoolean(), anyInt());
    }

    @Test
    public void testSetNotificationPermission_SystemFixedPermNotSet() throws Exception {
        when(mPermManager.getPermissionFlags(anyString(),
                eq(Manifest.permission.POST_NOTIFICATIONS),
                anyInt())).thenReturn(FLAG_PERMISSION_SYSTEM_FIXED);

        mPermissionHelper.setNotificationPermission("pkg", 10, false, true);
        verify(mPermManager, never()).revokeRuntimePermission(
                anyString(), anyString(), anyInt(), anyString());
        verify(mPermManager, never()).updatePermissionFlags(
                anyString(), anyString(), anyInt(), anyInt(), anyBoolean(), anyInt());
    }

    @Test
    public void testSetNotificationPermission_PolicyFixedPermNotSet() throws Exception {
        when(mPermManager.getPermissionFlags(anyString(),
                eq(Manifest.permission.POST_NOTIFICATIONS),
                anyInt())).thenReturn(FLAG_PERMISSION_POLICY_FIXED);

        mPermissionHelper.setNotificationPermission("pkg", 10, false, true);
        verify(mPermManager, never()).revokeRuntimePermission(
                anyString(), anyString(), anyInt(), anyString());
        verify(mPermManager, never()).updatePermissionFlags(
                anyString(), anyString(), anyInt(), anyInt(), anyBoolean(), anyInt());
    }

    @Test
    public void testIsPermissionFixed() throws Exception {
        when(mPermManager.getPermissionFlags(anyString(),