summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Evan Severson <evanseverson@google.com> 2022-10-18 22:28:05 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-10-18 22:28:05 +0000
commit44d50316437642dd5ed0d096590c60c7d4910531 (patch)
tree581c5ca2dd680950d150378bc3ce2aedcd14681c
parentc479ec4ca880573d043210a98c7c51708b002750 (diff)
parent3ad191796dea967c4ad8b2ecfc61470978f0eaca (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.kt35
-rw-r--r--service/java/com/android/permission/access/AccessState.kt9
-rw-r--r--service/java/com/android/permission/access/appop/AppOpModes.kt27
-rw-r--r--service/java/com/android/permission/access/appop/BaseAppOpPolicy.kt42
-rw-r--r--service/java/com/android/permission/access/appop/PackageAppOpPolicy.kt64
-rw-r--r--service/java/com/android/permission/access/appop/UidAppOpPolicy.kt59
-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.kt7
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