• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.v34
18 
19 import android.app.Application
20 import android.content.pm.InstallSourceInfo
21 import android.content.pm.PackageManager
22 import android.os.Process
23 import android.os.UserHandle
24 import android.util.Log
25 import com.android.permissioncontroller.PermissionControllerApplication
26 import com.android.permissioncontroller.permission.data.DataRepositoryForPackage
27 import com.android.permissioncontroller.permission.data.PackageBroadcastReceiver
28 import com.android.permissioncontroller.permission.data.SmartAsyncMediatorLiveData
29 import com.android.permissioncontroller.permission.model.livedatatypes.v34.LightInstallSourceInfo
30 import com.android.permissioncontroller.permission.model.livedatatypes.v34.LightInstallSourceInfo.Companion.INSTALL_SOURCE_UNAVAILABLE
31 import kotlinx.coroutines.Job
32 
33 /**
34  * [LightInstallSourceInfo] [LiveData] for the specified package
35  *
36  * @param app current Application
37  * @param packageName name of the package to get InstallSourceInfo for
38  * @param user The user of the package
39  */
40 class LightInstallSourceInfoLiveData
41 private constructor(
42     private val app: Application,
43     private val packageName: String,
44     private val user: UserHandle
45 ) :
46     SmartAsyncMediatorLiveData<LightInstallSourceInfo>(),
47     PackageBroadcastReceiver.PackageBroadcastListener {
48 
onActivenull49     override fun onActive() {
50         super.onActive()
51         PackageBroadcastReceiver.addChangeCallback(packageName, this)
52     }
53 
onInactivenull54     override fun onInactive() {
55         super.onInactive()
56         PackageBroadcastReceiver.removeChangeCallback(packageName, this)
57     }
58 
59     /**
60      * Callback from the PackageBroadcastReceiver
61      *
62      * @param packageName the name of the package which was updated.
63      */
onPackageUpdatenull64     override fun onPackageUpdate(packageName: String) {
65         update()
66     }
67 
loadDataAndPostValuenull68     override suspend fun loadDataAndPostValue(job: Job) {
69         if (job.isCancelled) {
70             return
71         }
72 
73         val lightInstallSourceInfo: LightInstallSourceInfo =
74             try {
75                 val installSourceInfo = getInstallSourceInfo(packageName)
76                 LightInstallSourceInfo(
77                     installSourceInfo.packageSource, installSourceInfo.initiatingPackageName)
78             } catch (e: PackageManager.NameNotFoundException) {
79                 Log.w(LOG_TAG, "InstallSourceInfo for $packageName not found")
80                 invalidateSingle(packageName to user)
81                 INSTALL_SOURCE_UNAVAILABLE
82             }
83         postValue(lightInstallSourceInfo)
84     }
85 
86     /** Returns the [InstallSourceInfo] for the given package. */
87     @Throws(PackageManager.NameNotFoundException::class)
getInstallSourceInfonull88     private fun getInstallSourceInfo(packageName: String): InstallSourceInfo {
89         val userContext =
90             if (user == Process.myUserHandle()) {
91                 app
92             } else {
93                 app.createContextAsUser(user, /* flags= */ 0)
94             }
95         return userContext.packageManager.getInstallSourceInfo(packageName)
96     }
97 
98     companion object :
99         DataRepositoryForPackage<Pair<String, UserHandle>, LightInstallSourceInfoLiveData>() {
100         private val LOG_TAG = LightInstallSourceInfoLiveData::class.java.simpleName
101 
newValuenull102         override fun newValue(key: Pair<String, UserHandle>): LightInstallSourceInfoLiveData {
103             return LightInstallSourceInfoLiveData(
104                 PermissionControllerApplication.get(), key.first, key.second)
105         }
106     }
107 }
108