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

Commit 93ed715a authored by Nate Myren's avatar Nate Myren
Browse files

Create setSourcesToDifference function

Create a function which automates the adding and removing of sources,
and ensure the whole function is posted to the main thread, so we are
guarenteed the ordering of add and remove source methods.

Test: manual, currently existing automated
Fixes: 156748792
Change-Id: Ib8498c5d4ec19197d1e02661595b3d19a658ef32
parent f68abebd
Loading
Loading
Loading
Loading
+3 −21
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.permissioncontroller.permission.data
import android.os.UserHandle
import com.android.permissioncontroller.permission.data.AllPackageInfosLiveData.addSource
import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo
import com.android.permissioncontroller.permission.utils.KotlinUtils

/**
 * A LiveData which tracks the PackageInfos of all of the packages in the system, for all users.
@@ -38,26 +37,9 @@ object AllPackageInfosLiveData :

    override fun onUpdate() {
        UsersLiveData.value?.let { users ->
            val (usersToAdd, usersToRemove) =
                KotlinUtils.getMapAndListDifferences(users, userPackageInfosLiveDatas)
            for (user in usersToRemove) {
                userPackageInfosLiveDatas[user]?.let { userPackageInfosLiveData ->
                    removeSource(userPackageInfosLiveData)
                    userPackageInfosLiveDatas.remove(user)
                }
            }
            for (user in usersToAdd) {
                val userPackageInfosLiveData =
                    UserPackageInfosLiveData[user]
                userPackageInfosLiveDatas[user] = userPackageInfosLiveData
            }

            for (user in usersToAdd) {
                addSource(userPackageInfosLiveDatas[user]!!) {
                    it?.let { packageInfos ->
                        onUserPackageUpdates(user, packageInfos)
                    }
                }
            val getLiveData = { user: UserHandle -> UserPackageInfosLiveData[user] }
            setSourcesToDifference(users, userPackageInfosLiveDatas, getLiveData) { user ->
                onUserPackageUpdates(user, userPackageInfosLiveDatas[user]?.value)
            }
        }
    }
+2 −24
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import com.android.permissioncontroller.permission.data.PackagePermissionsLiveDa
import com.android.permissioncontroller.permission.model.livedatatypes.AutoRevokeState
import com.android.permissioncontroller.permission.service.isAutoRevokeEnabled
import com.android.permissioncontroller.permission.service.isPackageAutoRevokeExempt
import com.android.permissioncontroller.permission.utils.KotlinUtils
import kotlinx.coroutines.Job

/**
@@ -81,7 +80,8 @@ class AutoRevokeStateLiveData private constructor(
            return
        }

        addAndRemovePermStateLiveDatas(groups)
        val getLiveData = { groupName: String -> PermStateLiveData[packageName, groupName, user] }
        setSourcesToDifference(groups, permStateLiveDatas, getLiveData)

        if (!permStateLiveDatas.all { it.value.isInitialized }) {
            return
@@ -102,28 +102,6 @@ class AutoRevokeStateLiveData private constructor(
        postValue(AutoRevokeState(isAutoRevokeEnabled(app), revocable, autoRevokeState))
    }

    private fun addAndRemovePermStateLiveDatas(groupNames: List<String>) {
        val (toAdd, toRemove) = KotlinUtils.getMapAndListDifferences(groupNames,
            permStateLiveDatas)

        for (groupToAdd in toAdd) {
            val permStateLiveData =
                PermStateLiveData[packageName, groupToAdd, user]
            permStateLiveDatas[groupToAdd] = permStateLiveData
        }

        for (groupToAdd in toAdd) {
            addSource(permStateLiveDatas[groupToAdd]!!) {
                updateIfActive()
            }
        }

        for (groupToRemove in toRemove) {
            removeSource(permStateLiveDatas[groupToRemove]!!)
            permStateLiveDatas.remove(groupToRemove)
        }
    }

    override fun onOpChanged(op: String?, packageName: String?) {
        if (op == OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED && packageName == packageName) {
            updateIfActive()
+71 −62
Original line number Diff line number Diff line
@@ -22,6 +22,9 @@ import com.android.permissioncontroller.PermissionControllerApplication
import com.android.permissioncontroller.permission.data.PackagePermissionsLiveData.Companion.NON_RUNTIME_NORMAL_PERMS
import com.android.permissioncontroller.permission.service.getUnusedThresholdMs
import com.android.permissioncontroller.permission.utils.KotlinUtils
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

/**
 * Tracks which packages have been auto-revoked, and which groups have been auto revoked for those
@@ -59,6 +62,7 @@ object AutoRevokedPackagesLiveData
            })
        }

        GlobalScope.launch(Main.immediate) {
            val (toAdd, toRemove) =
                KotlinUtils.getMapAndListDifferences(packageNames, packagePermGroupsLiveDatas)

@@ -85,6 +89,7 @@ object AutoRevokedPackagesLiveData
                }
            }
        }
    }

    private fun observePermStateLiveDatas() {
        val packageGroups = mutableListOf<Triple<String, String, UserHandle>>()
@@ -94,6 +99,9 @@ object AutoRevokedPackagesLiveData
                permGroups.map { Triple(pkgPair.first, it, pkgPair.second) }
            } ?: emptyList()
        })

        GlobalScope.launch(Main.immediate) {

            val (toAdd, toRemove) =
                KotlinUtils.getMapAndListDifferences(packageGroups, permStateLiveDatas)

@@ -147,6 +155,7 @@ object AutoRevokedPackagesLiveData
                }
            }
        }
    }

    private fun postCopyOfMap() {
        val autoRevokedCopy =
+5 −36
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import com.android.permissioncontroller.PermissionControllerApplication
import com.android.permissioncontroller.permission.model.livedatatypes.LightPermGroupInfo
import com.android.permissioncontroller.permission.model.livedatatypes.LightPermInfo
import com.android.permissioncontroller.permission.model.livedatatypes.PermGroup
import com.android.permissioncontroller.permission.utils.KotlinUtils
import com.android.permissioncontroller.permission.utils.Utils

/**
@@ -63,18 +62,6 @@ class PermGroupLiveData private constructor(
        updateIfActive()
    }

    /**
     * Adds a PackageInfoLiveData as a source, if we don't already have it.
     *
     * @param packageName the name of the package the PackageInfoLiveData watches
     * @param liveData the PackageInfoLiveData to be inserted
     */
    private fun addPackageLiveData(packageName: String, liveData: LightPackageInfoLiveData) {
        if (!packageLiveDatas.contains(packageName)) {
            packageLiveDatas[packageName] = liveData
        }
    }

    /**
     * Initializes this permission group from scratch. Resets the groupInfo, PermissionInfos, and
     * PackageInfoLiveDatas, then re-adds them.
@@ -116,32 +103,14 @@ class PermGroupLiveData private constructor(
        value = permGroup

        val packageNames = permissionInfos.values.map { permInfo -> permInfo.packageName }
            .toMutableSet()
        packageNames.add(groupInfo.packageName)

        // TODO ntmyren: What if the package isn't installed for the system user?
        addPackageLiveData(groupInfo.packageName,
            LightPackageInfoLiveData[groupInfo.packageName, UserHandle.SYSTEM])

        val (toAdd, toRemove) = KotlinUtils.getMapAndListDifferences(packageNames, packageLiveDatas)
        val toAddWithGroupPkg = toAdd.toMutableSet()
        if (!packageLiveDatas.contains(groupInfo.packageName)) {
                toAddWithGroupPkg.add(groupInfo.packageName)
            }

        for (packageName in toRemove) {
            packageLiveDatas[packageName]?.let { liveData ->
                packageLiveDatas.remove(packageName)
                removeSource(liveData)
            }
        }
        for (packageName in toAddWithGroupPkg) {
            packageLiveDatas[packageName] = LightPackageInfoLiveData[packageName, UserHandle.SYSTEM]
        }

        for (packageName in toAddWithGroupPkg) {
            addSource(packageLiveDatas[packageName]!!) {
                onUpdate()
            }
        val getLiveData = { packageName: String ->
            LightPackageInfoLiveData[packageName, UserHandle.SYSTEM]
        }
        setSourcesToDifference(packageNames, packageLiveDatas, getLiveData)
    }

    override fun onInactive() {
+8 −32
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import android.os.UserHandle
import androidx.lifecycle.LiveData
import com.android.permissioncontroller.PermissionControllerApplication
import com.android.permissioncontroller.permission.model.livedatatypes.PermGroup
import com.android.permissioncontroller.permission.utils.KotlinUtils
import com.android.permissioncontroller.permission.utils.Utils.OS_PKG

/**
@@ -45,45 +44,22 @@ class PermGroupsPackagesLiveData private constructor(
    init {
        addSource(groupNamesLiveData) {
            groupNames = it ?: emptyList()
            addPermissionGroups()
        }

        addSource(packagesLiveData) {
            if (permGroupLiveDatas.all { it.value.isInitialized }) {
            val getLiveData = { groupName: String -> PermGroupLiveData[groupName] }
            setSourcesToDifference(groupNames, permGroupLiveDatas, getLiveData) {
                if (packagesLiveData.isInitialized &&
                    permGroupLiveDatas.all { it.value.isInitialized }) {
                    updateIfActive()
                }
            }
        }

    /**
     * Called after updating groupNames to add and remove PermGroupLiveDatas to match the new
     * value of groupNames.
     */
    private fun addPermissionGroups() {
        val (toAdd, toRemove) = KotlinUtils.getMapAndListDifferences(groupNames, permGroupLiveDatas)
        for (groupToRemove in toRemove) {
            permGroupLiveDatas[groupToRemove]?.let { permGroupLiveData ->
                permGroupLiveDatas.remove(groupToRemove)
                removeSource(permGroupLiveData)
            }
        }

        // We add all groups to our map first, so that the check if all are initialized can see
        // all of the LiveDatas.
        for (groupToAdd in toAdd) {
            permGroupLiveDatas[groupToAdd] =
                PermGroupLiveData[groupToAdd]
        }

        for (groupToAdd in toAdd) {
            addSource(permGroupLiveDatas[groupToAdd]!!) {
                if (packagesLiveData.isInitialized &&
                    permGroupLiveDatas.all { it.value.isInitialized }) {
        addSource(packagesLiveData) {
            if (permGroupLiveDatas.all { it.value.isInitialized }) {
                updateIfActive()
            }
        }
    }
    }

    /**
     * Using the current list of permission groups, go through all packages in the system,
Loading