1 /** <lambda>null2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * ``` 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * ``` 10 * 11 * Unless required by applicable law or agreed to in writing, software distributed under the License 12 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 * or implied. See the License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 package com.android.healthconnect.controller.permissions.connectedapps 17 18 import com.android.healthconnect.controller.permissions.api.IGetGrantedHealthPermissionsUseCase 19 import com.android.healthconnect.controller.permissions.shared.IQueryRecentAccessLogsUseCase 20 import com.android.healthconnect.controller.service.IoDispatcher 21 import com.android.healthconnect.controller.shared.HealthPermissionReader 22 import com.android.healthconnect.controller.shared.app.AppInfoReader 23 import com.android.healthconnect.controller.shared.app.ConnectedAppMetadata 24 import com.android.healthconnect.controller.shared.app.ConnectedAppStatus 25 import com.android.healthconnect.controller.shared.app.IGetContributorAppInfoUseCase 26 import javax.inject.Inject 27 import javax.inject.Singleton 28 import kotlinx.coroutines.CoroutineDispatcher 29 import kotlinx.coroutines.withContext 30 31 @Singleton 32 class LoadHealthPermissionApps 33 @Inject 34 constructor( 35 private val healthPermissionReader: HealthPermissionReader, 36 private val loadGrantedHealthPermissionsUseCase: IGetGrantedHealthPermissionsUseCase, 37 private val getContributorAppInfoUseCase: IGetContributorAppInfoUseCase, 38 private val queryRecentAccessLogsUseCase: IQueryRecentAccessLogsUseCase, 39 private val appInfoReader: AppInfoReader, 40 @IoDispatcher private val dispatcher: CoroutineDispatcher, 41 ) : ILoadHealthPermissionApps { 42 43 /** Returns a list of [ConnectedAppMetadata]. */ 44 override suspend operator fun invoke(): List<ConnectedAppMetadata> = 45 withContext(dispatcher) { 46 val appsWithHealthPermissions = healthPermissionReader.getAppsWithHealthPermissions() 47 val appsWithData = getContributorAppInfoUseCase.invoke() 48 val connectedApps = mutableListOf<ConnectedAppMetadata>() 49 val recentAccess = queryRecentAccessLogsUseCase.invoke() 50 val appsWithOldHealthPermissions = 51 healthPermissionReader.getAppsWithOldHealthPermissions() 52 53 connectedApps.addAll( 54 appsWithHealthPermissions.map { packageName -> 55 val metadata = appInfoReader.getAppMetadata(packageName) 56 val grantedPermissions = loadGrantedHealthPermissionsUseCase(packageName) 57 val isConnected = 58 if (grantedPermissions.isNotEmpty()) { 59 ConnectedAppStatus.ALLOWED 60 } else { 61 ConnectedAppStatus.DENIED 62 } 63 ConnectedAppMetadata(metadata, isConnected, recentAccess[metadata.packageName]) 64 }) 65 66 val inactiveApps = 67 appsWithData.values 68 .filter { !appsWithHealthPermissions.contains(it.packageName) } 69 .map { ConnectedAppMetadata(it, ConnectedAppStatus.INACTIVE) } 70 71 val appsThatNeedUpdating = 72 appsWithOldHealthPermissions 73 .map { packageName -> 74 val metadata = appInfoReader.getAppMetadata(packageName) 75 ConnectedAppMetadata( 76 metadata, 77 ConnectedAppStatus.NEEDS_UPDATE, 78 recentAccess[metadata.packageName]) 79 } 80 .filter { !appsWithHealthPermissions.contains(it.appMetadata.packageName) } 81 82 connectedApps.addAll(inactiveApps) 83 connectedApps.addAll(appsThatNeedUpdating) 84 connectedApps 85 } 86 } 87 88 interface ILoadHealthPermissionApps { invokenull89 suspend fun invoke(): List<ConnectedAppMetadata> 90 } 91