1 /* <lambda>null2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.permission.access.appop 18 19 import android.util.Slog 20 import com.android.modules.utils.BinaryXmlPullParser 21 import com.android.modules.utils.BinaryXmlSerializer 22 import com.android.server.permission.access.AccessState 23 import com.android.server.permission.access.MutableAccessState 24 import com.android.server.permission.access.MutablePackageAppOpModes 25 import com.android.server.permission.access.PackageAppOpModes 26 import com.android.server.permission.access.WriteMode 27 import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports 28 import com.android.server.permission.access.immutable.* // ktlint-disable no-wildcard-imports 29 import com.android.server.permission.access.util.attributeInterned 30 import com.android.server.permission.access.util.forEachTag 31 import com.android.server.permission.access.util.getAttributeValueOrThrow 32 import com.android.server.permission.access.util.tag 33 import com.android.server.permission.access.util.tagName 34 35 class PackageAppOpPersistence : BaseAppOpPersistence() { 36 override fun BinaryXmlPullParser.parseUserState(state: MutableAccessState, userId: Int) { 37 when (tagName) { 38 TAG_PACKAGE_APP_OPS -> parsePackageAppOps(state, userId) 39 else -> {} 40 } 41 } 42 43 private fun BinaryXmlPullParser.parsePackageAppOps(state: MutableAccessState, userId: Int) { 44 val userState = state.mutateUserState(userId, WriteMode.NONE)!! 45 val packageAppOpModes = userState.mutatePackageAppOpModes() 46 forEachTag { 47 when (tagName) { 48 TAG_PACKAGE -> parsePackage(packageAppOpModes) 49 else -> Slog.w(LOG_TAG, "Ignoring unknown tag $name when parsing app-op state") 50 } 51 } 52 packageAppOpModes.forEachReversedIndexed { packageNameIndex, packageName, _ -> 53 if (packageName !in state.externalState.packageStates) { 54 Slog.w(LOG_TAG, "Dropping unknown package $packageName when parsing app-op state") 55 packageAppOpModes.removeAt(packageNameIndex) 56 userState.requestWriteMode(WriteMode.ASYNCHRONOUS) 57 } 58 } 59 } 60 61 private fun BinaryXmlPullParser.parsePackage(packageAppOpModes: MutablePackageAppOpModes) { 62 val packageName = getAttributeValueOrThrow(ATTR_NAME).intern() 63 val appOpModes = MutableIndexedMap<String, Int>() 64 packageAppOpModes[packageName] = appOpModes 65 parseAppOps(appOpModes) 66 } 67 68 override fun BinaryXmlSerializer.serializeUserState(state: AccessState, userId: Int) { 69 serializePackageAppOps(state.userStates[userId]!!.packageAppOpModes) 70 } 71 72 private fun BinaryXmlSerializer.serializePackageAppOps(packageAppOpModes: PackageAppOpModes) { 73 tag(TAG_PACKAGE_APP_OPS) { 74 packageAppOpModes.forEachIndexed { _, packageName, appOpModes -> 75 serializePackage(packageName, appOpModes) 76 } 77 } 78 } 79 80 private fun BinaryXmlSerializer.serializePackage( 81 packageName: String, 82 appOpModes: IndexedMap<String, Int> 83 ) { 84 tag(TAG_PACKAGE) { 85 attributeInterned(ATTR_NAME, packageName) 86 serializeAppOps(appOpModes) 87 } 88 } 89 90 companion object { 91 private val LOG_TAG = PackageAppOpPersistence::class.java.simpleName 92 93 private const val TAG_PACKAGE = "package" 94 private const val TAG_PACKAGE_APP_OPS = "package-app-ops" 95 96 private const val ATTR_NAME = "name" 97 } 98 } 99