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

Commit e641140e authored by Zimuzo's avatar Zimuzo
Browse files

Retain Activity Recognition permission state across device update

Bug: 131867032
Test: Manual testing with apks that request new Android and old gmscore
permission targetting P and Q. After system upgrade from P to Q,
both apps always get Android AR permission auto-granted. Meanwhile, new
installs of the same apps on Q don't get the Android AR permission
auto-granted.

Change-Id: I68493a42650407056ef6b9fa40e24aea94a72f88
parent 3415499a
Loading
Loading
Loading
Loading
+48 −10
Original line number Diff line number Diff line
@@ -930,6 +930,7 @@ public class PermissionManagerService {
                final BasePermission bp = mSettings.getPermissionLocked(permName);
                final boolean appSupportsRuntimePermissions =
                        pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
                String upgradedActivityRecognitionPermission = null;

                if (DEBUG_INSTALL) {
                    Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
@@ -948,12 +949,41 @@ public class PermissionManagerService {
                // Cache newImplicitPermissions before modifing permissionsState as for the shared
                // uids the original and new state are the same object
                if (!origPermissions.hasRequestedPermission(permName)
                        && pkg.implicitPermissions.contains(permName)) {
                        && (pkg.implicitPermissions.contains(permName)
                                || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) {
                    if (pkg.implicitPermissions.contains(permName)) {
                        // If permName is an implicit permission, try to auto-grant
                        newImplicitPermissions.add(permName);

                        if (DEBUG_PERMISSIONS) {
                            Slog.i(TAG, permName + " is newly added for " + pkg.packageName);
                        }
                    } else {
                        // Special case for Activity Recognition permission. Even if AR permission
                        // is not an implicit permission we want to add it to the list (try to
                        // auto-grant it) if the app was installed on a device before AR permission
                        // was split, regardless of if the app now requests the new AR permission
                        // or has updated its target SDK and AR is no longer implicit to it.
                        // This is a compatibility workaround for apps when AR permission was
                        // split in Q.
                        int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
                        for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
                            PermissionManager.SplitPermissionInfo sp =
                                    PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
                            String splitPermName = sp.getSplitPermission();
                            if (sp.getNewPermissions().contains(permName)
                                    && origPermissions.hasInstallPermission(splitPermName)) {
                                upgradedActivityRecognitionPermission = splitPermName;
                                newImplicitPermissions.add(permName);

                                if (DEBUG_PERMISSIONS) {
                                    Slog.i(TAG, permName + " is newly added for "
                                            + pkg.packageName);
                                }
                                break;
                            }
                        }
                    }
                }

                // Limit ephemeral apps to ephemeral allowed permissions.
@@ -986,7 +1016,8 @@ public class PermissionManagerService {
                    // For all apps normal permissions are install time ones.
                    grant = GRANT_INSTALL;
                } else if (bp.isRuntime()) {
                    if (origPermissions.hasInstallPermission(bp.getName())) {
                    if (origPermissions.hasInstallPermission(bp.getName())
                            || upgradedActivityRecognitionPermission != null) {
                        // Before Q we represented some runtime permissions as install permissions,
                        // in Q we cannot do this anymore. Hence upgrade them all.
                        grant = GRANT_UPGRADE;
@@ -1162,10 +1193,15 @@ public class PermissionManagerService {
                                    .getInstallPermissionState(perm);
                            int flags = (permState != null) ? permState.getFlags() : 0;

                            BasePermission bpToRevoke =
                                    upgradedActivityRecognitionPermission == null
                                    ? bp : mSettings.getPermissionLocked(
                                            upgradedActivityRecognitionPermission);
                            // Remove install permission
                            if (origPermissions.revokeInstallPermission(bp)
                            if (origPermissions.revokeInstallPermission(bpToRevoke)
                                    != PERMISSION_OPERATION_FAILURE) {
                                origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
                                origPermissions.updatePermissionFlags(bpToRevoke,
                                        UserHandle.USER_ALL,
                                        (MASK_PERMISSION_FLAGS_ALL
                                                & ~FLAG_PERMISSION_APPLY_RESTRICTION), 0);
                                changedInstallPermission = true;
@@ -1490,9 +1526,11 @@ public class PermissionManagerService {
                    for (int userNum = 0; userNum < numUsers; userNum++) {
                        int userId = users[userNum];

                        if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) {
                            ps.updatePermissionFlags(bp, userId,
                                    FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
                                    FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
                        }
                        updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);

                        boolean inheritsFromInstallPerm = false;