• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2019 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
18 
19 import android.app.Application
20 import android.content.pm.ApplicationInfo
21 import android.content.pm.PackageItemInfo
22 import android.content.pm.PackageManager
23 import android.content.pm.PermissionGroupInfo
24 import android.content.pm.PermissionInfo
25 import android.os.UserHandle
26 import android.util.Log
27 import com.android.permissioncontroller.PermissionControllerApplication
28 import com.android.permissioncontroller.permission.model.livedatatypes.LightPermGroupInfo
29 import com.android.permissioncontroller.permission.model.livedatatypes.LightPermInfo
30 import com.android.permissioncontroller.permission.model.livedatatypes.PermGroup
31 import com.android.permissioncontroller.permission.utils.Utils
32 
33 /**
34  * LiveData for a Permission Group. Contains GroupInfo and a list of PermissionInfos. Loads
35  * synchronously.
36  *
37  * @param app The current application
38  * @param groupName The name of the permission group this LiveData represents
39  */
40 class PermGroupLiveData
41 private constructor(private val app: Application, private val groupName: String) :
42     SmartUpdateMediatorLiveData<PermGroup>(), PackageBroadcastReceiver.PackageBroadcastListener {
43 
44     private val LOG_TAG = this::class.java.simpleName
45 
46     private val context = app.applicationContext!!
47 
48     /** Map<packageName, LiveData<PackageInfo>> */
49     private val packageLiveDatas = mutableMapOf<String, LightPackageInfoLiveData>()
50 
51     private lateinit var groupInfo: PackageItemInfo
52 
53     /**
54      * Called when a package is installed, changed, or removed.
55      *
56      * @param packageName the package which was added or changed
57      */
58     override fun onPackageUpdate(packageName: String) {
59         update()
60     }
61 
62     /**
63      * Initializes this permission group from scratch. Resets the groupInfo, PermissionInfos, and
64      * PackageInfoLiveDatas, then re-adds them.
65      */
66     override fun onUpdate() {
67         val permissionInfos = mutableMapOf<String, LightPermInfo>()
68         groupInfo =
69             Utils.getGroupInfo(groupName, context)
70                 ?: run {
71                     Log.e(LOG_TAG, "Invalid permission group $groupName")
72                     invalidateSingle(groupName)
73                     value = null
74                     return
75                 }
76         val permInfos = mutableListOf<PermissionInfo>()
77         when (groupInfo) {
78             is PermissionGroupInfo -> {
79                 try {
80                     permInfos.addAll(
81                         Utils.getInstalledRuntimePermissionInfosForGroup(
82                             context.packageManager,
83                             groupName
84                         )
85                     )
86                 } catch (e: PackageManager.NameNotFoundException) {
87                     Log.e(LOG_TAG, "Invalid permission group $groupName")
88                     invalidateSingle(groupName)
89                     value = null
90                     return
91                 }
92             }
93             is PermissionInfo -> {
94                 permInfos.add(groupInfo as PermissionInfo)
95             }
96             else -> {
97                 value = null
98                 return
99             }
100         }
101 
102         val packageNames = permInfos.map { permInfo -> permInfo.packageName }.toMutableSet()
103         packageNames.add(groupInfo.packageName)
104         // TODO ntmyren: What if the package isn't installed for the system user?
105         val getLiveData = { packageName: String ->
106             LightPackageInfoLiveData[packageName, UserHandle.SYSTEM]
107         }
108         setSourcesToDifference(packageNames, packageLiveDatas, getLiveData)
109         if (!packageLiveDatas.all { it.value.isInitialized }) {
110             return
111         }
112         for (permInfo in permInfos) {
113             val lightPackageInfo = packageLiveDatas[permInfo.packageName]?.value
114             val isSystem =
115                 lightPackageInfo?.let { it.appFlags and ApplicationInfo.FLAG_SYSTEM != 0 }
116             permissionInfos[permInfo.name] = LightPermInfo(permInfo, isSystem)
117         }
118 
119         val permGroup = PermGroup(LightPermGroupInfo(groupInfo), permissionInfos)
120         value = permGroup
121     }
122 
123     override fun onInactive() {
124         super.onInactive()
125 
126         PackageBroadcastReceiver.removeAllCallback(this)
127     }
128 
129     /**
130      * Load data, and register a package change listener. We must watch for package changes, because
131      * there is currently no listener for permission changes.
132      */
133     override fun onActive() {
134         update()
135 
136         super.onActive()
137 
138         PackageBroadcastReceiver.addAllCallback(this)
139     }
140 
141     /**
142      * Repository for PermGroupLiveDatas.
143      *
144      * <p> Key value is a string permission group name, value is its corresponding LiveData.
145      */
146     companion object : DataRepository<String, PermGroupLiveData>() {
147         override fun newValue(key: String): PermGroupLiveData {
148             return PermGroupLiveData(PermissionControllerApplication.get(), key)
149         }
150     }
151 }
152