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

Commit 059a58f5 authored by Manjeet Rulhania's avatar Manjeet Rulhania
Browse files

move permissions state upgrade to system server

Permissions upgrade runs based on file version, so this
cla also include changes for version unification. The
unified version would be used for both permissions and
app-ops upgrade.

Bug: 266164369
Test: manual
Change-Id: Ib85219b008268c2702d43450bb74c5d6795188e2
parent 9cd7ed6a
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1088,6 +1088,11 @@ public abstract class PackageManagerInternal {
     */
    public abstract RuntimePermissionsState getLegacyPermissionsState(@UserIdInt int userId);

    /**
     * @return permissions file version for the given user.
     */
    public abstract int getLegacyPermissionsVersion(@UserIdInt int userId);

    /**
     * Returns {@code true} if the caller is the installer of record for the given package.
     * Otherwise, {@code false}.
+7 −0
Original line number Diff line number Diff line
@@ -6778,6 +6778,13 @@ public class PackageManagerService implements PackageSender, TestUtilityService
            }
        }

        @Override
        public int getLegacyPermissionsVersion(@UserIdInt int userId) {
            synchronized (mLock) {
                return mSettings.getDefaultRuntimePermissionsVersion(userId);
            }
        }

        @Override
        @SuppressWarnings("GuardedBy")
        public boolean isPermissionUpgradeNeeded(int userId) {
+5 −0
Original line number Diff line number Diff line
@@ -45,6 +45,11 @@ public interface PermissionMigrationHelper {
    @NonNull
    Map<Integer, Map<String, LegacyPermissionState>> getLegacyPermissionStates(int userId);

    /**
     * @return permissions file version for the given user.
     */
    int getLegacyPermissionsVersion(int userId);

    /**
     * Legacy permission definition.
     */
+7 −0
Original line number Diff line number Diff line
@@ -115,6 +115,13 @@ public class PermissionMigrationHelperImpl implements PermissionMigrationHelper
        return appIdPermissionStates;
    }

    @Override
    public int getLegacyPermissionsVersion(int userId) {
        PackageManagerInternal packageManagerInternal =
                LocalServices.getService(PackageManagerInternal.class);
        return packageManagerInternal.getLegacyPermissionsVersion(userId);
    }

    @NonNull
    private Map<String, LegacyPermissionState> toLegacyPermissionStates(
            List<RuntimePermissionsState.PermissionState> permissions) {
+117 −4
Original line number Diff line number Diff line
@@ -20,11 +20,15 @@ import android.util.Log
import com.android.modules.utils.BinaryXmlPullParser
import com.android.modules.utils.BinaryXmlSerializer
import com.android.server.SystemConfig
import com.android.server.permission.access.appop.PackageAppOpPolicy
import com.android.server.permission.access.appop.AppIdAppOpPolicy
import com.android.server.permission.access.appop.PackageAppOpPolicy
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
import com.android.server.permission.access.permission.AppIdPermissionPolicy
import com.android.server.permission.access.util.attributeInt
import com.android.server.permission.access.util.attributeInterned
import com.android.server.permission.access.util.forEachTag
import com.android.server.permission.access.util.getAttributeIntOrThrow
import com.android.server.permission.access.util.getAttributeValueOrThrow
import com.android.server.permission.access.util.tag
import com.android.server.permission.access.util.tagName
import com.android.server.pm.permission.PermissionAllowlist
@@ -107,6 +111,9 @@ class AccessPolicy private constructor(
        forEachSchemePolicy {
            with(it) { onUserAdded(userId) }
        }
        newState.systemState.packageStates.forEach { (_, packageState) ->
            upgradePackageVersion(packageState, userId)
        }
    }

    fun MutateStateScope.onUserRemoved(userId: Int) {
@@ -147,6 +154,13 @@ class AccessPolicy private constructor(
        forEachSchemePolicy {
            with(it) { onStorageVolumeMounted(volumeUuid, isSystemUpdated) }
        }
        packageStates.forEach { (_, packageState) ->
            if (packageState.volumeUuid == volumeUuid) {
                newState.systemState.userIds.forEachIndexed { _, userId ->
                    upgradePackageVersion(packageState, userId)
                }
            }
        }
    }

    fun MutateStateScope.onPackageAdded(
@@ -179,6 +193,9 @@ class AccessPolicy private constructor(
        forEachSchemePolicy {
            with(it) { onPackageAdded(packageState) }
        }
        newState.systemState.userIds.forEachIndexed { _, userId ->
            upgradePackageVersion(packageState, userId)
        }
    }

    fun MutateStateScope.onPackageRemoved(
@@ -213,6 +230,10 @@ class AccessPolicy private constructor(
                with(it) { onAppIdRemoved(appId) }
            }
        }
        newState.userStates.forEachIndexed { _, _, userState ->
            userState.packageVersions -= packageName
            userState.requestWrite()
        }
    }

    fun MutateStateScope.onPackageInstalled(
@@ -274,6 +295,38 @@ class AccessPolicy private constructor(
        }
    }

    private fun MutateStateScope.upgradePackageVersion(packageState: PackageState, userId: Int) {
        if (packageState.androidPackage == null) {
            return
        }

        val packageName = packageState.packageName
        // The version would be latest when the package is new to the system, e.g. newly
        // installed, first boot, or system apps added via OTA.
        val version = newState.userStates[userId].packageVersions[packageName]
        when {
            version == null -> {
                newState.userStates[userId].apply {
                    packageVersions[packageName] = VERSION_LATEST
                    requestWrite()
                }
            }
            version < VERSION_LATEST -> {
                forEachSchemePolicy {
                    with(it) { upgradePackageState(packageState, userId, version) }
                }
                newState.userStates[userId].apply {
                    packageVersions[packageName] = VERSION_LATEST
                    requestWrite()
                }
            }
            version == VERSION_LATEST -> {}
            else -> Log.w(
                LOG_TAG, "Unexpected version $version for package $packageName," +
                    "latest version is $VERSION_LATEST"
            )
        }
    }

    fun BinaryXmlPullParser.parseSystemState(state: AccessState) {
        forEachTag {
@@ -303,11 +356,16 @@ class AccessPolicy private constructor(
            when (tagName) {
                TAG_ACCESS -> {
                    forEachTag {
                        when (tagName) {
                            TAG_PACKAGE_VERSIONS -> parsePackageVersions(state, userId)
                            else -> {
                                forEachSchemePolicy {
                                    with(it) { parseUserState(state, userId) }
                                }
                            }
                        }
                    }
                }
                else -> {
                    Log.w(
                        LOG_TAG,
@@ -318,11 +376,53 @@ class AccessPolicy private constructor(
        }
    }

    private fun BinaryXmlPullParser.parsePackageVersions(state: AccessState, userId: Int) {
        val userState = state.userStates[userId]
        forEachTag {
            when (tagName) {
                TAG_PACKAGE -> parsePackageVersion(userState)
                else -> Log.w(
                    LOG_TAG,
                    "Ignoring unknown tag $name when parsing package versions for user $userId"
                )
            }
        }
        userState.packageVersions.retainAllIndexed { _, packageName, _ ->
            val hasPackage = packageName in state.systemState.packageStates
            if (!hasPackage) {
                Log.w(
                    LOG_TAG,
                    "Dropping unknown $packageName when parsing package versions for user $userId"
                )
            }
            hasPackage
        }
    }

    private fun BinaryXmlPullParser.parsePackageVersion(userState: UserState) {
        val packageName = getAttributeValueOrThrow(ATTR_NAME).intern()
        val version = getAttributeIntOrThrow(ATTR_VERSION)
        userState.packageVersions[packageName] = version
    }

    fun BinaryXmlSerializer.serializeUserState(state: AccessState, userId: Int) {
        tag(TAG_ACCESS) {
            forEachSchemePolicy {
                with(it) { serializeUserState(state, userId) }
            }

            serializeVersions(state.userStates[userId])
        }
    }

    private fun BinaryXmlSerializer.serializeVersions(userState: UserState) {
        tag(TAG_PACKAGE_VERSIONS) {
            userState.packageVersions.forEachIndexed { _, packageName, version ->
                tag(TAG_PACKAGE) {
                    attributeInterned(ATTR_NAME, packageName)
                    attributeInt(ATTR_VERSION, version)
                }
            }
        }
    }

@@ -340,7 +440,14 @@ class AccessPolicy private constructor(
    companion object {
        private val LOG_TAG = AccessPolicy::class.java.simpleName

        internal const val VERSION_LATEST = 14

        private const val TAG_ACCESS = "access"
        private const val TAG_PACKAGE_VERSIONS = "package-versions"
        private const val TAG_PACKAGE = "package"

        private const val ATTR_NAME = "name"
        private const val ATTR_VERSION = "version"
    }
}

@@ -388,6 +495,12 @@ abstract class SchemePolicy {

    open fun migrateUserState(state: AccessState, userId: Int) {}

    open fun MutateStateScope.upgradePackageState(
        packageState: PackageState,
        userId: Int,
        version: Int
    ) {}

    open fun BinaryXmlPullParser.parseSystemState(state: AccessState) {}

    open fun BinaryXmlSerializer.serializeSystemState(state: AccessState) {}
Loading