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