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

Commit 4b0624fe authored by Bartosz Fabianowski's avatar Bartosz Fabianowski
Browse files

Allow system to retrieve permission grant state

To inform the user which apps were granted permissions by the admin,
the Settings app needs to access this information without being a DO/PO.

Bug: 32692748
Test: FrameworksServicesTests unit test

Change-Id: I3770ec6343b85be9c6f7655675ed6db5cb50612c
parent b3a20ee4
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6317,7 +6317,7 @@ public class DevicePolicyManager {
     * @see #setPermissionGrantState(ComponentName, String, String, int)
     * @see PackageManager#checkPermission(String, String)
     */
    public int getPermissionGrantState(@NonNull ComponentName admin, String packageName,
    public int getPermissionGrantState(@Nullable ComponentName admin, String packageName,
            String permission) {
        throwIfParentInstance("getPermissionGrantState");
        try {
+13 −1
Original line number Diff line number Diff line
@@ -6783,6 +6783,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        enforceManageUsers();
    }

    private void enforceProfileOwnerOrSystemUser(ComponentName admin) {
        synchronized (this) {
            if (getActiveAdminWithPolicyForUidLocked(admin,
                    DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, mInjector.binderGetCallingUid())
                            != null) {
                return;
            }
        }
        Preconditions.checkState(isCallerWithSystemUid(),
                "Only profile owner, device owner and system may call this method.");
    }

    private void ensureCallerPackage(@Nullable String packageName) {
        if (packageName == null) {
            Preconditions.checkState(isCallerWithSystemUid(),
@@ -8913,8 +8925,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        PackageManager packageManager = mInjector.getPackageManager();

        UserHandle user = mInjector.binderGetCallingUserHandle();
        enforceProfileOwnerOrSystemUser(admin);
        synchronized (this) {
            getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
            long ident = mInjector.binderClearCallingIdentity();
            try {
                int granted = mIPackageManager.checkPermission(permission,
+42 −0
Original line number Diff line number Diff line
@@ -3207,6 +3207,48 @@ public class DevicePolicyManagerTest extends DpmTestBase {
        }
    }

    public void testGetPermissionGrantState() throws Exception {
        final String permission = "some.permission";
        final String app1 = "com.example.app1";
        final String app2 = "com.example.app2";

        when(mContext.ipackageManager.checkPermission(eq(permission), eq(app1), anyInt()))
                .thenReturn(PackageManager.PERMISSION_GRANTED);
        doReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED).when(mContext.packageManager)
                .getPermissionFlags(permission, app1, UserHandle.SYSTEM);
        when(mContext.packageManager.getPermissionFlags(permission, app1,
                UserHandle.of(DpmMockContext.CALLER_USER_HANDLE)))
                .thenReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED);
        when(mContext.ipackageManager.checkPermission(eq(permission), eq(app2), anyInt()))
                .thenReturn(PackageManager.PERMISSION_DENIED);
        doReturn(0).when(mContext.packageManager).getPermissionFlags(permission, app2,
                UserHandle.SYSTEM);
        when(mContext.packageManager.getPermissionFlags(permission, app2,
                UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))).thenReturn(0);

        // System can retrieve permission grant state.
        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED,
                dpm.getPermissionGrantState(null, app1, permission));
        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT,
                dpm.getPermissionGrantState(null, app2, permission));

        // A regular app cannot retrieve permission grant state.
        mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
        try {
            dpm.getPermissionGrantState(null, app1, permission);
            fail("Didn't throw IllegalStateException");
        } catch (IllegalStateException expected) {
        }

        // Profile owner can retrieve permission grant state.
        setAsProfileOwner(admin1);
        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED,
                dpm.getPermissionGrantState(admin1, app1, permission));
        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT,
                dpm.getPermissionGrantState(admin1, app2, permission));
    }

    private void setUserSetupCompleteForUser(boolean isUserSetupComplete, int userhandle) {
        when(mContext.settings.settingsSecureGetIntForUser(Settings.Secure.USER_SETUP_COMPLETE, 0,
                userhandle)).thenReturn(isUserSetupComplete ? 1 : 0);