1 /*
2  * 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.content.pm.ApplicationInfo
22 import android.content.pm.PackageManager
23 import android.content.pm.PackageManager.ApplicationInfoFlags
24 import dagger.hilt.android.qualifiers.ApplicationContext
25 import javax.inject.Inject
26 import javax.inject.Singleton
27 
28 @Singleton
29 class AppInfoReader
30 @Inject
31 constructor(
32     @ApplicationContext private val context: Context,
33     private val applicationsInfoUseCase: GetContributorAppInfoUseCase
34 ) {
35 
36     private var cache: HashMap<String, AppMetadata> = HashMap()
37     private val packageManager = context.packageManager
38 
getAppMetadatanull39     suspend fun getAppMetadata(packageName: String): AppMetadata {
40         if (cache.containsKey(packageName)) {
41             return cache[packageName]!!
42         } else if (isAppInstalled(packageName)) {
43             val app =
44                 AppMetadata(
45                     packageName = packageName,
46                     appName =
47                         packageManager.getApplicationLabel(getPackageInfo(packageName)).toString(),
48                     icon = packageManager.getApplicationIcon(packageName))
49             cache[packageName] = app
50             return app
51         } else {
52             val contributorApps = applicationsInfoUseCase.invoke()
53             cache.putAll(contributorApps)
54             return if (contributorApps.containsKey(packageName)) {
55                 contributorApps[packageName]!!
56             } else {
57                 AppMetadata(packageName = packageName, appName = "", icon = null)
58             }
59         }
60     }
61 
isAppInstallednull62     fun isAppInstalled(packageName: String): Boolean {
63         return try {
64             getPackageInfo(packageName).enabled
65         } catch (e: PackageManager.NameNotFoundException) {
66             false
67         }
68     }
69 
getPackageInfonull70     private fun getPackageInfo(packageName: String): ApplicationInfo {
71         return packageManager.getApplicationInfo(packageName, ApplicationInfoFlags.of(0))
72     }
73 }
74