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

Commit c5deccb2 authored by Hai Zhang's avatar Hai Zhang Committed by Android (Google) Code Review
Browse files

Merge changes I3aa177e5,I2d678ef2,I9c4ec4b7

* changes:
  Various refactors to UidPermissionPolicy code.
  Start AccessCheckingService in SystemServer.
  Make AccessCheckingService a SystemService.
parents 91f05736 c6abc002
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -154,6 +154,7 @@ import com.android.server.os.DeviceIdentifiersPolicyService;
import com.android.server.os.NativeTombstoneManagerService;
import com.android.server.os.SchedulingPolicyService;
import com.android.server.people.PeopleService;
import com.android.server.permission.access.AccessCheckingService;
import com.android.server.pm.ApexManager;
import com.android.server.pm.ApexSystemServiceInfo;
import com.android.server.pm.BackgroundInstallControlService;
@@ -1110,6 +1111,11 @@ public final class SystemServer implements Dumpable {
        startMemtrackProxyService();
        t.traceEnd();

        // Start AccessCheckingService which provides new implementation for permission and app op.
        t.traceBegin("StartAccessCheckingService");
        mSystemServiceManager.startService(AccessCheckingService.class);
        t.traceEnd();

        // Activity manager runs the show.
        t.traceBegin("StartActivityManager");
        // TODO: Might need to move after migration to WM.
+76 −13
Original line number Diff line number Diff line
@@ -16,11 +16,23 @@

package com.android.server.permission.access

import android.content.Context
import com.android.internal.annotations.Keep
import com.android.server.permission.access.external.PackageState
import com.android.server.LocalManagerRegistry
import com.android.server.LocalServices
import com.android.server.SystemService
import com.android.server.appop.AppOpsCheckingServiceInterface
import com.android.server.permission.access.appop.AppOpService
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
import com.android.server.permission.access.permission.PermissionService
import com.android.server.pm.PackageManagerLocal
import com.android.server.pm.UserManagerService
import com.android.server.pm.permission.PermissionManagerServiceInterface
import com.android.server.pm.permission.PermissionManagerServiceInternal
import com.android.server.pm.pkg.PackageState

@Keep
class AccessCheckingService {
class AccessCheckingService(context: Context) : SystemService(context) {
    @Volatile
    private lateinit var state: AccessState
    private val stateLock = Any()
@@ -29,14 +41,35 @@ class AccessCheckingService {

    private val persistence = AccessPersistence(policy)

    fun init() {
        val state = AccessState()
        state.systemState.userIds.apply {
            // TODO: Get and add all user IDs.
            // TODO: Maybe get and add all packages?
    private lateinit var appOpService: AppOpService
    private lateinit var permissionService: PermissionService

    private lateinit var packageManagerLocal: PackageManagerLocal
    private lateinit var userManagerService: UserManagerService

    override fun onStart() {
        appOpService = AppOpService(this)
        permissionService = PermissionService(this)

        LocalServices.addService(AppOpsCheckingServiceInterface::class.java, appOpService)
        LocalServices.addService(PermissionManagerServiceInterface::class.java, permissionService)
    }

    fun initialize() {
        packageManagerLocal =
            LocalManagerRegistry.getManagerOrThrow(PackageManagerLocal::class.java)
        userManagerService = UserManagerService.getInstance()

        val userIds = IntSet(userManagerService.userIdsIncludingPreCreated)
        val packageStates = packageManagerLocal.packageStates

        val state = AccessState()
        policy.initialize(state, userIds, packageStates)
        persistence.read(state)
        this.state = state

        appOpService.initialize()
        permissionService.initialize()
    }

    fun getDecision(subject: AccessUri, `object`: AccessUri): Int =
@@ -50,30 +83,60 @@ class AccessCheckingService {
        }
    }

    fun onUserAdded(userId: Int) {
    internal fun onUserAdded(userId: Int) {
        mutateState {
            with(policy) { onUserAdded(userId) }
        }
    }

    fun onUserRemoved(userId: Int) {
    internal fun onUserRemoved(userId: Int) {
        mutateState {
            with(policy) { onUserRemoved(userId) }
        }
    }

    fun onPackageAdded(packageState: PackageState) {
    internal fun onStorageVolumeMounted(volumeUuid: String?, isSystemUpdated: Boolean) {
        val packageStates = packageManagerLocal.packageStates
        mutateState {
            with(policy) { onStorageVolumeMounted(packageStates, volumeUuid, isSystemUpdated) }
        }
    }

    internal fun onPackageAdded(packageName: String) {
        val packageStates = packageManagerLocal.packageStates
        mutateState {
            with(policy) { onPackageAdded(packageStates, packageName) }
        }
    }

    internal fun onPackageRemoved(packageName: String, appId: Int) {
        val packageStates = packageManagerLocal.packageStates
        mutateState {
            with(policy) { onPackageAdded(packageState) }
            with(policy) { onPackageRemoved(packageStates, packageName, appId) }
        }
    }

    fun onPackageRemoved(packageState: PackageState) {
    internal fun onPackageInstalled(
        packageName: String,
        params: PermissionManagerServiceInternal.PackageInstalledParams,
        userId: Int
    ) {
        val packageStates = packageManagerLocal.packageStates
        mutateState {
            with(policy) { onPackageRemoved(packageState) }
            with(policy) { onPackageInstalled(packageStates, packageName, params, userId) }
        }
    }

    internal fun onPackageUninstalled(packageName: String, appId: Int, userId: Int) {
        val packageStates = packageManagerLocal.packageStates
        mutateState {
            with(policy) { onPackageUninstalled(packageStates, packageName, appId, userId) }
        }
    }

    private val PackageManagerLocal.packageStates: Map<String, PackageState>
        get() = withUnfilteredSnapshot().use { it.packageStates }

    internal inline fun <T> getState(action: GetStateScope.() -> T): T =
        GetStateScope(state).action()

+95 −23
Original line number Diff line number Diff line
@@ -22,11 +22,12 @@ import com.android.modules.utils.BinaryXmlSerializer
import com.android.server.permission.access.appop.PackageAppOpPolicy
import com.android.server.permission.access.appop.UidAppOpPolicy
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
import com.android.server.permission.access.external.PackageState
import com.android.server.permission.access.permission.UidPermissionPolicy
import com.android.server.permission.access.util.forEachTag
import com.android.server.permission.access.util.tag
import com.android.server.permission.access.util.tagName
import com.android.server.pm.permission.PermissionManagerServiceInternal
import com.android.server.pm.pkg.PackageState

class AccessPolicy private constructor(
    private val schemePolicies: IndexedMap<String, IndexedMap<String, SchemePolicy>>
@@ -53,6 +54,17 @@ class AccessPolicy private constructor(
        with(getSchemePolicy(subject, `object`)) { setDecision(subject, `object`, decision) }
    }

    fun initialize(state: AccessState, userIds: IntSet, packageStates: Map<String, PackageState>) {
        state.systemState.apply {
            this.userIds += userIds
            this.packageStates = packageStates
            packageStates.forEach { (_, packageState) ->
                appIds.getOrPut(packageState.appId) { IndexedListSet() }
                    .add(packageState.packageName)
            }
        }
    }

    fun MutateStateScope.onUserAdded(userId: Int) {
        newState.systemState.userIds += userId
        newState.userStates[userId] = UserState()
@@ -69,18 +81,34 @@ class AccessPolicy private constructor(
        }
    }

    fun MutateStateScope.onPackageAdded(packageState: PackageState) {
    fun MutateStateScope.onStorageVolumeMounted(
        packageStates: Map<String, PackageState>,
        volumeUuid: String?,
        isSystemUpdated: Boolean
    ) {
        newState.systemState.packageStates = packageStates
        forEachSchemePolicy {
            with(it) { onStorageVolumeMounted(volumeUuid, isSystemUpdated) }
        }
    }

    fun MutateStateScope.onPackageAdded(
        packageStates: Map<String, PackageState>,
        packageName: String
    ) {
        newState.systemState.packageStates = packageStates
        var isAppIdAdded = false
        newState.systemState.apply {
            packageStates[packageState.packageName] = packageState
            appIds.getOrPut(packageState.appId) {
        val packageState = packageStates[packageName]
        // TODO(zhanghai): Remove check before submission.
        checkNotNull(packageState)
        val appId = packageState.appId
        newState.systemState.appIds.getOrPut(appId) {
            isAppIdAdded = true
            IndexedListSet()
            }.add(packageState.packageName)
        }
        }.add(packageName)
        if (isAppIdAdded) {
            forEachSchemePolicy {
                with(it) { onAppIdAdded(packageState.appId) }
                with(it) { onAppIdAdded(appId) }
            }
        }
        forEachSchemePolicy {
@@ -88,30 +116,61 @@ class AccessPolicy private constructor(
        }
    }

    fun MutateStateScope.onPackageRemoved(packageState: PackageState) {
    fun MutateStateScope.onPackageRemoved(
        packageStates: Map<String, PackageState>,
        packageName: String,
        appId: Int
    ) {
        newState.systemState.packageStates = packageStates
        var isAppIdRemoved = false
        newState.systemState.apply {
            packageStates -= packageState.packageName
            appIds.apply appIds@{
                this[packageState.appId]?.apply {
                    this -= packageState.packageName
        // TODO(zhanghai): Remove check before submission.
        check(packageName !in packageStates)
        newState.systemState.appIds.apply appIds@{
            this[appId]?.apply {
                this -= packageName
                if (isEmpty()) {
                        this@appIds -= packageState.appId
                    this@appIds -= appId
                    isAppIdRemoved = true
                }
            }
        }
        }
        forEachSchemePolicy {
            with(it) { onPackageRemoved(packageState) }
            with(it) { onPackageRemoved(packageName, appId) }
        }
        if (isAppIdRemoved) {
            forEachSchemePolicy {
                with(it) { onAppIdRemoved(packageState.appId) }
                with(it) { onAppIdRemoved(appId) }
            }
        }
    }

    fun MutateStateScope.onPackageInstalled(
        packageStates: Map<String, PackageState>,
        packageName: String,
        params: PermissionManagerServiceInternal.PackageInstalledParams,
        userId: Int
    ) {
        newState.systemState.packageStates = packageStates
        val packageState = packageStates[packageName]
        // TODO(zhanghai): Remove check before submission.
        checkNotNull(packageState)
        forEachSchemePolicy {
            with(it) { onPackageInstalled(packageState, params, userId) }
        }
    }

    fun MutateStateScope.onPackageUninstalled(
        packageStates: Map<String, PackageState>,
        packageName: String,
        appId: Int,
        userId: Int
    ) {
        newState.systemState.packageStates = packageStates
        forEachSchemePolicy {
            with(it) { onPackageUninstalled(packageName, appId, userId) }
        }
    }

    fun BinaryXmlPullParser.parseSystemState(systemState: SystemState) {
        forEachTag {
            when (tagName) {
@@ -230,9 +289,22 @@ abstract class SchemePolicy {

    open fun MutateStateScope.onAppIdRemoved(appId: Int) {}

    open fun MutateStateScope.onStorageVolumeMounted(
        volumeUuid: String?,
        isSystemUpdated: Boolean
    ) {}

    open fun MutateStateScope.onPackageAdded(packageState: PackageState) {}

    open fun MutateStateScope.onPackageRemoved(packageState: PackageState) {}
    open fun MutateStateScope.onPackageRemoved(packageName: String, appId: Int) {}

    open fun MutateStateScope.onPackageInstalled(
        packageState: PackageState,
        params: PermissionManagerServiceInternal.PackageInstalledParams,
        userId: Int
    ) {}

    open fun MutateStateScope.onPackageUninstalled(packageName: String, appId: Int, userId: Int) {}

    open fun BinaryXmlPullParser.parseSystemState(systemState: SystemState) {}

+13 −10
Original line number Diff line number Diff line
@@ -18,8 +18,8 @@ package com.android.server.permission.access

import android.content.pm.PermissionGroupInfo
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
import com.android.server.permission.access.data.Permission
import com.android.server.permission.access.external.PackageState
import com.android.server.permission.access.permission.Permission
import com.android.server.pm.pkg.PackageState

class AccessState private constructor(
    val systemState: SystemState,
@@ -32,8 +32,8 @@ class AccessState private constructor(

class SystemState private constructor(
    val userIds: IntSet,
    val packageStates: IndexedMap<String, PackageState>,
    val disabledSystemPackageStates: IndexedMap<String, PackageState>,
    var packageStates: Map<String, PackageState>,
    var disabledSystemPackageStates: Map<String, PackageState>,
    val appIds: IntMap<IndexedListSet<String>>,
    // A map of KnownPackagesInt to a set of known package names
    val knownPackages: IntMap<IndexedListSet<String>>,
@@ -59,7 +59,7 @@ class SystemState private constructor(
    val permissions: IndexedMap<String, Permission>
) : WritableState() {
    constructor() : this(
        IntSet(), IndexedMap(), IndexedMap(), IntMap(), IntMap(), IntMap(), IndexedMap(),
        IntSet(), emptyMap(), emptyMap(), IntMap(), IntMap(), IntMap(), IndexedMap(),
        IndexedListSet(), IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(),
        IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(),
        IndexedMap(), IndexedMap(), IndexedMap()
@@ -68,8 +68,8 @@ class SystemState private constructor(
    fun copy(): SystemState =
        SystemState(
            userIds.copy(),
            packageStates.copy { it },
            disabledSystemPackageStates.copy { it },
            packageStates,
            disabledSystemPackageStates,
            appIds.copy { it.copy() },
            knownPackages.copy { it.copy() },
            deviceAndProfileOwners.copy { it },
@@ -94,14 +94,17 @@ class SystemState private constructor(

class UserState private constructor(
    // A map of (appId to a map of (permissionName to permissionFlags))
    val permissionFlags: IntMap<IndexedMap<String, Int>>,
    val uidPermissionFlags: IntMap<IndexedMap<String, Int>>,
    val uidAppOpModes: IntMap<IndexedMap<String, Int>>,
    val packageAppOpModes: IndexedMap<String, IndexedMap<String, Int>>
) : WritableState() {
    constructor() : this(IntMap(), IntMap(), IndexedMap())

    fun copy(): UserState = UserState(permissionFlags.copy { it.copy { it } },
        uidAppOpModes.copy { it.copy { it } }, packageAppOpModes.copy { it.copy { it } })
    fun copy(): UserState = UserState(
        uidPermissionFlags.copy { it.copy { it } },
        uidAppOpModes.copy { it.copy { it } },
        packageAppOpModes.copy { it.copy { it } }
    )
}

object WriteMode {
+2 −3
Original line number Diff line number Diff line
@@ -16,8 +16,7 @@

package com.android.server.permission.access

import com.android.server.permission.access.external.UserHandle
import com.android.server.permission.access.external.UserHandleCompat
import android.os.UserHandle

sealed class AccessUri(
    val scheme: String
@@ -70,7 +69,7 @@ data class UidUri(
    val uid: Int
) : AccessUri(SCHEME) {
    val userId: Int
        get() = UserHandleCompat.getUserId(uid)
        get() = UserHandle.getUserId(uid)

    val appId: Int
        get() = UserHandle.getAppId(uid)
Loading