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