diff options
author | 2022-10-18 22:28:05 +0000 | |
---|---|---|
committer | 2022-10-18 22:28:05 +0000 | |
commit | 44d50316437642dd5ed0d096590c60c7d4910531 (patch) | |
tree | 581c5ca2dd680950d150378bc3ce2aedcd14681c | |
parent | c479ec4ca880573d043210a98c7c51708b002750 (diff) | |
parent | 3ad191796dea967c4ad8b2ecfc61470978f0eaca (diff) |
Merge changes I2b934de0,If624419b
* changes:
Throw exception when scheme policy isn't found
AppOps Policy implementation
-rw-r--r-- | service/java/com/android/permission/access/AccessPolicy.kt | 35 | ||||
-rw-r--r-- | service/java/com/android/permission/access/AccessState.kt | 9 | ||||
-rw-r--r-- | service/java/com/android/permission/access/appop/AppOpModes.kt | 27 | ||||
-rw-r--r-- | service/java/com/android/permission/access/appop/BaseAppOpPolicy.kt | 42 | ||||
-rw-r--r-- | service/java/com/android/permission/access/appop/PackageAppOpPolicy.kt | 64 | ||||
-rw-r--r-- | service/java/com/android/permission/access/appop/UidAppOpPolicy.kt | 59 | ||||
-rw-r--r-- | service/java/com/android/permission/access/permission/PermissionFlags.kt (renamed from service/java/com/android/permission/access/AccessDecisions.kt) | 4 | ||||
-rw-r--r-- | service/java/com/android/permission/access/permission/UidPermissionPolicy.kt | 7 |
8 files changed, 223 insertions, 24 deletions
diff --git a/service/java/com/android/permission/access/AccessPolicy.kt b/service/java/com/android/permission/access/AccessPolicy.kt index 9084d5bd0..87d2cb6cd 100644 --- a/service/java/com/android/permission/access/AccessPolicy.kt +++ b/service/java/com/android/permission/access/AccessPolicy.kt @@ -16,6 +16,8 @@ package com.android.permission.access +import com.android.permission.access.appop.PackageAppOpPolicy +import com.android.permission.access.appop.UidAppOpPolicy import com.android.permission.access.external.PackageState import com.android.permission.access.permission.UidPermissionPolicy import com.android.permission.access.util.* // ktlint-disable no-wildcard-imports @@ -25,15 +27,18 @@ class AccessPolicy private constructor( ) { constructor() : this( IndexedMap<String, IndexedMap<String, SchemePolicy>>().apply { - val uidPermissionPolicy = UidPermissionPolicy() - getOrPut(uidPermissionPolicy.subjectScheme) { IndexedMap() } - .put(uidPermissionPolicy.objectScheme, uidPermissionPolicy) + fun addPolicy(policy: SchemePolicy) = + getOrPut(policy.subjectScheme) { IndexedMap() }.put(policy.objectScheme, policy) + + addPolicy(UidPermissionPolicy()) + addPolicy(UidAppOpPolicy()) + addPolicy(PackageAppOpPolicy()) } ) fun getDecision(subject: AccessUri, `object`: AccessUri, state: AccessState): Int { - // TODO: Warn when not found? - val schemePolicy = getSchemePolicy(subject, `object`) ?: return AccessDecisions.DENIED + val schemePolicy = checkNotNull(getSchemePolicy(subject, `object`)) { "Scheme policy for " + + "subject=$subject object=$`object` does not exist."} return schemePolicy.getDecision(subject, `object`, state) } @@ -44,8 +49,8 @@ class AccessPolicy private constructor( oldState: AccessState, newState: AccessState ) { - // TODO: Warn when not found? - val schemePolicy = getSchemePolicy(subject, `object`) ?: return + val schemePolicy = checkNotNull(getSchemePolicy(subject, `object`)) { "Scheme policy for " + + "subject=$subject object=$`object` does not exist."} return schemePolicy.setDecision(subject, `object`, decision, oldState, newState) } @@ -123,23 +128,23 @@ abstract class SchemePolicy { newState: AccessState ) - abstract fun onUserAdded(userId: Int, oldState: AccessState, newState: AccessState) + open fun onUserAdded(userId: Int, oldState: AccessState, newState: AccessState) {} - abstract fun onUserRemoved(userId: Int, oldState: AccessState, newState: AccessState) + open fun onUserRemoved(userId: Int, oldState: AccessState, newState: AccessState) {} - abstract fun onAppIdAdded(appId: Int, oldState: AccessState, newState: AccessState) + open fun onAppIdAdded(appId: Int, oldState: AccessState, newState: AccessState) {} - abstract fun onAppIdRemoved(appId: Int, oldState: AccessState, newState: AccessState) + open fun onAppIdRemoved(appId: Int, oldState: AccessState, newState: AccessState) {} - abstract fun onPackageAdded( + open fun onPackageAdded( packageState: PackageState, oldState: AccessState, newState: AccessState - ) + ) {} - abstract fun onPackageRemoved( + open fun onPackageRemoved( packageState: PackageState, oldState: AccessState, newState: AccessState - ) + ) {} } diff --git a/service/java/com/android/permission/access/AccessState.kt b/service/java/com/android/permission/access/AccessState.kt index 00bc0d677..231d78ee6 100644 --- a/service/java/com/android/permission/access/AccessState.kt +++ b/service/java/com/android/permission/access/AccessState.kt @@ -48,11 +48,14 @@ class SystemState private constructor( } class UserState private constructor( - val permissionFlags: IntMap<IndexedMap<String, Int>> + val permissionFlags: IntMap<IndexedMap<String, Int>>, + val uidAppOpModes: IntMap<IndexedMap<String, Int>>, + val packageAppOpModes: IndexedMap<String, IndexedMap<String, Int>>, ) : WritableState() { - constructor() : this(IntMap()) + constructor() : this(IntMap(), IntMap(), IndexedMap()) - fun copy(): UserState = UserState(permissionFlags.copy { it.copy { it } }) + fun copy(): UserState = UserState(permissionFlags.copy { it.copy { it } }, + uidAppOpModes.copy { it.copy { it } }, packageAppOpModes.copy { it.copy { it } }) } object WriteMode { diff --git a/service/java/com/android/permission/access/appop/AppOpModes.kt b/service/java/com/android/permission/access/appop/AppOpModes.kt new file mode 100644 index 000000000..12f888eac --- /dev/null +++ b/service/java/com/android/permission/access/appop/AppOpModes.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permission.access.appop + +import android.app.AppOpsManager + +object AppOpModes { + const val MODE_ALLOWED = AppOpsManager.MODE_ALLOWED + const val MODE_IGNORED = AppOpsManager.MODE_IGNORED + const val MODE_ERRORED = AppOpsManager.MODE_ERRORED + const val MODE_DEFAULT = AppOpsManager.MODE_DEFAULT + const val MODE_FOREGROUND = AppOpsManager.MODE_FOREGROUND +} diff --git a/service/java/com/android/permission/access/appop/BaseAppOpPolicy.kt b/service/java/com/android/permission/access/appop/BaseAppOpPolicy.kt new file mode 100644 index 000000000..76f0b41af --- /dev/null +++ b/service/java/com/android/permission/access/appop/BaseAppOpPolicy.kt @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permission.access.appop + +import android.app.AppOpsManager +import com.android.permission.access.SchemePolicy +import com.android.permission.access.util.* // ktlint-disable no-wildcard-imports + +abstract class BaseAppOpPolicy : SchemePolicy() { + protected fun getAppOpMode(modes: IndexedMap<String, Int>?, appOpName: String): Int = + modes?.get(appOpName) ?: opToDefaultMode(appOpName) + + protected fun setAppOpMode( + modes: IndexedMap<String, Int>, + appOpName: String, + decision: Int + ) { + if (decision == opToDefaultMode(appOpName)) { + modes -= appOpName + } else { + modes[appOpName] = decision + } + } + + // TODO need to check that [AppOpsManager.getSystemAlertWindowDefault] works; likely no issue + // since running in system process. + private fun opToDefaultMode(appOpName: String) = AppOpsManager.opToDefaultMode(appOpName) +} diff --git a/service/java/com/android/permission/access/appop/PackageAppOpPolicy.kt b/service/java/com/android/permission/access/appop/PackageAppOpPolicy.kt new file mode 100644 index 000000000..4bf50948b --- /dev/null +++ b/service/java/com/android/permission/access/appop/PackageAppOpPolicy.kt @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permission.access.appop + +import com.android.permission.access.AccessState +import com.android.permission.access.AccessUri +import com.android.permission.access.AppOpUri +import com.android.permission.access.PackageUri +import com.android.permission.access.UserState +import com.android.permission.access.external.PackageState +import com.android.permission.access.util.* // ktlint-disable no-wildcard-imports + +class PackageAppOpPolicy : BaseAppOpPolicy() { + override val subjectScheme: String + get() = PackageUri.SCHEME + + override val objectScheme: String + get() = AppOpUri.SCHEME + + override fun getDecision(subject: AccessUri, `object`: AccessUri, state: AccessState): Int { + subject as PackageUri + `object` as AppOpUri + return getAppOpMode(state.userStates[subject.userId] + ?.packageAppOpModes?.get(subject.packageName), `object`.appOpName) + } + + override fun setDecision( + subject: AccessUri, + `object`: AccessUri, + decision: Int, + oldState: AccessState, + newState: AccessState + ) { + subject as PackageUri + `object` as AppOpUri + val modes = newState.userStates.getOrPut(subject.userId) { UserState() } + .packageAppOpModes.getOrPut(subject.packageName) { IndexedMap() } + setAppOpMode(modes, `object`.appOpName, decision) + } + + override fun onPackageRemoved( + packageState: PackageState, + oldState: AccessState, + newState: AccessState + ) { + newState.userStates.forEachIndexed { _, _, userState -> + userState.packageAppOpModes -= packageState.packageName + } + } +} diff --git a/service/java/com/android/permission/access/appop/UidAppOpPolicy.kt b/service/java/com/android/permission/access/appop/UidAppOpPolicy.kt new file mode 100644 index 000000000..cbc1a3200 --- /dev/null +++ b/service/java/com/android/permission/access/appop/UidAppOpPolicy.kt @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permission.access.appop + +import com.android.permission.access.AccessState +import com.android.permission.access.AccessUri +import com.android.permission.access.AppOpUri +import com.android.permission.access.UidUri +import com.android.permission.access.UserState +import com.android.permission.access.util.* // ktlint-disable no-wildcard-imports + +class UidAppOpPolicy : BaseAppOpPolicy() { + override val subjectScheme: String + get() = UidUri.SCHEME + + override val objectScheme: String + get() = AppOpUri.SCHEME + + override fun getDecision(subject: AccessUri, `object`: AccessUri, state: AccessState): Int { + subject as UidUri + `object` as AppOpUri + return getAppOpMode(state.userStates[subject.userId]?.uidAppOpModes + ?.get(subject.appId), `object`.appOpName) + } + + override fun setDecision( + subject: AccessUri, + `object`: AccessUri, + decision: Int, + oldState: AccessState, + newState: AccessState + ) { + subject as UidUri + `object` as AppOpUri + val modes = newState.userStates.getOrPut(subject.userId) { UserState() } + .uidAppOpModes.getOrPut(subject.appId) { IndexedMap() } + setAppOpMode(modes, `object`.appOpName, decision) + } + + override fun onAppIdRemoved(appId: Int, oldState: AccessState, newState: AccessState) { + newState.userStates.forEachIndexed { _, _, userState -> + userState.uidAppOpModes -= appId + } + } +} diff --git a/service/java/com/android/permission/access/AccessDecisions.kt b/service/java/com/android/permission/access/permission/PermissionFlags.kt index 70dd348c8..c6b9eb210 100644 --- a/service/java/com/android/permission/access/AccessDecisions.kt +++ b/service/java/com/android/permission/access/permission/PermissionFlags.kt @@ -14,8 +14,8 @@ * limitations under the License. */ -package com.android.permission.access +package com.android.permission.access.permission -object AccessDecisions { +object PermissionFlags { const val DENIED = 0 } diff --git a/service/java/com/android/permission/access/permission/UidPermissionPolicy.kt b/service/java/com/android/permission/access/permission/UidPermissionPolicy.kt index fb2c2fd87..eb93bd128 100644 --- a/service/java/com/android/permission/access/permission/UidPermissionPolicy.kt +++ b/service/java/com/android/permission/access/permission/UidPermissionPolicy.kt @@ -19,7 +19,6 @@ package com.android.permission.access.permission import android.content.pm.PackageManager import android.content.pm.PermissionInfo import android.util.Log -import com.android.permission.access.AccessDecisions import com.android.permission.access.AccessState import com.android.permission.access.AccessUri import com.android.permission.access.PermissionUri @@ -44,10 +43,10 @@ class UidPermissionPolicy : SchemePolicy() { subject as UidUri `object` as PermissionUri val flags = state.userStates[subject.userId]?.permissionFlags?.get(subject.appId) - ?.get(`object`.permissionName) ?: return AccessDecisions.DENIED + ?.get(`object`.permissionName) ?: return PermissionFlags.DENIED return when (flags) { // TODO - 0 -> AccessDecisions.DENIED + 0 -> PermissionFlags.DENIED else -> error(flags) } } @@ -65,7 +64,7 @@ class UidPermissionPolicy : SchemePolicy() { .permissionFlags.getOrPut(subject.appId) { IndexedMap() } val flags = when (decision) { // TODO - AccessDecisions.DENIED -> 0 + PermissionFlags.DENIED -> 0 else -> error(decision) } uidFlags[`object`.permissionName] = flags |