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

Commit fbae9f5a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Exempt device admin receiver-only apps from auto revoke" into rvc-dev

parents 26f2ff20 f972f892
Loading
Loading
Loading
Loading
+100 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.permissioncontroller.permission.data

import android.app.Application
import android.content.Intent
import android.content.pm.PackageManager
import android.os.UserHandle
import com.android.permissioncontroller.DumpableLog
import com.android.permissioncontroller.PermissionControllerApplication
import com.android.permissioncontroller.permission.utils.Utils.getUserContext
import kotlinx.coroutines.Job

/**
 * A LiveData which tracks broadcast receivers for a certain type
 *
 * @param app The current application
 * @param intentAction The name of the action the receiver receives
 * @param permission The permission required for the receiver
 * @param user The user the receivers should be determined for
 */
class BroadcastReceiverLiveData(
    private val app: Application,
    override val intentAction: String,
    private val permission: String,
    private val user: UserHandle
) : SmartAsyncMediatorLiveData<Set<String>>(),
        PackageBroadcastReceiver.PackageBroadcastListener,
        HasIntentAction {
    private val DEBUG = false

    override fun onPackageUpdate(packageName: String) {
        updateAsync()
    }

    override suspend fun loadDataAndPostValue(job: Job) {
        if (job.isCancelled) {
            return
        }

        val packageNames = getUserContext(app, user).packageManager
                .queryBroadcastReceivers(
                        Intent(intentAction),
                        PackageManager.GET_RECEIVERS or PackageManager.GET_META_DATA)
                .mapNotNull { resolveInfo ->
                    if (resolveInfo?.activityInfo?.permission != permission) {
                        return@mapNotNull null
                    }
                    resolveInfo?.activityInfo?.packageName
                }.toSet()
        if (DEBUG) {
            DumpableLog.i(LOG_TAG,
                    "Detected ${intentAction.substringAfterLast(".")}s: $packageNames")
        }

        postValue(packageNames)
    }

    override fun onActive() {
        super.onActive()

        PackageBroadcastReceiver.addAllCallback(this)

        updateAsync()
    }

    override fun onInactive() {
        super.onInactive()

        PackageBroadcastReceiver.removeAllCallback(this)
    }

    /**
     * Repository for [BroadcastReceiverLiveData]
     *
     * <p> Key value is a (string intent action, required permission, user) triple, value is its
     * corresponding LiveData.
     */
    companion object : DataRepositoryForPackage<Triple<String, String, UserHandle>,
            BroadcastReceiverLiveData>() {
        override fun newValue(key: Triple<String, String, UserHandle>): BroadcastReceiverLiveData {
            return BroadcastReceiverLiveData(PermissionControllerApplication.get(),
                    key.first, key.second, key.third)
        }
    }
}
 No newline at end of file
+24 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.permissioncontroller.permission.data

/**
 * An interface for classes that have an [Intent] action
 */
interface HasIntentAction {
    val intentAction: String
}
 No newline at end of file
+9 −8
Original line number Diff line number Diff line
@@ -29,17 +29,18 @@ import kotlinx.coroutines.Job
 * A LiveData which tracks services for a certain type
 *
 * @param app The current application
 * @param serviceInterface The name of interface the service implements
 * @param intentAction The name of interface the service implements
 * @param permission The permission required for the service
 * @param user The user the services should be determined for
 */
class ServiceLiveData(
    private val app: Application,
    val serviceInterface: String,
    override val intentAction: String,
    private val permission: String,
    private val user: UserHandle
) : SmartAsyncMediatorLiveData<Set<String>>(),
        PackageBroadcastReceiver.PackageBroadcastListener {
        PackageBroadcastReceiver.PackageBroadcastListener,
        HasIntentAction {
    private val DEBUG = false

    override fun onPackageUpdate(packageName: String) {
@@ -53,7 +54,7 @@ class ServiceLiveData(

        val packageNames = getUserContext(app, user).packageManager
                .queryIntentServices(
                        Intent(serviceInterface),
                        Intent(intentAction),
                        PackageManager.GET_SERVICES or PackageManager.GET_META_DATA)
                .mapNotNull { resolveInfo ->
                    if (resolveInfo?.serviceInfo?.permission != permission) {
@@ -63,7 +64,7 @@ class ServiceLiveData(
                }.toSet()
        if (DEBUG) {
            DumpableLog.i(LOG_TAG,
                    "Detected ${serviceInterface.substringAfterLast(".")}s: $packageNames")
                    "Detected ${intentAction.substringAfterLast(".")}s: $packageNames")
        }

        postValue(packageNames)
@@ -80,13 +81,13 @@ class ServiceLiveData(
    override fun onInactive() {
        super.onInactive()

        PackageBroadcastReceiver.addAllCallback(this)
        PackageBroadcastReceiver.removeAllCallback(this)
    }

    /**
     * Repository for ServiceLiveData
     * Repository for [ServiceLiveData]
     *
     * <p> Key value is a string service name, required permission user triple, value is its
     * <p> Key value is a (string service name, required permission, user) triple, value is its
     * corresponding LiveData.
     */
    companion object : DataRepositoryForPackage<Triple<String, String, UserHandle>,
+9 −2
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.app.NotificationManager.IMPORTANCE_LOW
import android.app.PendingIntent
import android.app.PendingIntent.FLAG_ONE_SHOT
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
import android.app.admin.DeviceAdminReceiver
import android.app.admin.DevicePolicyManager
import android.app.job.JobInfo
import android.app.job.JobParameters
@@ -84,7 +85,9 @@ import com.android.permissioncontroller.permission.data.AllPackageInfosLiveData
import com.android.permissioncontroller.permission.data.AppOpLiveData
import com.android.permissioncontroller.permission.data.AutoRevokeManifestExemptPackagesLiveData
import com.android.permissioncontroller.permission.data.AutoRevokeStateLiveData
import com.android.permissioncontroller.permission.data.BroadcastReceiverLiveData
import com.android.permissioncontroller.permission.data.DataRepositoryForPackage
import com.android.permissioncontroller.permission.data.HasIntentAction
import com.android.permissioncontroller.permission.data.LightAppPermGroupLiveData
import com.android.permissioncontroller.permission.data.PackagePermissionsLiveData
import com.android.permissioncontroller.permission.data.ServiceLiveData
@@ -626,7 +629,7 @@ class AutoRevokeService : JobService() {
 */
private class ExemptServicesLiveData(val user: UserHandle)
    : SmartUpdateMediatorLiveData<Map<String, List<String>>>() {
    private val serviceLiveDatas = listOf(
    private val serviceLiveDatas: List<SmartUpdateMediatorLiveData<Set<String>>> = listOf(
            ServiceLiveData[InputMethod.SERVICE_INTERFACE,
                    Manifest.permission.BIND_INPUT_METHOD,
                    user],
@@ -677,6 +680,10 @@ private class ExemptServicesLiveData(val user: UserHandle)
            ServiceLiveData[
                    DevicePolicyManager.ACTION_DEVICE_ADMIN_SERVICE,
                    Manifest.permission.BIND_DEVICE_ADMIN,
                    user],
            BroadcastReceiverLiveData[
                    DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED,
                    Manifest.permission.BIND_DEVICE_ADMIN,
                    user]
    )

@@ -691,7 +698,7 @@ private class ExemptServicesLiveData(val user: UserHandle)
            serviceLiveDatas.forEach { serviceLD ->
                serviceLD.value!!.forEach { packageName ->
                    pksToServices.getOrPut(packageName, { mutableListOf() })
                            .add(serviceLD.serviceInterface)
                            .add((serviceLD as? HasIntentAction)?.intentAction ?: "???")
                }
            }