• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2023 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  */
18 package com.android.healthconnect.controller.shared.app
19 
20 import android.content.Context
21 import android.graphics.Bitmap
22 import android.graphics.drawable.BitmapDrawable
23 import android.graphics.drawable.Drawable
24 import android.health.connect.ApplicationInfoResponse
25 import android.health.connect.HealthConnectManager
26 import android.health.connect.datatypes.AppInfo
27 import android.util.Log
28 import androidx.core.os.asOutcomeReceiver
29 import com.android.healthconnect.controller.service.IoDispatcher
30 import dagger.hilt.android.qualifiers.ApplicationContext
31 import javax.inject.Inject
32 import javax.inject.Singleton
33 import kotlinx.coroutines.CoroutineDispatcher
34 import kotlinx.coroutines.suspendCancellableCoroutine
35 import kotlinx.coroutines.withContext
36 
37 @Singleton
38 class GetContributorAppInfoUseCase
39 @Inject
40 constructor(
41     private val healthConnectManager: HealthConnectManager,
42     @ApplicationContext private val context: Context,
43     @IoDispatcher private val dispatcher: CoroutineDispatcher,
44 ) : IGetContributorAppInfoUseCase {
45     companion object {
46         private const val TAG = "GetContributorAppInfo"
47     }
48 
49     override suspend fun invoke(): Map<String, AppMetadata> =
50         withContext(dispatcher) {
51             try {
52                 val appInfoList =
53                     suspendCancellableCoroutine<ApplicationInfoResponse> { continuation ->
54                             healthConnectManager.getContributorApplicationsInfo(
55                                 Runnable::run,
56                                 continuation.asOutcomeReceiver(),
57                             )
58                         }
59                         .applicationInfoList
60                 appInfoList.associate { it.packageName to toAppMetadata(it) }
61             } catch (e: Exception) {
62                 Log.e(TAG, "GetContributorApplicationsInfoUseCase", e)
63                 emptyMap()
64             }
65         }
66 
67     private fun toAppMetadata(appInfo: AppInfo): AppMetadata {
68         return AppMetadata(
69             packageName = appInfo.packageName,
70             appName =
71                 appInfo.name
72                     ?: appInfo.packageName, // default to package name if appInfo name is null
73             icon = getIcon(appInfo.icon),
74         )
75     }
76 
77     private fun getIcon(bitmap: Bitmap?): Drawable? {
78         return bitmap?.let { BitmapDrawable(context.resources, it) }
79     }
80 }
81 
82 interface IGetContributorAppInfoUseCase {
invokenull83     suspend operator fun invoke(): Map<String, AppMetadata>
84 }
85