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

Commit cb595e1b authored by Manjeet Rulhania's avatar Manjeet Rulhania Committed by Android (Google) Code Review
Browse files

Merge "move permissions state upgrade to system server"

parents 78672b36 059a58f5
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