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

Commit 4505c429 authored by Evan Severson's avatar Evan Severson
Browse files

Fix wrong permission state on deny-anyway

This change fixes the behavior where denying a permission in
AppPermissionFragment which prompts the deny-anyway dialog will always
force it to select "deny" even if the denial was by selecting
"ask every time".

Fixes: 150400424
Test: Manual + atest PermissionsHostTest
Change-Id: Ie54f911eff925f9b667cfd65ee2fa5dda26e16b4
parent 00ababda
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -191,10 +191,12 @@ private suspend fun revokePermissionsOnUnusedApps(context: Context) {
                if (packageImportance > IMPORTANCE_TOP_SLEEPING) {
                    KotlinUtils.revokeBackgroundRuntimePermissions(
                            context.application, group,
                        userFixed = false, filterPermissions = revocablePermissions)
                            userFixed = false, oneTime = false,
                            filterPermissions = revocablePermissions)
                    KotlinUtils.revokeForegroundRuntimePermissions(
                            context.application, group,
                        userFixed = false, filterPermissions = revocablePermissions)
                            userFixed = false, oneTime = false,
                            filterPermissions = revocablePermissions)

                    for (permission in revocablePermissions) {
                        context.packageManager.updatePermissionFlags(
+8 −3
Original line number Diff line number Diff line
@@ -432,14 +432,16 @@ public class AppPermissionFragment extends SettingsWithLargeHeader
     * @param messageId The Id of the string message to show
     * @param buttonPressed Button which was pressed to initiate the dialog, one of
     *                      AppPermissionFragmentActionReported.button_pressed constants
     * @param oneTime Whether the one-time (ask) button was clicked rather than the deny button
     */
    @Override
    public void showDefaultDenyDialog(ChangeRequest changeRequest, @StringRes int messageId,
            int buttonPressed) {
            int buttonPressed, boolean oneTime) {
        Bundle args = getArguments().deepCopy();
        args.putInt(DefaultDenyDialog.MSG, messageId);
        args.putSerializable(DefaultDenyDialog.CHANGE_REQUEST, changeRequest);
        args.putInt(DefaultDenyDialog.BUTTON, buttonPressed);
        args.putBoolean(DefaultDenyDialog.ONE_TIME, oneTime);
        DefaultDenyDialog defaultDenyDialog = new DefaultDenyDialog();
        defaultDenyDialog.setCancelable(true);
        defaultDenyDialog.setArguments(args);
@@ -451,7 +453,8 @@ public class AppPermissionFragment extends SettingsWithLargeHeader
     * A dialog warning the user that they are about to deny a permission that was granted by
     * default, or that they are denying a permission on a Pre-M app
     *
     * @see #showDefaultDenyDialog(ChangeRequest, int, int)
     * @see AppPermissionViewModel.DefaultDenyShowingFragment#showDefaultDenyDialog(ChangeRequest,
     * int, int, boolean)
     */
    public static class DefaultDenyDialog extends DialogFragment {
        static final String MSG = DefaultDenyDialog.class.getName() + ".arg.msg";
@@ -459,6 +462,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader
                + ".arg.changeRequest";
        private static final String KEY = DefaultDenyDialog.class.getName() + ".arg.key";
        private static final String BUTTON = DefaultDenyDialog.class.getName() + ".arg.button";
        private static final String ONE_TIME = DefaultDenyDialog.class.getName() + ".arg.onetime";

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
@@ -471,7 +475,8 @@ public class AppPermissionFragment extends SettingsWithLargeHeader
                            (DialogInterface dialog, int which) ->
                                    fragment.mViewModel.onDenyAnyWay((ChangeRequest)
                                            getArguments().getSerializable(CHANGE_REQUEST),
                                            getArguments().getInt(BUTTON)));
                                            getArguments().getInt(BUTTON),
                                            getArguments().getBoolean(ONE_TIME)));
            Dialog d = b.create();
            d.setCanceledOnTouchOutside(true);
            return d;
+12 −7
Original line number Diff line number Diff line
@@ -85,7 +85,8 @@ class AppPermissionViewModel(
        fun showDefaultDenyDialog(
            changeRequest: ChangeRequest,
            @StringRes messageId: Int,
            buttonPressed: Int
            buttonPressed: Int,
            oneTime: Boolean
        )
    }

@@ -414,13 +415,15 @@ class AppPermissionViewModel(
        }

        if (showDefaultDenyDialog && !hasConfirmedRevoke && showGrantedByDefaultWarning) {
            defaultDeny.showDefaultDenyDialog(changeRequest, R.string.system_warning, buttonClicked)
            defaultDeny.showDefaultDenyDialog(changeRequest, R.string.system_warning, buttonClicked,
                    setOneTime)
            return
        }

        if (showDefaultDenyDialog && !hasConfirmedRevoke) {
            defaultDeny.showDefaultDenyDialog(changeRequest, R.string.old_sdk_deny_warning,
                    buttonClicked)
                    buttonClicked,
                    setOneTime)
            return
        }

@@ -428,7 +431,8 @@ class AppPermissionViewModel(
        val oldGroup = group

        if (shouldRevokeBackground && group.hasBackgroundGroup && wasBackgroundGranted) {
            newGroup = KotlinUtils.revokeBackgroundRuntimePermissions(app, newGroup, false)
            newGroup = KotlinUtils
                    .revokeBackgroundRuntimePermissions(app, newGroup, false, setOneTime)

            // only log if we have actually denied permissions, not if we switch from
            // "ask every time" to denied
@@ -474,9 +478,10 @@ class AppPermissionViewModel(
     * @param changeRequest whether to change foreground, background, or both.
     * @param buttonPressed button pressed to initiate the change, one of
     *                      AppPermissionFragmentActionReported.button_pressed constants
     * @param oneTime whether the change should show that the permission was selected as one-time
     *
     */
    fun onDenyAnyWay(changeRequest: ChangeRequest, buttonPressed: Int) {
    fun onDenyAnyWay(changeRequest: ChangeRequest, buttonPressed: Int, oneTime: Boolean) {
        val group = lightAppPermGroup ?: return
        val wasForegroundGranted = group.foreground.isGranted
        val wasBackgroundGranted = group.background.isGranted
@@ -487,7 +492,7 @@ class AppPermissionViewModel(

        if (changeRequest andValue ChangeRequest.REVOKE_BACKGROUND != 0 &&
            group.hasBackgroundGroup) {
            newGroup = KotlinUtils.revokeBackgroundRuntimePermissions(app, newGroup, false)
            newGroup = KotlinUtils.revokeBackgroundRuntimePermissions(app, newGroup, false, oneTime)

            if (wasBackgroundGranted) {
                SafetyNetLogger.logPermissionToggled(newGroup)
@@ -497,7 +502,7 @@ class AppPermissionViewModel(
        }

        if (changeRequest andValue ChangeRequest.REVOKE_FOREGROUND != 0) {
            newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, newGroup, false)
            newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, newGroup, false, oneTime)
            if (wasForegroundGranted) {
                SafetyNetLogger.logPermissionToggled(newGroup)
            }
+5 −28
Original line number Diff line number Diff line
@@ -478,30 +478,6 @@ object KotlinUtils {
        return LightPermission(perm.permInfo, newState, perm.foregroundPerms) to shouldKill
    }

    /**
     * Revoke all foreground runtime permissions of a LightAppPermGroup
     *
     * <p>This also disallows all app ops for permissions that have app ops.
     *
     * @param app The current application
     * @param group The group whose permissions should be revoked
     * @param userFixed If the user requested that they do not want to be asked again
     * @param filterPermissions If not specified, all permissions of the group will be revoked.
     *                          Otherwise only permissions in {@code filterPermissions} will be
     *                          revoked.
     *
     * @return a LightAppPermGroup representing the new state
     */
    @JvmOverloads
    fun revokeForegroundRuntimePermissions(
        app: Application,
        group: LightAppPermGroup,
        userFixed: Boolean,
        filterPermissions: List<String> = group.permissions.keys.toList()
    ): LightAppPermGroup {
        return revokeForegroundRuntimePermissions(app, group, userFixed, false, filterPermissions)
    }

    /**
     * Revoke all foreground runtime permissions of a LightAppPermGroup
     *
@@ -521,8 +497,8 @@ object KotlinUtils {
    fun revokeForegroundRuntimePermissions(
        app: Application,
        group: LightAppPermGroup,
        userFixed: Boolean,
        oneTime: Boolean,
        userFixed: Boolean = false,
        oneTime: Boolean = false,
        filterPermissions: List<String> = group.permissions.keys.toList()
    ): LightAppPermGroup {
        return revokeRuntimePermissions(app, group, false, userFixed, oneTime, filterPermissions)
@@ -546,10 +522,11 @@ object KotlinUtils {
    fun revokeBackgroundRuntimePermissions(
        app: Application,
        group: LightAppPermGroup,
        userFixed: Boolean,
        userFixed: Boolean = false,
        oneTime: Boolean = false,
        filterPermissions: List<String> = group.permissions.keys.toList()
    ): LightAppPermGroup {
        return revokeRuntimePermissions(app, group, true, userFixed, false, filterPermissions)
        return revokeRuntimePermissions(app, group, true, userFixed, oneTime, filterPermissions)
    }

    private fun revokeRuntimePermissions(
+12 −13
Original line number Diff line number Diff line
@@ -62,7 +62,6 @@ import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify

/**
@@ -695,7 +694,7 @@ class GrantRevokeTests {
        val group = createMockGroup(perms)
        resetMockAppState()

        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, false)
        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group)

        val newFlags = FLAG_PERMISSION_USER_SET
        verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true,
@@ -718,7 +717,7 @@ class GrantRevokeTests {
        val group = createMockGroup(perms)
        resetMockAppState()

        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, false)
        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group)

        val newFlags = FLAG_PERMISSION_USER_SET
        verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true,
@@ -744,7 +743,7 @@ class GrantRevokeTests {
        perms[FG_PERM_NAME_NO_APP_OP] = createMockPerm(FG_PERM_NAME_NO_APP_OP, true)
        val group = createMockGroup(perms)
        resetMockAppState()
        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, false)
        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group)

        val newFlags = FLAG_PERMISSION_USER_SET
        verifyPermissionState(permName = FG_PERM_NAME_NO_APP_OP, expectPermChange = true,
@@ -770,7 +769,7 @@ class GrantRevokeTests {
        val group = createMockGroup(perms)
        resetMockAppState()

        val newGroup = KotlinUtils.revokeBackgroundRuntimePermissions(app, group, false)
        val newGroup = KotlinUtils.revokeBackgroundRuntimePermissions(app, group)

        val newFlags = FLAG_PERMISSION_USER_SET
        verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false)
@@ -835,7 +834,7 @@ class GrantRevokeTests {
        val group = createMockGroup(perms)
        resetMockAppState()

        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, false)
        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group)

        val newFlags = FLAG_PERMISSION_USER_SET
        verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true,
@@ -864,7 +863,7 @@ class GrantRevokeTests {
        val group = createMockGroup(perms)
        resetMockAppState()

        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, false)
        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group)

        val newFlags = FLAG_PERMISSION_USER_SET
        verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true,
@@ -877,7 +876,7 @@ class GrantRevokeTests {
        assertGroupPermState(newGroup, expectedState)

        resetMockAppState()
        val newGroup2 = KotlinUtils.revokeBackgroundRuntimePermissions(app, newGroup, false)
        val newGroup2 = KotlinUtils.revokeBackgroundRuntimePermissions(app, newGroup)

        verifyPermissionState(permName = BG_PERM_NAME, expectPermChange = false)
        verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false)
@@ -900,7 +899,7 @@ class GrantRevokeTests {
        val group = createMockGroup(perms)
        resetMockAppState()

        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, false)
        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group)

        val newFlags = FLAG_PERMISSION_USER_SET
        verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true,
@@ -923,7 +922,7 @@ class GrantRevokeTests {
        val group = createMockGroup(perms, isPreMApp = true)
        resetMockAppState()

        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, false)
        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group)

        val newFlags = FLAG_PERMISSION_USER_SET or FLAG_PERMISSION_REVOKED_COMPAT
        verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false,
@@ -947,7 +946,7 @@ class GrantRevokeTests {
        val group = createMockGroup(perms)
        resetMockAppState()

        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, false)
        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group)

        verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false)
        verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false)
@@ -993,7 +992,7 @@ class GrantRevokeTests {
        val group = createMockGroup(perms)
        resetMockAppState()

        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, false)
        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group)

        val newFlags = FLAG_PERMISSION_USER_SET
        verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true,
@@ -1041,7 +1040,7 @@ class GrantRevokeTests {
        val group = createMockGroup(perms)
        resetMockAppState()

        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, false)
        val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group)

        val newFlags = FLAG_PERMISSION_USER_SET
        verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false,