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

Commit 1fb1ca5c authored by Hai Zhang's avatar Hai Zhang
Browse files

Only report permissions that require re-evaluation as changed.

A re-evaluation is only needed when the permission's owning package
changed, or protection level (protection + protection flags) changed,
or a runtime permission is moved to a new group. This helps us
significantly reduce the re-evaluations needed during boot.

Also fixed the issue that config permissions aren't turned into
manifest permissions when they matched. This is important because we
don't persist config permissions, but we do want to persist
permissions from APK manifest.

Also renamed isPermissionTypeChanged to isPermissionProtectionChanged
for clarity, and improved logging in one place.

Bug: 284205103
Test: presubmit
Change-Id: I176a60289d94363d665b6b4da33cbb00f989a8bd
parent 4eb9b734
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -74,8 +74,8 @@ class AppIdPermissionPersistence {
            if (packageName !in externalState.packageStates &&
                packageName !in externalState.disabledSystemPackageStates) {
                Slog.w(
                    LOG_TAG,
                    "Dropping permission with unknown package $packageName when parsing permissions"
                    LOG_TAG, "Dropping permission ${permission.name} from unknown package" +
                        " $packageName when parsing permissions"
                )
                permissions.removeAt(permissionIndex)
                systemState.requestWriteMode(WriteMode.ASYNCHRONOUS)
+20 −10
Original line number Diff line number Diff line
@@ -444,7 +444,7 @@ class AppIdPermissionPolicy : SchemePolicy() {
                    // It's a config permission and has no owner, take ownership now.
                    oldPermission.copy(
                        permissionInfo = newPermissionInfo, isReconciled = true,
                        appId = packageState.appId
                        type = Permission.TYPE_MANIFEST, appId = packageState.appId
                    )
                } else if (newState.externalState.packageStates[oldPackageName]?.isSystem != true) {
                    Slog.w(
@@ -478,11 +478,12 @@ class AppIdPermissionPolicy : SchemePolicy() {
                    val isPermissionGroupChanged = newPermissionInfo.isRuntime &&
                        newPermissionInfo.group != null &&
                        newPermissionInfo.group != oldPermission.groupName
                    val isPermissionTypeChanged = oldPermission.type != Permission.TYPE_CONFIG && (
                    val isPermissionProtectionChanged =
                        oldPermission.type != Permission.TYPE_CONFIG && (
                            (newPermissionInfo.isRuntime && !oldPermission.isRuntime) ||
                                (newPermissionInfo.isInternal && !oldPermission.isInternal)
                        )
                    if (isPermissionGroupChanged || isPermissionTypeChanged) {
                    if (isPermissionGroupChanged || isPermissionProtectionChanged) {
                        newState.externalState.userIds.forEachIndexed { _, userId ->
                            newState.externalState.appIdPackageNames.forEachIndexed { _, appId, _ ->
                                if (isPermissionGroupChanged) {
@@ -497,11 +498,11 @@ class AppIdPermissionPolicy : SchemePolicy() {
                                            " to ${newPermissionInfo.group}"
                                    )
                                }
                                if (isPermissionTypeChanged) {
                                if (isPermissionProtectionChanged) {
                                    Slog.w(
                                        LOG_TAG, "Revoking permission $permissionName for" +
                                            " appId $appId and userId $userId as the permission" +
                                            " type changed."
                                            " protection changed."
                                    )
                                }
                                setPermissionFlags(appId, userId, permissionName, 0)
@@ -517,7 +518,7 @@ class AppIdPermissionPolicy : SchemePolicy() {
                if (oldPermission != null) {
                    oldPermission.copy(
                        permissionInfo = newPermissionInfo, isReconciled = true,
                        appId = packageState.appId
                        type = Permission.TYPE_MANIFEST, appId = packageState.appId
                    )
                } else {
                    Permission(
@@ -530,10 +531,19 @@ class AppIdPermissionPolicy : SchemePolicy() {
                newState.mutateSystemState().mutatePermissionTrees()[permissionName] = newPermission
            } else {
                newState.mutateSystemState().mutatePermissions()[permissionName] = newPermission
            }
                val isPermissionChanged = oldPermission == null ||
                    newPackageName != oldPermission.packageName ||
                    newPermission.protectionLevel != oldPermission.protectionLevel || (
                        oldPermission.isReconciled && newPermission.isRuntime &&
                            newPermission.groupName != null &&
                            newPermission.groupName != oldPermission.groupName
                    )
                if (isPermissionChanged) {
                    changedPermissionNames += permissionName
                }
            }
        }
    }

    private fun MutateStateScope.trimPermissions(
        packageName: String,