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

Commit cdf84d3a authored by Philip P. Moltmann's avatar Philip P. Moltmann
Browse files

Skip grant dialog when permission are granted

While the permission grant dialog is shown a permission might be granted
via other methods. If this is done, the grant dialog should
automatically skip this step. If this is the last step, the dialog should
exit.

Test: Granted verious permissions sets via UI while also granting some of the
      permissions via the shell
Fixes: 69437524

Change-Id: I4a7baa8f8d2bb62f8a6e8fa601039056757261e1
parent 0fd15df7
Loading
Loading
Loading
Loading
+111 −10
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.os.Build;
import android.os.Bundle;
import android.text.Html;
import android.text.Spanned;
import android.util.ArraySet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -72,6 +73,13 @@ public class GrantPermissionsActivity extends OverlayTouchActivity

    boolean mResultSet;

    private PackageManager.OnPermissionsChangedListener mPermissionChangeListener;

    private int getPermissionPolicy() {
        DevicePolicyManager devicePolicyManager = getSystemService(DevicePolicyManager.class);
        return devicePolicyManager.getPermissionPolicy(null);
    }

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
@@ -112,6 +120,13 @@ public class GrantPermissionsActivity extends OverlayTouchActivity
            return;
        }

        try {
            mPermissionChangeListener = new PermissionChangeListener();
        } catch (NameNotFoundException e) {
            setResultAndFinish();
            return;
        }

        PackageInfo callingPackageInfo = getCallingPackageInfo();

        if (callingPackageInfo == null || callingPackageInfo.requestedPermissions == null
@@ -129,11 +144,7 @@ public class GrantPermissionsActivity extends OverlayTouchActivity
            return;
        }

        DevicePolicyManager devicePolicyManager = getSystemService(DevicePolicyManager.class);
        final int permissionPolicy = devicePolicyManager.getPermissionPolicy(null);

        // If calling package is null we default to deny all.
        updateDefaultResults(callingPackageInfo, permissionPolicy);
        updateAlreadyGrantedPermissions(getCallingPackageInfo(), getPermissionPolicy());

        mAppPermissions = new AppPermissions(this, callingPackageInfo, null, false,
                new Runnable() {
@@ -161,7 +172,7 @@ public class GrantPermissionsActivity extends OverlayTouchActivity
            // We allow the user to choose only non-fixed permissions. A permission
            // is fixed either by device policy or the user denying with prejudice.
            if (!group.isUserFixed() && !group.isPolicyFixed()) {
                switch (permissionPolicy) {
                switch (getPermissionPolicy()) {
                    case DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT: {
                        if (!group.areRuntimePermissionsGranted()) {
                            group.grantRuntimePermissions(false, computeAffectedPermissions(
@@ -227,6 +238,78 @@ public class GrantPermissionsActivity extends OverlayTouchActivity
        }
    }


    /**
     * Update the {@link #mRequestedPermissions} if the system reports them as granted.
     *
     * <p>This also updates the {@link #mAppPermissions} state and switches to the next group grant
     * request if the current group becomes granted.
     */
    private void updateIfPermissionsWereGranted() {
        updateAlreadyGrantedPermissions(getCallingPackageInfo(), getPermissionPolicy());

        ArraySet<String> grantedPermissionNames = new ArraySet<>(mRequestedPermissions.length);
        for (int i = 0; i < mRequestedPermissions.length; i++) {
            if (mGrantResults[i] == PERMISSION_GRANTED) {
                grantedPermissionNames.add(mRequestedPermissions[i]);
            }
        }

        boolean mightShowNextGroup = true;
        int numGroups = mAppPermissions.getPermissionGroups().size();
        for (int groupNum = 0; groupNum < numGroups; groupNum++) {
            AppPermissionGroup group = mAppPermissions.getPermissionGroups().get(groupNum);
            GroupState groupState = mRequestGrantPermissionGroups.get(group.getName());

            if (groupState == null || groupState.mState != GroupState.STATE_UNKNOWN) {
                // Group has already been approved / denied via the UI by the user
                continue;
            }

            boolean allAffectedPermissionsOfThisGroupAreGranted = true;

            for (int permNum = 0; permNum < groupState.affectedPermissions.length;
                    permNum++) {
                if (!grantedPermissionNames.contains(
                        groupState.affectedPermissions[permNum])) {
                    allAffectedPermissionsOfThisGroupAreGranted = false;
                    break;
                }
            }

            if (allAffectedPermissionsOfThisGroupAreGranted) {
                groupState.mState = GroupState.STATE_ALLOWED;

                if (mightShowNextGroup) {
                    // The UI currently displays the first group with
                    // mState == STATE_UNKNOWN. So we are switching to next group until we
                    // could not allow a group that was still unknown
                    if (!showNextPermissionGroupGrantRequest()) {
                        setResultAndFinish();
                    }
                }
            } else {
                mightShowNextGroup = false;
            }
        }
    }

    @Override
    protected void onStart() {
        super.onStart();

        getPackageManager().addOnPermissionsChangeListener(mPermissionChangeListener);

        updateIfPermissionsWereGranted();
    }

    @Override
    protected void onStop() {
        super.onStop();

        getPackageManager().removeOnPermissionsChangeListener(mPermissionChangeListener);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
@@ -435,13 +518,16 @@ public class GrantPermissionsActivity extends OverlayTouchActivity
        }
    }

    private void updateDefaultResults(PackageInfo callingPackageInfo, int permissionPolicy) {
    private void updateAlreadyGrantedPermissions(PackageInfo callingPackageInfo,
            int permissionPolicy) {
        final int requestedPermCount = mRequestedPermissions.length;
        for (int i = 0; i < requestedPermCount; i++) {
            String permission = mRequestedPermissions[i];
            mGrantResults[i] = callingPackageInfo != null
                    ? computePermissionGrantState(callingPackageInfo, permission, permissionPolicy)
                    : PERMISSION_DENIED;

            if (computePermissionGrantState(callingPackageInfo, permission, permissionPolicy)
                    == PERMISSION_GRANTED) {
                mGrantResults[i] = PERMISSION_GRANTED;
            }
        }
    }

@@ -513,4 +599,19 @@ public class GrantPermissionsActivity extends OverlayTouchActivity
            mGroup = group;
        }
    }

    private class PermissionChangeListener implements PackageManager.OnPermissionsChangedListener {
        final int mCallingPackageUid;

        PermissionChangeListener() throws NameNotFoundException {
            mCallingPackageUid = getPackageManager().getPackageUid(getCallingPackage(), 0);
        }

        @Override
        public void onPermissionsChanged(int uid) {
            if (uid == mCallingPackageUid) {
                updateIfPermissionsWereGranted();
            }
        }
    }
}