1 /*
<lambda>null2  * Copyright (C) 2021 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.server.permission.access
18 
19 import android.content.Context
20 import android.content.pm.PackageManager
21 import android.content.pm.PackageManagerInternal
22 import android.os.SystemProperties
23 import android.os.UserHandle
24 import com.android.internal.annotations.Keep
25 import com.android.server.LocalManagerRegistry
26 import com.android.server.LocalServices
27 import com.android.server.SystemConfig
28 import com.android.server.SystemService
29 import com.android.server.appop.AppOpsCheckingServiceInterface
30 import com.android.server.permission.PermissionManagerLocal
31 import com.android.server.permission.access.appop.AppOpService
32 import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
33 import com.android.server.permission.access.immutable.* // ktlint-disable no-wildcard-imports
34 import com.android.server.permission.access.permission.PermissionManagerLocalImpl
35 import com.android.server.permission.access.permission.PermissionService
36 import com.android.server.pm.KnownPackages
37 import com.android.server.pm.PackageManagerLocal
38 import com.android.server.pm.UserManagerService
39 import com.android.server.pm.permission.PermissionManagerServiceInterface
40 import com.android.server.pm.pkg.PackageState
41 import kotlin.contracts.ExperimentalContracts
42 import kotlin.contracts.InvocationKind
43 import kotlin.contracts.contract
44 
45 @Keep
46 class AccessCheckingService(context: Context) : SystemService(context) {
47     @Volatile private lateinit var state: AccessState
48     private val stateLock = Any()
49 
50     private val policy = AccessPolicy()
51 
52     private val persistence = AccessPersistence(policy)
53 
54     private lateinit var appOpService: AppOpService
55     private lateinit var permissionService: PermissionService
56 
57     private lateinit var packageManagerInternal: PackageManagerInternal
58     private lateinit var packageManagerLocal: PackageManagerLocal
59     private lateinit var userManagerService: UserManagerService
60     private lateinit var systemConfig: SystemConfig
61 
62     override fun onStart() {
63         appOpService = AppOpService(this)
64         permissionService = PermissionService(this)
65 
66         LocalServices.addService(AppOpsCheckingServiceInterface::class.java, appOpService)
67         LocalServices.addService(PermissionManagerServiceInterface::class.java, permissionService)
68 
69         LocalManagerRegistry.addManager(
70             PermissionManagerLocal::class.java,
71             PermissionManagerLocalImpl(this)
72         )
73     }
74 
75     fun initialize() {
76         packageManagerInternal = LocalServices.getService(PackageManagerInternal::class.java)
77         packageManagerLocal =
78             LocalManagerRegistry.getManagerOrThrow(PackageManagerLocal::class.java)
79         userManagerService = UserManagerService.getInstance()
80         systemConfig = SystemConfig.getInstance()
81 
82         val userIds = MutableIntSet(userManagerService.userIdsIncludingPreCreated)
83         val (packageStates, disabledSystemPackageStates) = packageManagerLocal.allPackageStates
84         val knownPackages = packageManagerInternal.knownPackages
85         val isLeanback = systemConfig.isLeanback
86         val configPermissions = systemConfig.permissions
87         val privilegedPermissionAllowlistPackages =
88             systemConfig.privilegedPermissionAllowlistPackages
89         val permissionAllowlist = systemConfig.permissionAllowlist
90         val implicitToSourcePermissions = systemConfig.implicitToSourcePermissions
91 
92         val state = MutableAccessState()
93         policy.initialize(
94             state,
95             userIds,
96             packageStates,
97             disabledSystemPackageStates,
98             knownPackages,
99             isLeanback,
100             configPermissions,
101             privilegedPermissionAllowlistPackages,
102             permissionAllowlist,
103             implicitToSourcePermissions
104         )
105         persistence.initialize()
106         persistence.read(state)
107         this.state = state
108 
109         appOpService.initialize()
110         permissionService.initialize()
111     }
112 
113     private val SystemConfig.isLeanback: Boolean
114         get() = PackageManager.FEATURE_LEANBACK in availableFeatures
115 
116     private val SystemConfig.privilegedPermissionAllowlistPackages: IndexedListSet<String>
117         get() =
118             MutableIndexedListSet<String>().apply {
119                 this += "android"
120                 if (PackageManager.FEATURE_AUTOMOTIVE in availableFeatures) {
121                     // Note that SystemProperties.get(String, String) forces returning an empty
122                     // string
123                     // even if we pass null for the def parameter.
124                     val carServicePackage =
125                         SystemProperties.get("ro.android.car.carservice.package")
126                     if (carServicePackage.isNotEmpty()) {
127                         this += carServicePackage
128                     }
129                 }
130             }
131 
132     private val SystemConfig.implicitToSourcePermissions: IndexedMap<String, IndexedListSet<String>>
133         @Suppress("UNCHECKED_CAST")
134         get() =
135             MutableIndexedMap<String, MutableIndexedListSet<String>>().apply {
136                 splitPermissions.forEach { splitPermissionInfo ->
137                     val sourcePermissionName = splitPermissionInfo.splitPermission
138                     splitPermissionInfo.newPermissions.forEach { implicitPermissionName ->
139                         getOrPut(implicitPermissionName) { MutableIndexedListSet() } +=
140                             sourcePermissionName
141                     }
142                 }
143             } as IndexedMap<String, IndexedListSet<String>>
144 
145     internal fun onUserAdded(userId: Int) {
146         mutateState { with(policy) { onUserAdded(userId) } }
147     }
148 
149     internal fun onUserRemoved(userId: Int) {
150         mutateState { with(policy) { onUserRemoved(userId) } }
151     }
152 
153     internal fun onStorageVolumeMounted(
154         volumeUuid: String?,
155         packageNames: List<String>,
156         isSystemUpdated: Boolean
157     ) {
158         val (packageStates, disabledSystemPackageStates) = packageManagerLocal.allPackageStates
159         val knownPackages = packageManagerInternal.knownPackages
160         mutateState {
161             with(policy) {
162                 onStorageVolumeMounted(
163                     packageStates,
164                     disabledSystemPackageStates,
165                     knownPackages,
166                     volumeUuid,
167                     packageNames,
168                     isSystemUpdated
169                 )
170             }
171         }
172     }
173 
174     internal fun onPackageAdded(packageName: String) {
175         val (packageStates, disabledSystemPackageStates) = packageManagerLocal.allPackageStates
176         val knownPackages = packageManagerInternal.knownPackages
177         mutateState {
178             with(policy) {
179                 onPackageAdded(
180                     packageStates,
181                     disabledSystemPackageStates,
182                     knownPackages,
183                     packageName
184                 )
185             }
186         }
187     }
188 
189     internal fun onPackageRemoved(packageName: String, appId: Int) {
190         val (packageStates, disabledSystemPackageStates) = packageManagerLocal.allPackageStates
191         val knownPackages = packageManagerInternal.knownPackages
192         mutateState {
193             with(policy) {
194                 onPackageRemoved(
195                     packageStates,
196                     disabledSystemPackageStates,
197                     knownPackages,
198                     packageName,
199                     appId
200                 )
201             }
202         }
203     }
204 
205     internal fun onPackageInstalled(packageName: String, userId: Int) {
206         val (packageStates, disabledSystemPackageStates) = packageManagerLocal.allPackageStates
207         val knownPackages = packageManagerInternal.knownPackages
208         mutateState {
209             with(policy) {
210                 onPackageInstalled(
211                     packageStates,
212                     disabledSystemPackageStates,
213                     knownPackages,
214                     packageName,
215                     userId
216                 )
217             }
218         }
219     }
220 
221     internal fun onPackageUninstalled(packageName: String, appId: Int, userId: Int) {
222         val (packageStates, disabledSystemPackageStates) = packageManagerLocal.allPackageStates
223         val knownPackages = packageManagerInternal.knownPackages
224         mutateState {
225             with(policy) {
226                 onPackageUninstalled(
227                     packageStates,
228                     disabledSystemPackageStates,
229                     knownPackages,
230                     packageName,
231                     appId,
232                     userId
233                 )
234             }
235         }
236     }
237 
238     internal fun onSystemReady() {
239         mutateState { with(policy) { onSystemReady() } }
240     }
241 
242     private val PackageManagerLocal.allPackageStates:
243         Pair<Map<String, PackageState>, Map<String, PackageState>>
244         get() = withUnfilteredSnapshot().use { it.packageStates to it.disabledSystemPackageStates }
245 
246     private val PackageManagerInternal.knownPackages: IntMap<Array<String>>
247         get() =
248             MutableIntMap<Array<String>>().apply {
249                 this[KnownPackages.PACKAGE_INSTALLER] = getKnownPackageNames(
250                     KnownPackages.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM
251                 )
252                 this[KnownPackages.PACKAGE_PERMISSION_CONTROLLER] = getKnownPackageNames(
253                     KnownPackages.PACKAGE_PERMISSION_CONTROLLER, UserHandle.USER_SYSTEM
254                 )
255                 this[KnownPackages.PACKAGE_VERIFIER] = getKnownPackageNames(
256                     KnownPackages.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM
257                 )
258                 this[KnownPackages.PACKAGE_SETUP_WIZARD] = getKnownPackageNames(
259                     KnownPackages.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM
260                 )
261                 this[KnownPackages.PACKAGE_SYSTEM_TEXT_CLASSIFIER] = getKnownPackageNames(
262                     KnownPackages.PACKAGE_SYSTEM_TEXT_CLASSIFIER, UserHandle.USER_SYSTEM
263                 )
264                 this[KnownPackages.PACKAGE_CONFIGURATOR] = getKnownPackageNames(
265                     KnownPackages.PACKAGE_CONFIGURATOR, UserHandle.USER_SYSTEM
266                 )
267                 this[KnownPackages.PACKAGE_INCIDENT_REPORT_APPROVER] = getKnownPackageNames(
268                     KnownPackages.PACKAGE_INCIDENT_REPORT_APPROVER, UserHandle.USER_SYSTEM
269                 )
270                 this[KnownPackages.PACKAGE_APP_PREDICTOR] = getKnownPackageNames(
271                     KnownPackages.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM
272                 )
273                 this[KnownPackages.PACKAGE_COMPANION] = getKnownPackageNames(
274                     KnownPackages.PACKAGE_COMPANION, UserHandle.USER_SYSTEM
275                 )
276                 this[KnownPackages.PACKAGE_RETAIL_DEMO] = getKnownPackageNames(
277                     KnownPackages.PACKAGE_RETAIL_DEMO, UserHandle.USER_SYSTEM
278                 )
279                 this[KnownPackages.PACKAGE_RECENTS] = getKnownPackageNames(
280                     KnownPackages.PACKAGE_RECENTS, UserHandle.USER_SYSTEM
281                 )
282             }
283 
284     @OptIn(ExperimentalContracts::class)
285     internal inline fun <T> getState(action: GetStateScope.() -> T): T {
286         contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
287         return GetStateScope(state).action()
288     }
289 
290     @OptIn(ExperimentalContracts::class)
291     internal inline fun mutateState(crossinline action: MutateStateScope.() -> Unit) {
292         contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
293         synchronized(stateLock) {
294             val oldState = state
295             val newState = oldState.toMutable()
296             MutateStateScope(oldState, newState).action()
297             persistence.write(newState)
298             state = newState
299             with(policy) { GetStateScope(newState).onStateMutated() }
300         }
301     }
302 
303     internal fun getSchemePolicy(subjectScheme: String, objectScheme: String): SchemePolicy =
304         policy.getSchemePolicy(subjectScheme, objectScheme)
305 }
306