1 /* <lambda>null2 * Copyright (C) 2024 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 17 package com.android.permissioncontroller.permission.data.v35 18 19 import android.app.Application 20 import android.companion.virtual.VirtualDeviceManager 21 import android.content.pm.PackageManager 22 import android.os.Build 23 import android.os.UserHandle 24 import android.permission.PermissionManager 25 import android.permission.PermissionManager.PermissionState 26 import androidx.annotation.RequiresApi 27 import com.android.modules.utils.build.SdkLevel 28 import com.android.permissioncontroller.PermissionControllerApplication 29 import com.android.permissioncontroller.permission.data.DataRepositoryForPackage 30 import com.android.permissioncontroller.permission.data.SmartAsyncMediatorLiveData 31 import com.android.permissioncontroller.permission.model.livedatatypes.AppPermGroupUiInfo 32 import com.android.permissioncontroller.permission.utils.PermissionMapping 33 import kotlinx.coroutines.Job 34 35 /** 36 * LiveData that loads all the external device permissions per package. The permissions will be 37 * loaded only if the package has requested the permission. This live data produces the list of 38 * {@link ExternalDeviceGrantInfo} that has group name to which permission belongs to, grant state 39 * and persistentDeviceId 40 * 41 * @param app The current Application 42 * @param packageName The name of the package 43 * @param user The user for whom the packageInfo will be defined 44 */ 45 class PackagePermissionsExternalDeviceLiveData 46 private constructor(private val app: Application, val packageName: String, val user: UserHandle) : 47 SmartAsyncMediatorLiveData< 48 List<PackagePermissionsExternalDeviceLiveData.ExternalDeviceGrantInfo> 49 >() { 50 private val permissionManager = app.getSystemService(PermissionManager::class.java)!! 51 52 data class ExternalDeviceGrantInfo( 53 val groupName: String, 54 val permGrantState: AppPermGroupUiInfo.PermGrantState, 55 val persistentDeviceId: String 56 ) 57 58 @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) 59 override suspend fun loadDataAndPostValue(job: Job) { 60 if (!SdkLevel.isAtLeastV()) { 61 return 62 } 63 val virtualDeviceManager = app.getSystemService(VirtualDeviceManager::class.java) ?: return 64 val externalDeviceGrantInfoList = 65 virtualDeviceManager.allPersistentDeviceIds 66 .map { getVirtualDeviceGrantInfoList(it) } 67 .toList() 68 .flatten() 69 postValue(externalDeviceGrantInfoList) 70 } 71 72 @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) 73 private fun getVirtualDeviceGrantInfoList( 74 persistentDeviceId: String 75 ): List<ExternalDeviceGrantInfo> { 76 val permissionState = 77 permissionManager.getAllPermissionStates(packageName, persistentDeviceId) 78 return permissionState.mapNotNull { (permissionName, permissionState) -> 79 PermissionMapping.getGroupOfPlatformPermission(permissionName)?.let { groupName -> 80 val grantState = getGrantState(permissionState) 81 ExternalDeviceGrantInfo(groupName, grantState, persistentDeviceId) 82 } 83 } 84 } 85 86 /** 87 * This method returns the GrantState for currently supported virtual device permissions 88 * (Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO). 89 * 90 * TODO: b/328841671 (Unite this with PermGroupUiInfoLiveData#getGrantedIncludingBackground) 91 */ 92 @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) 93 private fun getGrantState(permissionState: PermissionState): AppPermGroupUiInfo.PermGrantState = 94 if (permissionState.isGranted) { 95 AppPermGroupUiInfo.PermGrantState.PERMS_ALLOWED_FOREGROUND_ONLY 96 } else if (permissionState.flags and PackageManager.FLAG_PERMISSION_ONE_TIME != 0) { 97 AppPermGroupUiInfo.PermGrantState.PERMS_ASK 98 } else { 99 AppPermGroupUiInfo.PermGrantState.PERMS_DENIED 100 } 101 102 companion object : 103 DataRepositoryForPackage< 104 Pair<String, UserHandle>, PackagePermissionsExternalDeviceLiveData 105 >() { 106 override fun newValue( 107 key: Pair<String, UserHandle> 108 ): PackagePermissionsExternalDeviceLiveData { 109 return PackagePermissionsExternalDeviceLiveData( 110 PermissionControllerApplication.get(), 111 key.first, 112 key.second 113 ) 114 } 115 } 116 } 117