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.accessibilityservice.AccessibilityService 21 import android.app.Application 22 import android.app.admin.DevicePolicyManager 23 import android.content.Intent 24 import android.content.pm.PackageManager 25 import android.os.UserHandle 26 import android.printservice.PrintService 27 import android.service.autofill.AutofillService 28 import android.service.dreams.DreamService 29 import android.service.notification.NotificationListenerService 30 import android.service.voice.VoiceInteractionService 31 import android.service.wallpaper.WallpaperService 32 import android.view.inputmethod.InputMethod 33 import com.android.permissioncontroller.DumpableLog 34 import com.android.permissioncontroller.PermissionControllerApplication 35 import com.android.permissioncontroller.hibernation.DEBUG_HIBERNATION_POLICY 36 import com.android.permissioncontroller.permission.utils.Utils.getUserContext 37 import kotlinx.coroutines.Job 38 39 /** 40 * A LiveData which tracks services for a certain type 41 * 42 * @param app The current application 43 * @param intentAction The name of interface the service implements 44 * @param permission The permission required for the service 45 * @param user The user the services should be determined for 46 */ 47 class ServiceLiveData( 48 private val app: Application, 49 override val intentAction: String, 50 private val permission: String, 51 private val user: UserHandle 52 ) : SmartAsyncMediatorLiveData<Set<String>>(), 53 PackageBroadcastReceiver.PackageBroadcastListener, 54 HasIntentAction { 55 56 private val name = intentAction.substringAfterLast(".") 57 58 private val enabledAccessibilityServicesLiveData = EnabledAccessibilityServicesLiveData[user] 59 private val enabledInputMethodsLiveData = EnabledInputMethodsLiveData[user] 60 private val enabledNotificationListenersLiveData = EnabledNotificationListenersLiveData[user] 61 private val selectedWallpaperServiceLiveData = SelectedWallpaperServiceLiveData[user] 62 private val selectedVoiceInteractionServiceLiveData = 63 SelectedVoiceInteractionServiceLiveData[user] 64 private val selectedAutofillServiceLiveData = SelectedAutofillServiceLiveData[user] 65 private val enabledDreamServicesLiveData = EnabledDreamServicesLiveData[user] 66 private val disabledPrintServicesLiveData = DisabledPrintServicesLiveData[user] 67 private val enabledDeviceAdminsLiveDataLiveData = EnabledDeviceAdminsLiveData[user] 68 69 init { 70 if (intentAction == AccessibilityService.SERVICE_INTERFACE) { 71 addSource(enabledAccessibilityServicesLiveData) { 72 updateAsync() 73 } 74 } 75 if (intentAction == InputMethod.SERVICE_INTERFACE) { 76 addSource(enabledInputMethodsLiveData) { 77 updateAsync() 78 } 79 } 80 if (intentAction == NotificationListenerService.SERVICE_INTERFACE) { 81 addSource(enabledNotificationListenersLiveData) { 82 updateAsync() 83 } 84 } 85 if (intentAction == WallpaperService.SERVICE_INTERFACE) { 86 addSource(selectedWallpaperServiceLiveData) { 87 updateAsync() 88 } 89 } 90 if (intentAction == VoiceInteractionService.SERVICE_INTERFACE) { 91 addSource(selectedVoiceInteractionServiceLiveData) { 92 updateAsync() 93 } 94 } 95 if (intentAction == AutofillService.SERVICE_INTERFACE) { 96 addSource(selectedAutofillServiceLiveData) { 97 updateAsync() 98 } 99 } 100 if (intentAction == DreamService.SERVICE_INTERFACE) { 101 addSource(enabledDreamServicesLiveData) { 102 updateAsync() 103 } 104 } 105 if (intentAction == PrintService.SERVICE_INTERFACE) { 106 addSource(disabledPrintServicesLiveData) { 107 updateAsync() 108 } 109 } 110 if (intentAction == DevicePolicyManager.ACTION_DEVICE_ADMIN_SERVICE) { 111 addSource(enabledDeviceAdminsLiveDataLiveData) { 112 updateAsync() 113 } 114 } 115 } 116 117 override fun onPackageUpdate(packageName: String) { 118 updateAsync() 119 } 120 121 override suspend fun loadDataAndPostValue(job: Job) { 122 if (job.isCancelled) { 123 return 124 } 125 if (intentAction == AccessibilityService.SERVICE_INTERFACE && 126 !enabledAccessibilityServicesLiveData.isInitialized) { 127 return 128 } 129 if (intentAction == InputMethod.SERVICE_INTERFACE && 130 !enabledInputMethodsLiveData.isInitialized) { 131 return 132 } 133 if (intentAction == NotificationListenerService.SERVICE_INTERFACE && 134 !enabledNotificationListenersLiveData.isInitialized) { 135 return 136 } 137 138 if (intentAction == WallpaperService.SERVICE_INTERFACE && 139 !selectedWallpaperServiceLiveData.isInitialized) { 140 return 141 } 142 if (intentAction == VoiceInteractionService.SERVICE_INTERFACE && 143 !selectedVoiceInteractionServiceLiveData.isInitialized) { 144 return 145 } 146 if (intentAction == AutofillService.SERVICE_INTERFACE && 147 !selectedAutofillServiceLiveData.isInitialized) { 148 return 149 } 150 if (intentAction == DreamService.SERVICE_INTERFACE && 151 !enabledDreamServicesLiveData.isInitialized) { 152 return 153 } 154 if (intentAction == PrintService.SERVICE_INTERFACE && 155 !disabledPrintServicesLiveData.isInitialized) { 156 return 157 } 158 if (intentAction == DevicePolicyManager.ACTION_DEVICE_ADMIN_SERVICE && 159 !enabledDeviceAdminsLiveDataLiveData.isInitialized) { 160 return 161 } 162 163 val packageNames = getUserContext(app, user).packageManager 164 .queryIntentServices( 165 Intent(intentAction), 166 PackageManager.GET_SERVICES or PackageManager.GET_META_DATA) 167 .mapNotNull { resolveInfo -> 168 if (resolveInfo?.serviceInfo?.permission != permission) { 169 return@mapNotNull null 170 } 171 val packageName = resolveInfo.serviceInfo?.packageName 172 if (!isServiceEnabled(packageName)) { 173 if (DEBUG_HIBERNATION_POLICY) { 174 DumpableLog.i(LOG_TAG, 175 "Not exempting $packageName - not an active $name " + 176 "for u${user.identifier}") 177 } 178 return@mapNotNull null 179 } 180 packageName 181 }.toSet() 182 if (DEBUG_HIBERNATION_POLICY) { 183 DumpableLog.i(LOG_TAG, 184 "Detected ${name}s: $packageNames") 185 } 186 187 postValue(packageNames) 188 } 189 190 suspend fun isServiceEnabled(pkg: String?): Boolean { 191 if (pkg == null) { 192 return false 193 } 194 return when (intentAction) { 195 AccessibilityService.SERVICE_INTERFACE -> { 196 pkg in (enabledAccessibilityServicesLiveData.value ?: emptyList<String>()) 197 } 198 InputMethod.SERVICE_INTERFACE -> { 199 pkg in (enabledInputMethodsLiveData.value ?: emptyList<String>()) 200 } 201 NotificationListenerService.SERVICE_INTERFACE -> { 202 pkg in (enabledNotificationListenersLiveData.value ?: emptyList<String>()) 203 } 204 WallpaperService.SERVICE_INTERFACE -> { 205 pkg == selectedWallpaperServiceLiveData.value 206 } 207 VoiceInteractionService.SERVICE_INTERFACE -> { 208 pkg == selectedVoiceInteractionServiceLiveData.value 209 } 210 AutofillService.SERVICE_INTERFACE -> { 211 pkg == selectedAutofillServiceLiveData.value 212 } 213 DreamService.SERVICE_INTERFACE -> { 214 pkg in (enabledDreamServicesLiveData.value ?: emptyList<String>()) 215 } 216 PrintService.SERVICE_INTERFACE -> { 217 pkg !in (disabledPrintServicesLiveData.value ?: emptyList<String>()) 218 } 219 DevicePolicyManager.ACTION_DEVICE_ADMIN_SERVICE -> { 220 pkg in (enabledDeviceAdminsLiveDataLiveData.value ?: emptyList<String>()) 221 } 222 else -> true 223 } 224 } 225 226 override fun onActive() { 227 super.onActive() 228 229 PackageBroadcastReceiver.addAllCallback(this) 230 } 231 232 override fun onInactive() { 233 super.onInactive() 234 235 PackageBroadcastReceiver.removeAllCallback(this) 236 } 237 238 /** 239 * Repository for [ServiceLiveData] 240 * 241 * <p> Key value is a (string service name, required permission, user) triple, value is its 242 * corresponding LiveData. 243 */ 244 companion object : DataRepositoryForPackage<Triple<String, String, UserHandle>, 245 ServiceLiveData>() { 246 private const val LOG_TAG = "ServiceLiveData" 247 248 override fun newValue(key: Triple<String, String, UserHandle>): ServiceLiveData { 249 return ServiceLiveData(PermissionControllerApplication.get(), 250 key.first, key.second, key.third) 251 } 252 } 253 } 254