Merge "Add ModernPermissionManagerServiceImpl skeleton and two methods."
This commit is contained in:
@@ -467,7 +467,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
|
||||
@Override
|
||||
public PermissionInfo getPermissionInfo(String permissionName, String packageName, int flags) {
|
||||
return mPermissionManagerServiceImpl.getPermissionInfo(permissionName, packageName, flags);
|
||||
return mPermissionManagerServiceImpl.getPermissionInfo(permissionName, flags, packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -792,14 +792,14 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<PermissionInfo> getAllPermissionsWithProtection(
|
||||
public List<PermissionInfo> getAllPermissionsWithProtection(
|
||||
@PermissionInfo.Protection int protection) {
|
||||
return mPermissionManagerServiceImpl.getAllPermissionsWithProtection(protection);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<PermissionInfo> getAllPermissionsWithProtectionFlags(
|
||||
public List<PermissionInfo> getAllPermissionsWithProtectionFlags(
|
||||
@PermissionInfo.ProtectionFlags int protectionFlags) {
|
||||
return mPermissionManagerServiceImpl
|
||||
.getAllPermissionsWithProtectionFlags(protectionFlags);
|
||||
|
||||
@@ -559,8 +559,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PermissionInfo getPermissionInfo(@NonNull String permName, @NonNull String opPackageName,
|
||||
@PackageManager.PermissionInfoFlags int flags) {
|
||||
public PermissionInfo getPermissionInfo(@NonNull String permName,
|
||||
@PackageManager.PermissionInfoFlags int flags, @NonNull String opPackageName) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
|
||||
return null;
|
||||
@@ -2127,7 +2127,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
|
||||
for (int i = 0; i < numRequestedPermissions; i++) {
|
||||
PermissionInfo permInfo = getPermissionInfo(
|
||||
newPackage.getRequestedPermissions().get(i),
|
||||
newPackage.getPackageName(), 0);
|
||||
0, newPackage.getPackageName());
|
||||
if (permInfo == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -5204,9 +5204,9 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<PermissionInfo> getAllPermissionsWithProtection(
|
||||
public List<PermissionInfo> getAllPermissionsWithProtection(
|
||||
@PermissionInfo.Protection int protection) {
|
||||
ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
|
||||
List<PermissionInfo> matchingPermissions = new ArrayList<>();
|
||||
|
||||
synchronized (mLock) {
|
||||
for (final Permission permission : mRegistry.getPermissions()) {
|
||||
@@ -5221,9 +5221,9 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<PermissionInfo> getAllPermissionsWithProtectionFlags(
|
||||
public List<PermissionInfo> getAllPermissionsWithProtectionFlags(
|
||||
@PermissionInfo.ProtectionFlags int protectionFlags) {
|
||||
ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
|
||||
List<PermissionInfo> matchingPermissions = new ArrayList<>();
|
||||
|
||||
synchronized (mLock) {
|
||||
for (final Permission permission : mRegistry.getPermissions()) {
|
||||
|
||||
@@ -32,7 +32,6 @@ import com.android.server.pm.pkg.AndroidPackage;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -77,8 +76,8 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte
|
||||
* @return a {@link PermissionInfo} containing information about the permission, or {@code null}
|
||||
* if not found
|
||||
*/
|
||||
PermissionInfo getPermissionInfo(@NonNull String permName, @NonNull String opPackageName,
|
||||
@PackageManager.PermissionInfoFlags int flags);
|
||||
PermissionInfo getPermissionInfo(@NonNull String permName,
|
||||
@PackageManager.PermissionInfoFlags int flags, @NonNull String opPackageName);
|
||||
|
||||
/**
|
||||
* Query for all of the permissions associated with a particular group.
|
||||
@@ -487,11 +486,11 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte
|
||||
|
||||
/** Get all permissions that have a certain protection */
|
||||
@NonNull
|
||||
ArrayList<PermissionInfo> getAllPermissionsWithProtection(
|
||||
List<PermissionInfo> getAllPermissionsWithProtection(
|
||||
@PermissionInfo.Protection int protection);
|
||||
|
||||
/** Get all permissions that have certain protection flags */
|
||||
@NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtectionFlags(
|
||||
@NonNull List<PermissionInfo> getAllPermissionsWithProtectionFlags(
|
||||
@PermissionInfo.ProtectionFlags int protectionFlags);
|
||||
|
||||
/**
|
||||
|
||||
@@ -164,11 +164,12 @@ public interface PermissionManagerServiceInternal extends PermissionManagerInter
|
||||
|
||||
/** Get all permissions that have a certain protection */
|
||||
@NonNull
|
||||
ArrayList<PermissionInfo> getAllPermissionsWithProtection(
|
||||
List<PermissionInfo> getAllPermissionsWithProtection(
|
||||
@PermissionInfo.Protection int protection);
|
||||
|
||||
/** Get all permissions that have certain protection flags */
|
||||
@NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtectionFlags(
|
||||
/** Get all permissions that have certain protection flags
|
||||
* @return*/
|
||||
@NonNull List<PermissionInfo> getAllPermissionsWithProtectionFlags(
|
||||
@PermissionInfo.ProtectionFlags int protectionFlags);
|
||||
|
||||
/**
|
||||
|
||||
@@ -232,7 +232,7 @@ public final class PermissionPolicyService extends SystemService {
|
||||
}
|
||||
};
|
||||
|
||||
final ArrayList<PermissionInfo> dangerousPerms =
|
||||
final List<PermissionInfo> dangerousPerms =
|
||||
mPermissionManagerInternal.getAllPermissionsWithProtection(
|
||||
PermissionInfo.PROTECTION_DANGEROUS);
|
||||
try {
|
||||
|
||||
@@ -29,6 +29,8 @@ java_library_static {
|
||||
],
|
||||
static_libs: [
|
||||
"kotlin-stdlib",
|
||||
// Adds reflection-less suppressed exceptions and AutoCloseable.use().
|
||||
"kotlin-stdlib-jdk7",
|
||||
],
|
||||
jarjar_rules: "jarjar-rules.txt",
|
||||
kotlincflags: [
|
||||
|
||||
@@ -40,46 +40,53 @@ class AccessCheckingService {
|
||||
}
|
||||
|
||||
fun getDecision(subject: AccessUri, `object`: AccessUri): Int =
|
||||
policy.getDecision(subject, `object`, state)
|
||||
getState {
|
||||
with(policy) { getDecision(subject, `object`) }
|
||||
}
|
||||
|
||||
fun setDecision(subject: AccessUri, `object`: AccessUri, decision: Int) {
|
||||
mutateState { oldState, newState ->
|
||||
policy.setDecision(subject, `object`, decision, oldState, newState)
|
||||
mutateState {
|
||||
with(policy) { setDecision(subject, `object`, decision) }
|
||||
}
|
||||
}
|
||||
|
||||
fun onUserAdded(userId: Int) {
|
||||
mutateState { oldState, newState ->
|
||||
policy.onUserAdded(userId, oldState, newState)
|
||||
mutateState {
|
||||
with(policy) { onUserAdded(userId) }
|
||||
}
|
||||
}
|
||||
|
||||
fun onUserRemoved(userId: Int) {
|
||||
mutateState { oldState, newState ->
|
||||
policy.onUserRemoved(userId, oldState, newState)
|
||||
mutateState {
|
||||
with(policy) { onUserRemoved(userId) }
|
||||
}
|
||||
}
|
||||
|
||||
fun onPackageAdded(packageState: PackageState) {
|
||||
mutateState { oldState, newState ->
|
||||
policy.onPackageAdded(packageState, oldState, newState)
|
||||
mutateState {
|
||||
with(policy) { onPackageAdded(packageState) }
|
||||
}
|
||||
}
|
||||
|
||||
fun onPackageRemoved(packageState: PackageState) {
|
||||
mutateState { oldState, newState ->
|
||||
policy.onPackageRemoved(packageState, oldState, newState)
|
||||
mutateState {
|
||||
with(policy) { onPackageRemoved(packageState) }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Replace (oldState, newState) with Kotlin context receiver once it's stabilized.
|
||||
private inline fun mutateState(action: (oldState: AccessState, newState: AccessState) -> Unit) {
|
||||
internal inline fun <T> getState(action: GetStateScope.() -> T): T =
|
||||
GetStateScope(state).action()
|
||||
|
||||
internal inline fun mutateState(action: MutateStateScope.() -> Unit) {
|
||||
synchronized(stateLock) {
|
||||
val oldState = state
|
||||
val newState = oldState.copy()
|
||||
action(oldState, newState)
|
||||
MutateStateScope(oldState, newState).action()
|
||||
persistence.write(newState)
|
||||
state = newState
|
||||
}
|
||||
}
|
||||
|
||||
internal fun getSchemePolicy(subjectScheme: String, objectScheme: String): SchemePolicy =
|
||||
policy.getSchemePolicy(subjectScheme, objectScheme)
|
||||
}
|
||||
|
||||
@@ -44,13 +44,13 @@ class AccessPersistence(
|
||||
systemFile.parse {
|
||||
// This is the canonical way to call an extension function in a different class.
|
||||
// TODO(b/259469752): Use context receiver for this when it becomes stable.
|
||||
with(policy) { this@parse.parseSystemState(systemState) }
|
||||
with(policy) { parseSystemState(systemState) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun readUserState(userId: Int, userState: UserState) {
|
||||
getUserFile(userId).parse {
|
||||
with(policy) { this@parse.parseUserState(userId, userState) }
|
||||
with(policy) { parseUserState(userId, userState) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,13 +82,13 @@ class AccessPersistence(
|
||||
|
||||
private fun writeSystemState(systemState: SystemState) {
|
||||
systemFile.serialize {
|
||||
with(policy) { this@serialize.serializeSystemState(systemState) }
|
||||
with(policy) { serializeSystemState(systemState) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun writeUserState(userId: Int, userState: UserState) {
|
||||
getUserFile(userId).serialize {
|
||||
with(policy) { this@serialize.serializeUserState(userId, userState) }
|
||||
with(policy) { serializeUserState(userId, userState) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,38 +41,35 @@ class AccessPolicy private constructor(
|
||||
}
|
||||
)
|
||||
|
||||
fun getDecision(subject: AccessUri, `object`: AccessUri, state: AccessState): Int =
|
||||
getSchemePolicy(subject, `object`).getDecision(subject, `object`, state)
|
||||
|
||||
fun setDecision(
|
||||
subject: AccessUri,
|
||||
`object`: AccessUri,
|
||||
decision: Int,
|
||||
oldState: AccessState,
|
||||
newState: AccessState
|
||||
) {
|
||||
getSchemePolicy(subject, `object`)
|
||||
.setDecision(subject, `object`, decision, oldState, newState)
|
||||
}
|
||||
|
||||
private fun getSchemePolicy(subject: AccessUri, `object`: AccessUri): SchemePolicy =
|
||||
checkNotNull(schemePolicies[subject.scheme]?.get(`object`.scheme)) {
|
||||
"Scheme policy for subject=$subject object=$`object` does not exist"
|
||||
fun getSchemePolicy(subjectScheme: String, objectScheme: String): SchemePolicy =
|
||||
checkNotNull(schemePolicies[subjectScheme]?.get(objectScheme)) {
|
||||
"Scheme policy for $subjectScheme and $objectScheme does not exist"
|
||||
}
|
||||
|
||||
fun onUserAdded(userId: Int, oldState: AccessState, newState: AccessState) {
|
||||
fun GetStateScope.getDecision(subject: AccessUri, `object`: AccessUri): Int =
|
||||
with(getSchemePolicy(subject, `object`)){ getDecision(subject, `object`) }
|
||||
|
||||
fun MutateStateScope.setDecision(subject: AccessUri, `object`: AccessUri, decision: Int) {
|
||||
with(getSchemePolicy(subject, `object`)) { setDecision(subject, `object`, decision) }
|
||||
}
|
||||
|
||||
fun MutateStateScope.onUserAdded(userId: Int) {
|
||||
newState.systemState.userIds += userId
|
||||
newState.userStates[userId] = UserState()
|
||||
forEachSchemePolicy { it.onUserAdded(userId, oldState, newState) }
|
||||
forEachSchemePolicy {
|
||||
with(it) { onUserAdded(userId) }
|
||||
}
|
||||
}
|
||||
|
||||
fun onUserRemoved(userId: Int, oldState: AccessState, newState: AccessState) {
|
||||
fun MutateStateScope.onUserRemoved(userId: Int) {
|
||||
newState.systemState.userIds -= userId
|
||||
newState.userStates -= userId
|
||||
forEachSchemePolicy { it.onUserRemoved(userId, oldState, newState) }
|
||||
forEachSchemePolicy {
|
||||
with(it) { onUserRemoved(userId) }
|
||||
}
|
||||
}
|
||||
|
||||
fun onPackageAdded(packageState: PackageState, oldState: AccessState, newState: AccessState) {
|
||||
fun MutateStateScope.onPackageAdded(packageState: PackageState) {
|
||||
var isAppIdAdded = false
|
||||
newState.systemState.apply {
|
||||
packageStates[packageState.packageName] = packageState
|
||||
@@ -82,12 +79,16 @@ class AccessPolicy private constructor(
|
||||
}.add(packageState.packageName)
|
||||
}
|
||||
if (isAppIdAdded) {
|
||||
forEachSchemePolicy { it.onAppIdAdded(packageState.appId, oldState, newState) }
|
||||
forEachSchemePolicy {
|
||||
with(it) { onAppIdAdded(packageState.appId) }
|
||||
}
|
||||
}
|
||||
forEachSchemePolicy {
|
||||
with(it) { onPackageAdded(packageState) }
|
||||
}
|
||||
forEachSchemePolicy { it.onPackageAdded(packageState, oldState, newState) }
|
||||
}
|
||||
|
||||
fun onPackageRemoved(packageState: PackageState, oldState: AccessState, newState: AccessState) {
|
||||
fun MutateStateScope.onPackageRemoved(packageState: PackageState) {
|
||||
var isAppIdRemoved = false
|
||||
newState.systemState.apply {
|
||||
packageStates -= packageState.packageName
|
||||
@@ -101,9 +102,13 @@ class AccessPolicy private constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
forEachSchemePolicy { it.onPackageRemoved(packageState, oldState, newState) }
|
||||
forEachSchemePolicy {
|
||||
with(it) { onPackageRemoved(packageState) }
|
||||
}
|
||||
if (isAppIdRemoved) {
|
||||
forEachSchemePolicy { it.onAppIdRemoved(packageState.appId, oldState, newState) }
|
||||
forEachSchemePolicy {
|
||||
with(it) { onAppIdRemoved(packageState.appId) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +118,7 @@ class AccessPolicy private constructor(
|
||||
TAG_ACCESS -> {
|
||||
forEachTag {
|
||||
forEachSchemePolicy {
|
||||
with(it) { this@parseSystemState.parseSystemState(systemState) }
|
||||
with(it) { parseSystemState(systemState) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,7 +130,7 @@ class AccessPolicy private constructor(
|
||||
fun BinaryXmlSerializer.serializeSystemState(systemState: SystemState) {
|
||||
tag(TAG_ACCESS) {
|
||||
forEachSchemePolicy {
|
||||
with(it) { this@serializeSystemState.serializeSystemState(systemState) }
|
||||
with(it) { serializeSystemState(systemState) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,7 +141,7 @@ class AccessPolicy private constructor(
|
||||
TAG_ACCESS -> {
|
||||
forEachTag {
|
||||
forEachSchemePolicy {
|
||||
with(it) { this@parseUserState.parseUserState(userId, userState) }
|
||||
with(it) { parseUserState(userId, userState) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,11 +158,14 @@ class AccessPolicy private constructor(
|
||||
fun BinaryXmlSerializer.serializeUserState(userId: Int, userState: UserState) {
|
||||
tag(TAG_ACCESS) {
|
||||
forEachSchemePolicy {
|
||||
with(it) { this@serializeUserState.serializeUserState(userId, userState) }
|
||||
with(it) { serializeUserState(userId, userState) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSchemePolicy(subject: AccessUri, `object`: AccessUri): SchemePolicy =
|
||||
getSchemePolicy(subject.scheme, `object`.scheme)
|
||||
|
||||
private inline fun forEachSchemePolicy(action: (SchemePolicy) -> Unit) {
|
||||
schemePolicies.forEachValueIndexed { _, objectSchemePolicies ->
|
||||
objectSchemePolicies.forEachValueIndexed { _, schemePolicy ->
|
||||
@@ -182,14 +190,12 @@ abstract class SchemePolicy {
|
||||
|
||||
abstract val objectScheme: String
|
||||
|
||||
abstract fun getDecision(subject: AccessUri, `object`: AccessUri, state: AccessState): Int
|
||||
abstract fun GetStateScope.getDecision(subject: AccessUri, `object`: AccessUri): Int
|
||||
|
||||
abstract fun setDecision(
|
||||
abstract fun MutateStateScope.setDecision(
|
||||
subject: AccessUri,
|
||||
`object`: AccessUri,
|
||||
decision: Int,
|
||||
oldState: AccessState,
|
||||
newState: AccessState
|
||||
decision: Int
|
||||
)
|
||||
|
||||
fun addOnDecisionChangedListener(listener: OnDecisionChangedListener) {
|
||||
@@ -216,25 +222,17 @@ abstract class SchemePolicy {
|
||||
}
|
||||
}
|
||||
|
||||
open fun onUserAdded(userId: Int, oldState: AccessState, newState: AccessState) {}
|
||||
open fun MutateStateScope.onUserAdded(userId: Int) {}
|
||||
|
||||
open fun onUserRemoved(userId: Int, oldState: AccessState, newState: AccessState) {}
|
||||
open fun MutateStateScope.onUserRemoved(userId: Int) {}
|
||||
|
||||
open fun onAppIdAdded(appId: Int, oldState: AccessState, newState: AccessState) {}
|
||||
open fun MutateStateScope.onAppIdAdded(appId: Int) {}
|
||||
|
||||
open fun onAppIdRemoved(appId: Int, oldState: AccessState, newState: AccessState) {}
|
||||
open fun MutateStateScope.onAppIdRemoved(appId: Int) {}
|
||||
|
||||
open fun onPackageAdded(
|
||||
packageState: PackageState,
|
||||
oldState: AccessState,
|
||||
newState: AccessState
|
||||
) {}
|
||||
open fun MutateStateScope.onPackageAdded(packageState: PackageState) {}
|
||||
|
||||
open fun onPackageRemoved(
|
||||
packageState: PackageState,
|
||||
oldState: AccessState,
|
||||
newState: AccessState
|
||||
) {}
|
||||
open fun MutateStateScope.onPackageRemoved(packageState: PackageState) {}
|
||||
|
||||
open fun BinaryXmlPullParser.parseSystemState(systemState: SystemState) {}
|
||||
|
||||
|
||||
@@ -124,3 +124,12 @@ abstract class WritableState {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GetStateScope(
|
||||
val state: AccessState
|
||||
)
|
||||
|
||||
class MutateStateScope(
|
||||
val oldState: AccessState,
|
||||
val newState: AccessState
|
||||
)
|
||||
|
||||
@@ -19,44 +19,43 @@ package com.android.server.permission.access.appop
|
||||
import android.app.AppOpsManager
|
||||
import com.android.modules.utils.BinaryXmlPullParser
|
||||
import com.android.modules.utils.BinaryXmlSerializer
|
||||
import com.android.server.permission.access.AccessState
|
||||
import com.android.server.permission.access.AccessUri
|
||||
import com.android.server.permission.access.AppOpUri
|
||||
import com.android.server.permission.access.GetStateScope
|
||||
import com.android.server.permission.access.MutateStateScope
|
||||
import com.android.server.permission.access.SchemePolicy
|
||||
import com.android.server.permission.access.UserState
|
||||
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
|
||||
|
||||
abstract class BaseAppOpPolicy(private val persistence: BaseAppOpPersistence) : SchemePolicy() {
|
||||
override fun getDecision(subject: AccessUri, `object`: AccessUri, state: AccessState): Int {
|
||||
override fun GetStateScope.getDecision(subject: AccessUri, `object`: AccessUri): Int {
|
||||
`object` as AppOpUri
|
||||
return getModes(subject, state)
|
||||
return getModes(subject)
|
||||
.getWithDefault(`object`.appOpName, opToDefaultMode(`object`.appOpName))
|
||||
}
|
||||
|
||||
override fun setDecision(
|
||||
override fun MutateStateScope.setDecision(
|
||||
subject: AccessUri,
|
||||
`object`: AccessUri,
|
||||
decision: Int,
|
||||
oldState: AccessState,
|
||||
newState: AccessState
|
||||
decision: Int
|
||||
) {
|
||||
`object` as AppOpUri
|
||||
val modes = getOrCreateModes(subject, newState)
|
||||
val modes = getOrCreateModes(subject)
|
||||
val oldMode = modes.putWithDefault(`object`.appOpName, decision,
|
||||
opToDefaultMode(`object`.appOpName))
|
||||
if (modes.isEmpty()) {
|
||||
removeModes(subject, newState)
|
||||
removeModes(subject)
|
||||
}
|
||||
if (oldMode != decision) {
|
||||
notifyOnDecisionChangedListeners(subject, `object`, oldMode, decision)
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun getModes(subject: AccessUri, state: AccessState): IndexedMap<String, Int>?
|
||||
abstract fun GetStateScope.getModes(subject: AccessUri): IndexedMap<String, Int>?
|
||||
|
||||
abstract fun getOrCreateModes(subject: AccessUri, state: AccessState): IndexedMap<String, Int>
|
||||
abstract fun MutateStateScope.getOrCreateModes(subject: AccessUri): IndexedMap<String, Int>
|
||||
|
||||
abstract fun removeModes(subject: AccessUri, state: AccessState)
|
||||
abstract fun MutateStateScope.removeModes(subject: AccessUri)
|
||||
|
||||
// TODO need to check that [AppOpsManager.getSystemAlertWindowDefault] works; likely no issue
|
||||
// since running in system process.
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
|
||||
package com.android.server.permission.access.appop
|
||||
|
||||
import com.android.server.permission.access.AccessState
|
||||
import com.android.server.permission.access.AccessUri
|
||||
import com.android.server.permission.access.AppOpUri
|
||||
import com.android.server.permission.access.GetStateScope
|
||||
import com.android.server.permission.access.MutateStateScope
|
||||
import com.android.server.permission.access.PackageUri
|
||||
import com.android.server.permission.access.UserState
|
||||
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
|
||||
@@ -31,27 +32,23 @@ class PackageAppOpPolicy : BaseAppOpPolicy(PackageAppOpPersistence()) {
|
||||
override val objectScheme: String
|
||||
get() = AppOpUri.SCHEME
|
||||
|
||||
override fun getModes(subject: AccessUri, state: AccessState): IndexedMap<String, Int>? {
|
||||
override fun GetStateScope.getModes(subject: AccessUri): IndexedMap<String, Int>? {
|
||||
subject as PackageUri
|
||||
return state.userStates[subject.userId]?.packageAppOpModes?.get(subject.packageName)
|
||||
}
|
||||
|
||||
override fun getOrCreateModes(subject: AccessUri, state: AccessState): IndexedMap<String, Int> {
|
||||
override fun MutateStateScope.getOrCreateModes(subject: AccessUri): IndexedMap<String, Int> {
|
||||
subject as PackageUri
|
||||
return state.userStates.getOrPut(subject.userId) { UserState() }
|
||||
return newState.userStates.getOrPut(subject.userId) { UserState() }
|
||||
.packageAppOpModes.getOrPut(subject.packageName) { IndexedMap() }
|
||||
}
|
||||
|
||||
override fun removeModes(subject: AccessUri, state: AccessState) {
|
||||
override fun MutateStateScope.removeModes(subject: AccessUri) {
|
||||
subject as PackageUri
|
||||
state.userStates[subject.userId]?.packageAppOpModes?.remove(subject.packageName)
|
||||
newState.userStates[subject.userId]?.packageAppOpModes?.remove(subject.packageName)
|
||||
}
|
||||
|
||||
override fun onPackageRemoved(
|
||||
packageState: PackageState,
|
||||
oldState: AccessState,
|
||||
newState: AccessState
|
||||
) {
|
||||
override fun MutateStateScope.onPackageRemoved(packageState: PackageState) {
|
||||
newState.userStates.forEachIndexed { _, _, userState ->
|
||||
userState.packageAppOpModes -= packageState.packageName
|
||||
}
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
|
||||
package com.android.server.permission.access.appop
|
||||
|
||||
import com.android.server.permission.access.AccessState
|
||||
import com.android.server.permission.access.AccessUri
|
||||
import com.android.server.permission.access.AppOpUri
|
||||
import com.android.server.permission.access.GetStateScope
|
||||
import com.android.server.permission.access.MutateStateScope
|
||||
import com.android.server.permission.access.UidUri
|
||||
import com.android.server.permission.access.UserState
|
||||
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
|
||||
@@ -30,23 +31,23 @@ class UidAppOpPolicy : BaseAppOpPolicy(UidAppOpPersistence()) {
|
||||
override val objectScheme: String
|
||||
get() = AppOpUri.SCHEME
|
||||
|
||||
override fun getModes(subject: AccessUri, state: AccessState): IndexedMap<String, Int>? {
|
||||
override fun GetStateScope.getModes(subject: AccessUri): IndexedMap<String, Int>? {
|
||||
subject as UidUri
|
||||
return state.userStates[subject.userId]?.uidAppOpModes?.get(subject.appId)
|
||||
}
|
||||
|
||||
override fun getOrCreateModes(subject: AccessUri, state: AccessState): IndexedMap<String, Int> {
|
||||
override fun MutateStateScope.getOrCreateModes(subject: AccessUri): IndexedMap<String, Int> {
|
||||
subject as UidUri
|
||||
return state.userStates.getOrPut(subject.userId) { UserState() }
|
||||
return newState.userStates.getOrPut(subject.userId) { UserState() }
|
||||
.uidAppOpModes.getOrPut(subject.appId) { IndexedMap() }
|
||||
}
|
||||
|
||||
override fun removeModes(subject: AccessUri, state: AccessState) {
|
||||
override fun MutateStateScope.removeModes(subject: AccessUri) {
|
||||
subject as UidUri
|
||||
state.userStates[subject.userId]?.uidAppOpModes?.remove(subject.appId)
|
||||
newState.userStates[subject.userId]?.uidAppOpModes?.remove(subject.appId)
|
||||
}
|
||||
|
||||
override fun onAppIdRemoved(appId: Int, oldState: AccessState, newState: AccessState) {
|
||||
override fun MutateStateScope.onAppIdRemoved(appId: Int) {
|
||||
newState.userStates.forEachIndexed { _, _, userState ->
|
||||
userState.uidAppOpModes -= appId
|
||||
}
|
||||
|
||||
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
* 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.server.permission.access.permission
|
||||
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.PackageManagerInternal
|
||||
import android.content.pm.PermissionGroupInfo
|
||||
import android.content.pm.PermissionInfo
|
||||
import android.content.pm.permission.SplitPermissionInfoParcelable
|
||||
import android.os.Binder
|
||||
import android.os.Build
|
||||
import android.os.Process
|
||||
import android.os.UserHandle
|
||||
import android.permission.IOnPermissionsChangeListener
|
||||
import com.android.server.LocalManagerRegistry
|
||||
import com.android.server.LocalServices
|
||||
import com.android.server.pm.PackageManagerLocal
|
||||
import com.android.server.pm.permission.PermissionManagerServiceInterface
|
||||
import com.android.server.permission.access.AccessCheckingService
|
||||
import com.android.server.permission.access.PermissionUri
|
||||
import com.android.server.permission.access.UidUri
|
||||
import com.android.server.permission.access.data.Permission
|
||||
import com.android.server.permission.access.util.hasBits
|
||||
import com.android.server.pm.permission.LegacyPermission
|
||||
import com.android.server.pm.permission.LegacyPermissionSettings
|
||||
import com.android.server.pm.permission.LegacyPermissionState
|
||||
import com.android.server.pm.permission.PermissionManagerServiceInternal
|
||||
import com.android.server.pm.pkg.AndroidPackage
|
||||
import java.io.FileDescriptor
|
||||
import java.io.PrintWriter
|
||||
|
||||
/**
|
||||
* Modern implementation of [PermissionManagerServiceInterface].
|
||||
*/
|
||||
class ModernPermissionManagerServiceImpl(
|
||||
private val service: AccessCheckingService
|
||||
) : PermissionManagerServiceInterface {
|
||||
private val policy =
|
||||
service.getSchemePolicy(UidUri.SCHEME, PermissionUri.SCHEME) as UidPermissionPolicy
|
||||
|
||||
private val packageManagerInternal =
|
||||
LocalServices.getService(PackageManagerInternal::class.java)
|
||||
|
||||
private val packageManagerLocal =
|
||||
LocalManagerRegistry.getManagerOrThrow(PackageManagerLocal::class.java)
|
||||
|
||||
override fun getAllPermissionGroups(flags: Int): List<PermissionGroupInfo> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getPermissionGroupInfo(
|
||||
permissionGroupName: String,
|
||||
flags: Int
|
||||
): PermissionGroupInfo? {
|
||||
val permissionGroup: PermissionGroupInfo
|
||||
packageManagerLocal.withUnfilteredSnapshot().use { snapshot ->
|
||||
val callingUid = Binder.getCallingUid()
|
||||
if (snapshot.isUidInstantApp(callingUid)) {
|
||||
return null
|
||||
}
|
||||
|
||||
permissionGroup = service.getState {
|
||||
with(policy) { getPermissionGroup(permissionGroupName) }
|
||||
} ?: return null
|
||||
|
||||
val isPermissionGroupVisible =
|
||||
snapshot.isPackageVisibleToUid(permissionGroup.packageName, callingUid)
|
||||
if (!isPermissionGroupVisible) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
return permissionGroup.generatePermissionGroupInfo(flags)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new [PermissionGroupInfo] from [PermissionGroupInfo] and adjust it accordingly.
|
||||
*/
|
||||
private fun PermissionGroupInfo.generatePermissionGroupInfo(flags: Int): PermissionGroupInfo =
|
||||
@Suppress("DEPRECATION")
|
||||
PermissionGroupInfo(this).apply {
|
||||
if (!flags.hasBits(PackageManager.GET_META_DATA)) {
|
||||
metaData = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPermissionInfo(
|
||||
permissionName: String,
|
||||
flags: Int,
|
||||
opPackageName: String
|
||||
): PermissionInfo? {
|
||||
val permission: Permission
|
||||
val targetSdkVersion: Int
|
||||
packageManagerLocal.withUnfilteredSnapshot().use { snapshot ->
|
||||
val callingUid = Binder.getCallingUid()
|
||||
if (snapshot.isUidInstantApp(callingUid)) {
|
||||
return null
|
||||
}
|
||||
|
||||
permission = service.getState {
|
||||
with(policy) { getPermission(permissionName) }
|
||||
} ?: return null
|
||||
|
||||
val isPermissionVisible =
|
||||
snapshot.isPackageVisibleToUid(permission.packageName, callingUid)
|
||||
if (!isPermissionVisible) {
|
||||
return null
|
||||
}
|
||||
|
||||
val callingAppId = UserHandle.getAppId(callingUid)
|
||||
val opPackage = snapshot.packageStates[opPackageName]?.androidPackage
|
||||
targetSdkVersion = when {
|
||||
// System sees all flags.
|
||||
callingAppId == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID ||
|
||||
callingAppId == Process.SHELL_UID -> Build.VERSION_CODES.CUR_DEVELOPMENT
|
||||
opPackage != null -> opPackage.targetSdkVersion
|
||||
else -> Build.VERSION_CODES.CUR_DEVELOPMENT
|
||||
}
|
||||
}
|
||||
|
||||
return permission.generatePermissionInfo(flags, targetSdkVersion)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new [PermissionInfo] from [Permission] and adjust it accordingly.
|
||||
*/
|
||||
private fun Permission.generatePermissionInfo(
|
||||
flags: Int,
|
||||
targetSdkVersion: Int
|
||||
): PermissionInfo =
|
||||
@Suppress("DEPRECATION")
|
||||
PermissionInfo(permissionInfo).apply {
|
||||
if (!flags.hasBits(PackageManager.GET_META_DATA)) {
|
||||
metaData = null
|
||||
}
|
||||
if (targetSdkVersion < Build.VERSION_CODES.O) {
|
||||
val protection = protection
|
||||
// Signature permission's protection flags are always reported.
|
||||
if (protection != PermissionInfo.PROTECTION_SIGNATURE) {
|
||||
protectionLevel = protection
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun queryPermissionsByGroup(
|
||||
permissionGroupName: String,
|
||||
flags: Int
|
||||
): List<PermissionInfo> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getAllPermissionsWithProtection(protection: Int): List<PermissionInfo> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getAllPermissionsWithProtectionFlags(protectionFlags: Int): List<PermissionInfo> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getPermissionGids(permissionName: String, userId: Int): IntArray {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun addPermission(permissionInfo: PermissionInfo, async: Boolean): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun removePermission(permissionName: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun checkPermission(packageName: String, permissionName: String, userId: Int): Int {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun checkUidPermission(uid: Int, permissionName: String): Int {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getGrantedPermissions(packageName: String, userId: Int): Set<String> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun grantRuntimePermission(packageName: String, permissionName: String, userId: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun revokeRuntimePermission(
|
||||
packageName: String,
|
||||
permissionName: String,
|
||||
userId: Int,
|
||||
reason: String?
|
||||
) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun revokePostNotificationPermissionWithoutKillForTest(
|
||||
packageName: String,
|
||||
userId: Int
|
||||
) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun addOnPermissionsChangeListener(listener: IOnPermissionsChangeListener) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun removeOnPermissionsChangeListener(listener: IOnPermissionsChangeListener) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getPermissionFlags(packageName: String, permissionName: String, userId: Int): Int {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun isPermissionRevokedByPolicy(
|
||||
packageName: String,
|
||||
permissionName: String,
|
||||
userId: Int
|
||||
): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun isPermissionsReviewRequired(packageName: String, userId: Int): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun shouldShowRequestPermissionRationale(
|
||||
packageName: String,
|
||||
permissionName: String,
|
||||
userId: Int
|
||||
): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun updatePermissionFlags(
|
||||
packageName: String,
|
||||
permissionName: String,
|
||||
flagMask: Int,
|
||||
flagValues: Int,
|
||||
checkAdjustPolicyFlagPermission: Boolean,
|
||||
userId: Int
|
||||
) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun updatePermissionFlagsForAllApps(flagMask: Int, flagValues: Int, userId: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun addAllowlistedRestrictedPermission(
|
||||
packageName: String,
|
||||
permissionName: String,
|
||||
flags: Int,
|
||||
userId: Int
|
||||
): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getAllowlistedRestrictedPermissions(
|
||||
packageName: String,
|
||||
flags: Int,
|
||||
userId: Int
|
||||
): MutableList<String> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun removeAllowlistedRestrictedPermission(
|
||||
packageName: String,
|
||||
permissionName: String,
|
||||
flags: Int,
|
||||
userId: Int
|
||||
): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun resetRuntimePermissions(androidPackage: AndroidPackage, userId: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun resetRuntimePermissionsForUser(userId: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun addOnRuntimePermissionStateChangedListener(
|
||||
listener: PermissionManagerServiceInternal.OnRuntimePermissionStateChangedListener
|
||||
) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun removeOnRuntimePermissionStateChangedListener(
|
||||
listener: PermissionManagerServiceInternal.OnRuntimePermissionStateChangedListener
|
||||
) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getSplitPermissions(): List<SplitPermissionInfoParcelable> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getAppOpPermissionPackages(permissionName: String): Array<String> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getAllAppOpPermissionPackages(): Map<String, Set<String>> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getGidsForUid(uid: Int): IntArray {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun backupRuntimePermissions(userId: Int): ByteArray? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun restoreRuntimePermissions(backup: ByteArray, userId: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun restoreDelayedRuntimePermissions(packageName: String, userId: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>?) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getPermissionTEMP(
|
||||
permissionName: String
|
||||
): com.android.server.pm.permission.Permission? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getLegacyPermissions(): List<LegacyPermission> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun readLegacyPermissionsTEMP(legacyPermissionSettings: LegacyPermissionSettings) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun writeLegacyPermissionsTEMP(legacyPermissionSettings: LegacyPermissionSettings) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getLegacyPermissionState(appId: Int): LegacyPermissionState {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun readLegacyPermissionStateTEMP() {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun writeLegacyPermissionStateTEMP() {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onSystemReady() {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onUserCreated(userId: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onUserRemoved(userId: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onStorageVolumeMounted(volumeUuid: String, fingerprintChanged: Boolean) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onPackageAdded(
|
||||
androidPackage: AndroidPackage,
|
||||
isInstantApp: Boolean,
|
||||
oldPackage: AndroidPackage?
|
||||
) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onPackageInstalled(
|
||||
androidPackage: AndroidPackage,
|
||||
previousAppId: Int,
|
||||
params: PermissionManagerServiceInternal.PackageInstalledParams,
|
||||
userId: Int
|
||||
) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onPackageUninstalled(
|
||||
packageName: String,
|
||||
appId: Int,
|
||||
androidPackage: AndroidPackage?,
|
||||
sharedUserPkgs: MutableList<AndroidPackage>,
|
||||
userId: Int
|
||||
) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onPackageRemoved(androidPackage: AndroidPackage) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a UID belongs to an instant app.
|
||||
*/
|
||||
private fun PackageManagerLocal.UnfilteredSnapshot.isUidInstantApp(uid: Int): Boolean {
|
||||
if (Process.isIsolatedUid(uid)) {
|
||||
// Unfortunately we don't have the API for getting the owner UID of an isolated UID yet,
|
||||
// so for now we just keep calling the old API.
|
||||
return packageManagerInternal.getInstantAppPackageName(uid) != null
|
||||
}
|
||||
val appId = UserHandle.getAppId(uid)
|
||||
// Instant apps can't have shared UIDs, so we can just take the first package.
|
||||
val firstPackageState = packageStates.values.firstOrNull { it.appId == appId }
|
||||
?: return false
|
||||
val userId = UserHandle.getUserId(uid)
|
||||
return firstPackageState.getUserStateOrDefault(userId).isInstantApp
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a package is visible to a UID within the same user as the UID.
|
||||
*/
|
||||
private fun PackageManagerLocal.UnfilteredSnapshot.isPackageVisibleToUid(
|
||||
packageName: String,
|
||||
uid: Int
|
||||
): Boolean = isPackageVisibleToUid(packageName, UserHandle.getUserId(uid), uid)
|
||||
|
||||
/**
|
||||
* Check whether a package in a particular user is visible to a UID.
|
||||
*/
|
||||
private fun PackageManagerLocal.UnfilteredSnapshot.isPackageVisibleToUid(
|
||||
packageName: String,
|
||||
userId: Int,
|
||||
uid: Int
|
||||
): Boolean {
|
||||
val user = UserHandle.of(userId)
|
||||
return filtered(uid, user).use { it.getPackageState(packageName) != null }
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package com.android.server.permission.access.permission
|
||||
|
||||
import android.Manifest
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.PermissionGroupInfo
|
||||
import android.content.pm.PermissionInfo
|
||||
import android.os.Build
|
||||
import android.os.UserHandle
|
||||
@@ -26,6 +27,8 @@ import com.android.modules.utils.BinaryXmlPullParser
|
||||
import com.android.modules.utils.BinaryXmlSerializer
|
||||
import com.android.server.permission.access.AccessState
|
||||
import com.android.server.permission.access.AccessUri
|
||||
import com.android.server.permission.access.GetStateScope
|
||||
import com.android.server.permission.access.MutateStateScope
|
||||
import com.android.server.permission.access.PermissionUri
|
||||
import com.android.server.permission.access.SchemePolicy
|
||||
import com.android.server.permission.access.SystemState
|
||||
@@ -52,19 +55,17 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
override val objectScheme: String
|
||||
get() = PermissionUri.SCHEME
|
||||
|
||||
override fun getDecision(subject: AccessUri, `object`: AccessUri, state: AccessState): Int {
|
||||
override fun GetStateScope.getDecision(subject: AccessUri, `object`: AccessUri): Int {
|
||||
subject as UidUri
|
||||
`object` as PermissionUri
|
||||
return state.userStates[subject.userId]?.permissionFlags?.get(subject.appId)
|
||||
?.get(`object`.permissionName) ?: 0
|
||||
}
|
||||
|
||||
override fun setDecision(
|
||||
override fun MutateStateScope.setDecision(
|
||||
subject: AccessUri,
|
||||
`object`: AccessUri,
|
||||
decision: Int,
|
||||
oldState: AccessState,
|
||||
newState: AccessState
|
||||
decision: Int
|
||||
) {
|
||||
subject as UidUri
|
||||
`object` as PermissionUri
|
||||
@@ -73,64 +74,58 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
uidFlags[`object`.permissionName] = decision
|
||||
}
|
||||
|
||||
override fun onUserAdded(userId: Int, oldState: AccessState, newState: AccessState) {
|
||||
override fun MutateStateScope.onUserAdded(userId: Int) {
|
||||
newState.systemState.packageStates.forEachValueIndexed { _, packageState ->
|
||||
evaluateAllPermissionStatesForPackageAndUser(
|
||||
packageState, null, userId, oldState, newState
|
||||
)
|
||||
grantImplicitPermissions(packageState, userId, oldState, newState)
|
||||
evaluateAllPermissionStatesForPackageAndUser(packageState, null, userId)
|
||||
grantImplicitPermissions(packageState, userId)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAppIdAdded(appId: Int, oldState: AccessState, newState: AccessState) {
|
||||
override fun MutateStateScope.onAppIdAdded(appId: Int) {
|
||||
newState.userStates.forEachIndexed { _, _, userState ->
|
||||
userState.permissionFlags.getOrPut(appId) { IndexedMap() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAppIdRemoved(appId: Int, oldState: AccessState, newState: AccessState) {
|
||||
override fun MutateStateScope.onAppIdRemoved(appId: Int) {
|
||||
newState.userStates.forEachIndexed { _, _, userState -> userState.permissionFlags -= appId }
|
||||
}
|
||||
|
||||
override fun onPackageAdded(
|
||||
packageState: PackageState,
|
||||
oldState: AccessState,
|
||||
newState: AccessState
|
||||
) {
|
||||
override fun MutateStateScope.onPackageAdded(packageState: PackageState) {
|
||||
val changedPermissionNames = IndexedSet<String>()
|
||||
adoptPermissions(packageState, changedPermissionNames, newState)
|
||||
addPermissionGroups(packageState, newState)
|
||||
addPermissions(packageState, changedPermissionNames, newState)
|
||||
adoptPermissions(packageState, changedPermissionNames)
|
||||
addPermissionGroups(packageState)
|
||||
addPermissions(packageState, changedPermissionNames)
|
||||
// TODO: revokeStoragePermissionsIfScopeExpandedInternal()
|
||||
trimPermissions(packageState.packageName, newState)
|
||||
changedPermissionNames.forEachIndexed { _, it ->
|
||||
evaluatePermissionStateForAllPackages(it, packageState, oldState, newState)
|
||||
trimPermissions(packageState.packageName)
|
||||
changedPermissionNames.forEachIndexed { _, permissionName ->
|
||||
evaluatePermissionStateForAllPackages(permissionName, packageState)
|
||||
}
|
||||
|
||||
evaluateAllPermissionStatesForPackage(packageState, packageState, oldState, newState)
|
||||
newState.systemState.userIds.forEachIndexed { _, it ->
|
||||
grantImplicitPermissions(packageState, it, oldState, newState)
|
||||
evaluateAllPermissionStatesForPackage(packageState, packageState)
|
||||
newState.systemState.userIds.forEachIndexed { _, userId ->
|
||||
grantImplicitPermissions(packageState, userId)
|
||||
}
|
||||
|
||||
// TODO: add trimPermissionStates() here for removing the permission states that are
|
||||
// no longer requested. (equivalent to revokeUnusedSharedUserPermissionsLocked())
|
||||
}
|
||||
|
||||
private fun adoptPermissions(
|
||||
private fun MutateStateScope.adoptPermissions(
|
||||
packageState: PackageState,
|
||||
changedPermissionNames: IndexedSet<String>,
|
||||
newState: AccessState
|
||||
changedPermissionNames: IndexedSet<String>
|
||||
) {
|
||||
val `package` = packageState.androidPackage!!
|
||||
`package`.adoptPermissions.forEachIndexed { _, originalPackageName ->
|
||||
val packageName = `package`.packageName
|
||||
if (!canAdoptPermissions(packageName, originalPackageName, newState)) {
|
||||
if (!canAdoptPermissions(packageName, originalPackageName)) {
|
||||
return@forEachIndexed
|
||||
}
|
||||
newState.systemState.permissions.let { permissions ->
|
||||
permissions.forEachIndexed { i, permissionName, oldPermission ->
|
||||
permissions.forEachIndexed permissions@ {
|
||||
permissionIndex, permissionName, oldPermission ->
|
||||
if (oldPermission.packageName != originalPackageName) {
|
||||
return@forEachIndexed
|
||||
return@permissions
|
||||
}
|
||||
@Suppress("DEPRECATION")
|
||||
val newPermissionInfo = PermissionInfo().apply {
|
||||
@@ -140,16 +135,15 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
}
|
||||
val newPermission = Permission(newPermissionInfo, false, oldPermission.type, 0)
|
||||
changedPermissionNames += permissionName
|
||||
permissions.setValueAt(i, newPermission)
|
||||
permissions.setValueAt(permissionIndex, newPermission)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun canAdoptPermissions(
|
||||
private fun MutateStateScope.canAdoptPermissions(
|
||||
packageName: String,
|
||||
originalPackageName: String,
|
||||
newState: AccessState
|
||||
originalPackageName: String
|
||||
): Boolean {
|
||||
val originalPackageState = newState.systemState.packageStates[originalPackageName]
|
||||
?: return false
|
||||
@@ -170,7 +164,7 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
return true
|
||||
}
|
||||
|
||||
private fun addPermissionGroups(packageState: PackageState, newState: AccessState) {
|
||||
private fun MutateStateScope.addPermissionGroups(packageState: PackageState) {
|
||||
// Different from the old implementation, which decides whether the app is an instant app by
|
||||
// the install flags, now for consistent behavior we allow adding permission groups if the
|
||||
// app is non-instant in at least one user.
|
||||
@@ -202,10 +196,9 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun addPermissions(
|
||||
private fun MutateStateScope.addPermissions(
|
||||
packageState: PackageState,
|
||||
changedPermissionNames: IndexedSet<String>,
|
||||
newState: AccessState
|
||||
changedPermissionNames: IndexedSet<String>
|
||||
) {
|
||||
packageState.androidPackage!!.permissions.forEachIndexed { _, parsedPermission ->
|
||||
// TODO:
|
||||
@@ -229,7 +222,7 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
// Different from the old implementation, which may add an (incomplete) signature
|
||||
// permission inside another package's permission tree, we now consistently ignore such
|
||||
// permissions.
|
||||
val permissionTree = getPermissionTree(permissionName, newState)
|
||||
val permissionTree = getPermissionTree(permissionName)
|
||||
val newPackageName = newPermissionInfo.packageName
|
||||
if (permissionTree != null && newPackageName != permissionTree.packageName) {
|
||||
Log.w(
|
||||
@@ -294,10 +287,7 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun trimPermissions(
|
||||
packageName: String,
|
||||
newState: AccessState,
|
||||
) {
|
||||
private fun MutateStateScope.trimPermissions(packageName: String) {
|
||||
val packageState = newState.systemState.packageStates[packageName]
|
||||
val androidPackage = packageState?.androidPackage
|
||||
if (packageState != null && androidPackage == null) {
|
||||
@@ -314,20 +304,20 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
}
|
||||
|
||||
newState.systemState.permissions.removeAllIndexed { i, permissionName, permission ->
|
||||
val updatedPermission = updatePermissionIfDynamic(permission, newState)
|
||||
val updatedPermission = updatePermissionIfDynamic(permission)
|
||||
newState.systemState.permissions.setValueAt(i, updatedPermission)
|
||||
if (updatedPermission.packageName == packageName && (
|
||||
packageState == null || androidPackage!!.permissions.noneIndexed { _, it ->
|
||||
!it.isTree && it.name == permissionName
|
||||
}
|
||||
)) {
|
||||
if (!isPermissionDeclaredByDisabledSystemPackage(permission, newState)) {
|
||||
if (!isPermissionDeclaredByDisabledSystemPackage(permission)) {
|
||||
newState.userStates.forEachIndexed { _, userId, userState ->
|
||||
userState.permissionFlags.forEachKeyIndexed { _, appId ->
|
||||
setPermissionFlags(
|
||||
appId, permissionName, getPermissionFlags(
|
||||
appId, permissionName, userId, newState
|
||||
) and PermissionFlags.INSTALL_REVOKED, userId, newState
|
||||
appId, permissionName, userId
|
||||
) and PermissionFlags.INSTALL_REVOKED, userId
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -339,9 +329,8 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun isPermissionDeclaredByDisabledSystemPackage(
|
||||
permission: Permission,
|
||||
newState: AccessState
|
||||
private fun MutateStateScope.isPermissionDeclaredByDisabledSystemPackage(
|
||||
permission: Permission
|
||||
): Boolean {
|
||||
val disabledSystemPackage = newState.systemState
|
||||
.disabledSystemPackageStates[permission.packageName]?.androidPackage ?: return false
|
||||
@@ -350,14 +339,11 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePermissionIfDynamic(
|
||||
permission: Permission,
|
||||
newState: AccessState
|
||||
): Permission {
|
||||
private fun MutateStateScope.updatePermissionIfDynamic(permission: Permission): Permission {
|
||||
if (!permission.isDynamic) {
|
||||
return permission
|
||||
}
|
||||
val permissionTree = getPermissionTree(permission.name, newState) ?: return permission
|
||||
val permissionTree = getPermissionTree(permission.name) ?: return permission
|
||||
@Suppress("DEPRECATION")
|
||||
return permission.copy(
|
||||
permissionInfo = PermissionInfo(permission.permissionInfo).apply {
|
||||
@@ -366,7 +352,7 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
)
|
||||
}
|
||||
|
||||
private fun getPermissionTree(permissionName: String, newState: AccessState): Permission? =
|
||||
private fun MutateStateScope.getPermissionTree(permissionName: String): Permission? =
|
||||
newState.systemState.permissionTrees.firstNotNullOfOrNullIndexed {
|
||||
_, permissionTreeName, permissionTree ->
|
||||
if (permissionName.startsWith(permissionTreeName) &&
|
||||
@@ -378,58 +364,48 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun evaluatePermissionStateForAllPackages(
|
||||
private fun MutateStateScope.evaluatePermissionStateForAllPackages(
|
||||
permissionName: String,
|
||||
installedPackageState: PackageState?,
|
||||
oldState: AccessState,
|
||||
newState: AccessState
|
||||
installedPackageState: PackageState?
|
||||
) {
|
||||
newState.systemState.userIds.forEachIndexed { _, userId ->
|
||||
oldState.userStates[userId]?.permissionFlags?.forEachIndexed {
|
||||
_, appId, permissionFlags ->
|
||||
if (permissionName in permissionFlags) {
|
||||
evaluatePermissionState(
|
||||
appId, permissionName, installedPackageState, userId, oldState, newState
|
||||
)
|
||||
evaluatePermissionState(appId, permissionName, installedPackageState, userId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun evaluateAllPermissionStatesForPackage(
|
||||
private fun MutateStateScope.evaluateAllPermissionStatesForPackage(
|
||||
packageState: PackageState,
|
||||
installedPackageState: PackageState?,
|
||||
oldState: AccessState,
|
||||
newState: AccessState
|
||||
installedPackageState: PackageState?
|
||||
) {
|
||||
newState.systemState.userIds.forEachIndexed { _, userId ->
|
||||
evaluateAllPermissionStatesForPackageAndUser(
|
||||
packageState, installedPackageState, userId, oldState, newState
|
||||
packageState, installedPackageState, userId
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun evaluateAllPermissionStatesForPackageAndUser(
|
||||
private fun MutateStateScope.evaluateAllPermissionStatesForPackageAndUser(
|
||||
packageState: PackageState,
|
||||
installedPackageState: PackageState?,
|
||||
userId: Int,
|
||||
oldState: AccessState,
|
||||
newState: AccessState
|
||||
userId: Int
|
||||
) {
|
||||
packageState.androidPackage?.requestedPermissions?.forEachIndexed { _, it ->
|
||||
packageState.androidPackage?.requestedPermissions?.forEachIndexed { _, permissionName ->
|
||||
evaluatePermissionState(
|
||||
packageState.appId, it, installedPackageState, userId, oldState, newState
|
||||
packageState.appId, permissionName, installedPackageState, userId
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun evaluatePermissionState(
|
||||
private fun MutateStateScope.evaluatePermissionState(
|
||||
appId: Int,
|
||||
permissionName: String,
|
||||
installedPackageState: PackageState?,
|
||||
userId: Int,
|
||||
oldState: AccessState,
|
||||
newState: AccessState
|
||||
userId: Int
|
||||
) {
|
||||
val packageNames = newState.systemState.appIds[appId]
|
||||
val hasMissingPackage = packageNames.anyIndexed { _, packageName ->
|
||||
@@ -440,17 +416,17 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
return
|
||||
}
|
||||
val permission = newState.systemState.permissions[permissionName] ?: return
|
||||
val oldFlags = getPermissionFlags(appId, permissionName, userId, newState)
|
||||
val oldFlags = getPermissionFlags(appId, permissionName, userId)
|
||||
if (permission.isNormal) {
|
||||
val wasGranted = oldFlags.hasBits(PermissionFlags.INSTALL_GRANTED)
|
||||
if (!wasGranted) {
|
||||
val wasRevoked = oldFlags.hasBits(PermissionFlags.INSTALL_REVOKED)
|
||||
val isRequestedByInstalledPackage = installedPackageState != null &&
|
||||
permissionName in installedPackageState.androidPackage!!.requestedPermissions
|
||||
val isRequestedBySystemPackage = anyPackageInAppId(appId, newState) {
|
||||
val isRequestedBySystemPackage = anyPackageInAppId(appId) {
|
||||
it.isSystem && permissionName in it.androidPackage!!.requestedPermissions
|
||||
}
|
||||
val isCompatibilityPermission = anyPackageInAppId(appId, newState) {
|
||||
val isCompatibilityPermission = anyPackageInAppId(appId) {
|
||||
isCompatibilityPermissionForPackage(it.androidPackage!!, permissionName)
|
||||
}
|
||||
// If this is an existing, non-system package,
|
||||
@@ -462,7 +438,7 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
} else {
|
||||
PermissionFlags.INSTALL_REVOKED
|
||||
}
|
||||
setPermissionFlags(appId, permissionName, newFlags, userId, newState)
|
||||
setPermissionFlags(appId, permissionName, newFlags, userId)
|
||||
}
|
||||
} else if (permission.isSignature || permission.isInternal) {
|
||||
val wasProtectionGranted = oldFlags.hasBits(PermissionFlags.PROTECTION_GRANTED)
|
||||
@@ -471,17 +447,17 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
PermissionFlags.PROTECTION_GRANTED
|
||||
} else {
|
||||
val mayGrantByPrivileged = !permission.isPrivileged || (
|
||||
anyPackageInAppId(appId, newState) {
|
||||
checkPrivilegedPermissionAllowlist(it, permission, newState)
|
||||
anyPackageInAppId(appId) {
|
||||
checkPrivilegedPermissionAllowlist(it, permission)
|
||||
}
|
||||
)
|
||||
val shouldGrantBySignature = permission.isSignature && (
|
||||
anyPackageInAppId(appId, newState) {
|
||||
shouldGrantPermissionBySignature(it, permission, newState)
|
||||
anyPackageInAppId(appId) {
|
||||
shouldGrantPermissionBySignature(it, permission)
|
||||
}
|
||||
)
|
||||
val shouldGrantByProtectionFlags = anyPackageInAppId(appId, newState) {
|
||||
shouldGrantPermissionByProtectionFlags(it, permission, newState)
|
||||
val shouldGrantByProtectionFlags = anyPackageInAppId(appId) {
|
||||
shouldGrantPermissionByProtectionFlags(it, permission)
|
||||
}
|
||||
if (mayGrantByPrivileged &&
|
||||
(shouldGrantBySignature || shouldGrantByProtectionFlags)) {
|
||||
@@ -501,7 +477,7 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
if (permission.isRole) {
|
||||
newFlags = newFlags or (oldFlags and PermissionFlags.ROLE_GRANTED)
|
||||
}
|
||||
setPermissionFlags(appId, permissionName, newFlags, userId, newState)
|
||||
setPermissionFlags(appId, permissionName, newFlags, userId)
|
||||
} else if (permission.isRuntime) {
|
||||
// TODO: add runtime permissions
|
||||
} else {
|
||||
@@ -513,12 +489,7 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
// TODO: revokePermissionsNoLongerImplicitLocked() for runtime permissions
|
||||
}
|
||||
|
||||
private fun grantImplicitPermissions(
|
||||
packageState: PackageState,
|
||||
userId: Int,
|
||||
oldState: AccessState,
|
||||
newState: AccessState
|
||||
) {
|
||||
private fun MutateStateScope.grantImplicitPermissions(packageState: PackageState, userId: Int) {
|
||||
val appId = packageState.appId
|
||||
val androidPackage = packageState.androidPackage ?: return
|
||||
androidPackage.implicitPermissions.forEachIndexed implicitPermissions@ {
|
||||
@@ -530,6 +501,7 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
if (!implicitPermission.isRuntime) {
|
||||
return@implicitPermissions
|
||||
}
|
||||
// Explicitly check against the old state to determine if this permission is new.
|
||||
val isNewPermission = getPermissionFlags(
|
||||
appId, implicitPermissionName, userId, oldState
|
||||
) == 0
|
||||
@@ -544,7 +516,7 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
checkNotNull(sourcePermission) {
|
||||
"Unknown source permission $sourcePermissionName in split permissions"
|
||||
}
|
||||
val sourceFlags = getPermissionFlags(appId, sourcePermissionName, userId, newState)
|
||||
val sourceFlags = getPermissionFlags(appId, sourcePermissionName, userId)
|
||||
val isSourceGranted = sourceFlags.hasAnyBit(PermissionFlags.MASK_GRANTED)
|
||||
val isNewGranted = newFlags.hasAnyBit(PermissionFlags.MASK_GRANTED)
|
||||
val isGrantingNewFromRevoke = isSourceGranted && !isNewGranted
|
||||
@@ -559,23 +531,22 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
}
|
||||
}
|
||||
newFlags = newFlags or PermissionFlags.IMPLICIT
|
||||
setPermissionFlags(appId, implicitPermissionName, newFlags, userId, newState)
|
||||
setPermissionFlags(appId, implicitPermissionName, newFlags, userId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPermissionFlags(
|
||||
private fun MutateStateScope.getPermissionFlags(
|
||||
appId: Int,
|
||||
permissionName: String,
|
||||
userId: Int,
|
||||
state: AccessState
|
||||
state: AccessState = newState
|
||||
): Int = state.userStates[userId].permissionFlags[appId].getWithDefault(permissionName, 0)
|
||||
|
||||
private fun setPermissionFlags(
|
||||
private fun MutateStateScope.setPermissionFlags(
|
||||
appId: Int,
|
||||
permissionName: String,
|
||||
flags: Int,
|
||||
userId: Int,
|
||||
newState: AccessState
|
||||
userId: Int
|
||||
) {
|
||||
newState.userStates[userId].permissionFlags[appId]!!
|
||||
.putWithDefault(permissionName, flags, 0)
|
||||
@@ -585,8 +556,9 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
androidPackage: AndroidPackage,
|
||||
permissionName: String
|
||||
): Boolean {
|
||||
for (info: CompatibilityPermissionInfo in CompatibilityPermissionInfo.COMPAT_PERMS) {
|
||||
if (info.name == permissionName && androidPackage.targetSdkVersion < info.sdkVersion) {
|
||||
for (compatibilityPermission in CompatibilityPermissionInfo.COMPAT_PERMS) {
|
||||
if (compatibilityPermission.name == permissionName &&
|
||||
androidPackage.targetSdkVersion < compatibilityPermission.sdkVersion) {
|
||||
Log.i(
|
||||
LOG_TAG, "Auto-granting $permissionName to old package" +
|
||||
" ${androidPackage.packageName}"
|
||||
@@ -597,10 +569,9 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
return false
|
||||
}
|
||||
|
||||
private fun shouldGrantPermissionBySignature(
|
||||
private fun MutateStateScope.shouldGrantPermissionBySignature(
|
||||
packageState: PackageState,
|
||||
permission: Permission,
|
||||
newState: AccessState
|
||||
permission: Permission
|
||||
): Boolean {
|
||||
// check if the package is allow to use this signature permission. A package is allowed to
|
||||
// use a signature permission if:
|
||||
@@ -622,10 +593,9 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
SigningDetails.CertCapabilities.PERMISSION)
|
||||
}
|
||||
|
||||
private fun checkPrivilegedPermissionAllowlist(
|
||||
private fun MutateStateScope.checkPrivilegedPermissionAllowlist(
|
||||
packageState: PackageState,
|
||||
permission: Permission,
|
||||
newState: AccessState
|
||||
permission: Permission
|
||||
): Boolean {
|
||||
if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE) {
|
||||
return true
|
||||
@@ -641,10 +611,10 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
newState.systemState.privilegedPermissionAllowlistSourcePackageNames) {
|
||||
return true
|
||||
}
|
||||
if (isInSystemConfigPrivAppPermissions(androidPackage, permission.name, newState)) {
|
||||
if (isInSystemConfigPrivAppPermissions(androidPackage, permission.name)) {
|
||||
return true
|
||||
}
|
||||
if (isInSystemConfigPrivAppDenyPermissions(androidPackage, permission.name, newState)) {
|
||||
if (isInSystemConfigPrivAppDenyPermissions(androidPackage, permission.name)) {
|
||||
return false
|
||||
}
|
||||
// Updated system apps do not need to be allowlisted
|
||||
@@ -655,10 +625,9 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
return !RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE
|
||||
}
|
||||
|
||||
private fun isInSystemConfigPrivAppPermissions(
|
||||
private fun MutateStateScope.isInSystemConfigPrivAppPermissions(
|
||||
androidPackage: AndroidPackage,
|
||||
permissionName: String,
|
||||
newState: AccessState
|
||||
permissionName: String
|
||||
): Boolean {
|
||||
val apexModuleName = androidPackage.apexModuleName
|
||||
val systemState = newState.systemState
|
||||
@@ -682,10 +651,9 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
return permissionNames?.contains(permissionName) == true
|
||||
}
|
||||
|
||||
private fun isInSystemConfigPrivAppDenyPermissions(
|
||||
private fun MutateStateScope.isInSystemConfigPrivAppDenyPermissions(
|
||||
androidPackage: AndroidPackage,
|
||||
permissionName: String,
|
||||
newState: AccessState
|
||||
permissionName: String
|
||||
): Boolean {
|
||||
// Different from the previous implementation, which may incorrectly use the APEX package
|
||||
// name, we now use the APEX module name to be consistent with the allowlist.
|
||||
@@ -713,22 +681,21 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
return permissionNames?.contains(permissionName) == true
|
||||
}
|
||||
|
||||
private fun anyPackageInAppId(
|
||||
private fun MutateStateScope.anyPackageInAppId(
|
||||
appId: Int,
|
||||
newState: AccessState,
|
||||
state: AccessState = newState,
|
||||
predicate: (PackageState) -> Boolean
|
||||
): Boolean {
|
||||
val packageNames = newState.systemState.appIds[appId]
|
||||
val packageNames = state.systemState.appIds[appId]
|
||||
return packageNames.anyIndexed { _, packageName ->
|
||||
val packageState = newState.systemState.packageStates[packageName]!!
|
||||
val packageState = state.systemState.packageStates[packageName]!!
|
||||
packageState.androidPackage != null && predicate(packageState)
|
||||
}
|
||||
}
|
||||
|
||||
private fun shouldGrantPermissionByProtectionFlags(
|
||||
private fun MutateStateScope.shouldGrantPermissionByProtectionFlags(
|
||||
packageState: PackageState,
|
||||
permission: Permission,
|
||||
newState: AccessState
|
||||
permission: Permission
|
||||
): Boolean {
|
||||
val androidPackage = packageState.androidPackage!!
|
||||
val knownPackages = newState.systemState.knownPackages
|
||||
@@ -741,11 +708,9 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
.disabledSystemPackageStates[packageState.packageName]?.androidPackage
|
||||
disabledSystemPackage != null &&
|
||||
permission.name in disabledSystemPackage.requestedPermissions &&
|
||||
shouldGrantPrivilegedOrOemPermission(
|
||||
disabledSystemPackage, permission, newState
|
||||
)
|
||||
shouldGrantPrivilegedOrOemPermission(disabledSystemPackage, permission)
|
||||
} else {
|
||||
shouldGrantPrivilegedOrOemPermission(androidPackage, permission, newState)
|
||||
shouldGrantPrivilegedOrOemPermission(androidPackage, permission)
|
||||
}
|
||||
if (shouldGrant) {
|
||||
return true
|
||||
@@ -815,7 +780,7 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
}
|
||||
if (permission.isRetailDemo &&
|
||||
packageName in knownPackages[KnownPackages.PACKAGE_RETAIL_DEMO] &&
|
||||
isDeviceOrProfileOwnerUid(packageState.appId, newState)) {
|
||||
isDeviceOrProfileOwnerUid(packageState.appId)) {
|
||||
// Special permission granted only to the OEM specified retail demo app.
|
||||
// Note that the original code was passing app ID as UID, so this behavior is kept
|
||||
// unchanged.
|
||||
@@ -829,10 +794,9 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
return false
|
||||
}
|
||||
|
||||
private fun shouldGrantPrivilegedOrOemPermission(
|
||||
private fun MutateStateScope.shouldGrantPrivilegedOrOemPermission(
|
||||
androidPackage: AndroidPackage,
|
||||
permission: Permission,
|
||||
state: AccessState
|
||||
permission: Permission
|
||||
): Boolean {
|
||||
val permissionName = permission.name
|
||||
val packageName = androidPackage.packageName
|
||||
@@ -855,7 +819,7 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
}
|
||||
permission.isOem -> {
|
||||
if (androidPackage.isOem) {
|
||||
val isOemAllowlisted = state.systemState
|
||||
val isOemAllowlisted = newState.systemState
|
||||
.oemPermissions[packageName]?.get(permissionName)
|
||||
checkNotNull(isOemAllowlisted) {
|
||||
"OEM permission $permissionName requested by package" +
|
||||
@@ -868,19 +832,15 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
return false
|
||||
}
|
||||
|
||||
private fun isDeviceOrProfileOwnerUid(uid: Int, state: AccessState): Boolean {
|
||||
private fun MutateStateScope.isDeviceOrProfileOwnerUid(uid: Int): Boolean {
|
||||
val userId = UserHandle.getUserId(uid)
|
||||
val ownerPackageName = state.systemState.deviceAndProfileOwners[userId] ?: return false
|
||||
val ownerPackageState = state.systemState.packageStates[ownerPackageName] ?: return false
|
||||
val ownerPackageName = newState.systemState.deviceAndProfileOwners[userId] ?: return false
|
||||
val ownerPackageState = newState.systemState.packageStates[ownerPackageName] ?: return false
|
||||
val ownerUid = UserHandle.getUid(userId, ownerPackageState.appId)
|
||||
return uid == ownerUid
|
||||
}
|
||||
|
||||
override fun onPackageRemoved(
|
||||
packageState: PackageState,
|
||||
oldState: AccessState,
|
||||
newState: AccessState
|
||||
) {
|
||||
override fun MutateStateScope.onPackageRemoved(packageState: PackageState) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@@ -892,6 +852,12 @@ class UidPermissionPolicy : SchemePolicy() {
|
||||
with(persistence) { this@serializeSystemState.serializeSystemState(systemState) }
|
||||
}
|
||||
|
||||
fun GetStateScope.getPermissionGroup(permissionGroupName: String): PermissionGroupInfo? =
|
||||
state.systemState.permissionGroups[permissionGroupName]
|
||||
|
||||
fun GetStateScope.getPermission(permissionName: String): Permission? =
|
||||
state.systemState.permissions[permissionName]
|
||||
|
||||
companion object {
|
||||
private val LOG_TAG = UidPermissionPolicy::class.java.simpleName
|
||||
|
||||
|
||||
Reference in New Issue
Block a user