1 /* <lambda>null2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 @file:Suppress("DEPRECATION") 17 18 package com.android.permissioncontroller.permission.data 19 20 import android.app.Application 21 import android.app.admin.DeviceAdminReceiver 22 import android.content.Intent 23 import android.content.pm.PackageManager 24 import android.os.UserHandle 25 import com.android.permissioncontroller.DumpableLog 26 import com.android.permissioncontroller.PermissionControllerApplication 27 import com.android.permissioncontroller.hibernation.DEBUG_HIBERNATION_POLICY 28 import com.android.permissioncontroller.permission.utils.Utils.getUserContext 29 import kotlinx.coroutines.Job 30 31 /** 32 * A LiveData which tracks broadcast receivers for a certain type 33 * 34 * @param app The current application 35 * @param intentAction The name of the action the receiver receives 36 * @param permission The permission required for the receiver 37 * @param user The user the receivers should be determined for 38 */ 39 class BroadcastReceiverLiveData( 40 private val app: Application, 41 override val intentAction: String, 42 private val permission: String, 43 private val user: UserHandle 44 ) : SmartAsyncMediatorLiveData<Set<String>>(), 45 PackageBroadcastReceiver.PackageBroadcastListener, 46 HasIntentAction { 47 48 private val name = intentAction.substringAfterLast(".") 49 50 private val enabledDeviceAdminsLiveDataLiveData = EnabledDeviceAdminsLiveData[user] 51 52 init { 53 if (intentAction == DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED) { 54 addSource(enabledDeviceAdminsLiveDataLiveData) { 55 updateAsync() 56 } 57 } 58 } 59 60 override fun onPackageUpdate(packageName: String) { 61 updateAsync() 62 } 63 64 override suspend fun loadDataAndPostValue(job: Job) { 65 if (job.isCancelled) { 66 return 67 } 68 if (intentAction == DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED && 69 !enabledDeviceAdminsLiveDataLiveData.isInitialized) { 70 return 71 } 72 73 val packageNames = getUserContext(app, user).packageManager 74 .queryBroadcastReceivers( 75 Intent(intentAction), 76 PackageManager.GET_RECEIVERS or PackageManager.GET_META_DATA) 77 .mapNotNull { resolveInfo -> 78 if (resolveInfo?.activityInfo?.permission != permission) { 79 return@mapNotNull null 80 } 81 val packageName = resolveInfo.activityInfo?.packageName 82 if (!isReceiverEnabled(packageName)) { 83 if (DEBUG_HIBERNATION_POLICY) { 84 DumpableLog.i(LOG_TAG, 85 "Not exempting $packageName - not an active $name " + 86 "for u${user.identifier}") 87 } 88 return@mapNotNull null 89 } 90 packageName 91 }.toSet() 92 if (DEBUG_HIBERNATION_POLICY) { 93 DumpableLog.i(LOG_TAG, 94 "Detected ${intentAction.substringAfterLast(".")}s: $packageNames") 95 } 96 97 postValue(packageNames) 98 } 99 100 private fun isReceiverEnabled(pkg: String?): Boolean { 101 if (pkg == null) { 102 return false 103 } 104 return when (intentAction) { 105 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED -> { 106 pkg in enabledDeviceAdminsLiveDataLiveData.value!! 107 } 108 else -> true 109 } 110 } 111 112 override fun onActive() { 113 super.onActive() 114 115 PackageBroadcastReceiver.addAllCallback(this) 116 } 117 118 override fun onInactive() { 119 super.onInactive() 120 121 PackageBroadcastReceiver.removeAllCallback(this) 122 } 123 124 /** 125 * Repository for [BroadcastReceiverLiveData] 126 * 127 * <p> Key value is a (string intent action, required permission, user) triple, value is its 128 * corresponding LiveData. 129 */ 130 companion object : DataRepositoryForPackage<Triple<String, String, UserHandle>, 131 BroadcastReceiverLiveData>() { 132 private const val LOG_TAG = "BroadcastReceiverLiveData" 133 134 override fun newValue(key: Triple<String, String, UserHandle>): BroadcastReceiverLiveData { 135 return BroadcastReceiverLiveData(PermissionControllerApplication.get(), 136 key.first, key.second, key.third) 137 } 138 } 139 }