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.os.Process 20 import android.util.Slog 21 import com.android.modules.utils.BinaryXmlPullParser 22 import com.android.modules.utils.BinaryXmlSerializer 23 import com.android.server.permission.access.AccessState 24 import com.android.server.permission.access.AppIdAppOpModes 25 import com.android.server.permission.access.MutableAccessState 26 import com.android.server.permission.access.MutableAppIdAppOpModes 27 import com.android.server.permission.access.WriteMode 28 import com.android.server.permission.access.immutable.* // ktlint-disable no-wildcard-imports 29 import com.android.server.permission.access.util.attributeInt 30 import com.android.server.permission.access.util.forEachTag 31 import com.android.server.permission.access.util.getAttributeIntOrThrow 32 import com.android.server.permission.access.util.tag 33 import com.android.server.permission.access.util.tagName 34 35 class AppIdAppOpPersistence : BaseAppOpPersistence() { 36 override fun BinaryXmlPullParser.parseUserState(state: MutableAccessState, userId: Int) { 37 when (tagName) { 38 TAG_APP_ID_APP_OPS -> parseAppIdAppOps(state, userId) 39 else -> {} 40 } 41 } 42 43 private fun BinaryXmlPullParser.parseAppIdAppOps(state: MutableAccessState, userId: Int) { 44 val userState = state.mutateUserState(userId, WriteMode.NONE)!! 45 val appIdAppOpModes = userState.mutateAppIdAppOpModes() 46 forEachTag { 47 when (tagName) { 48 TAG_APP_ID -> parseAppId(appIdAppOpModes) 49 else -> Slog.w(LOG_TAG, "Ignoring unknown tag $name when parsing app-op state") 50 } 51 } 52 userState.appIdAppOpModes.forEachReversedIndexed { appIdIndex, appId, _ -> 53 // Non-application UIDs may not have an Android package but may still have app op state. 54 if ( 55 appId !in state.externalState.appIdPackageNames && 56 appId >= Process.FIRST_APPLICATION_UID 57 ) { 58 Slog.w(LOG_TAG, "Dropping unknown app ID $appId when parsing app-op state") 59 appIdAppOpModes.removeAt(appIdIndex) 60 userState.requestWriteMode(WriteMode.ASYNCHRONOUS) 61 } 62 } 63 } 64 65 private fun BinaryXmlPullParser.parseAppId(appIdAppOpModes: MutableAppIdAppOpModes) { 66 val appId = getAttributeIntOrThrow(ATTR_ID) 67 val appOpModes = MutableIndexedMap<String, Int>() 68 appIdAppOpModes[appId] = appOpModes 69 parseAppOps(appOpModes) 70 } 71 72 override fun BinaryXmlSerializer.serializeUserState(state: AccessState, userId: Int) { 73 serializeAppIdAppOps(state.userStates[userId]!!.appIdAppOpModes) 74 } 75 76 private fun BinaryXmlSerializer.serializeAppIdAppOps(appIdAppOpModes: AppIdAppOpModes) { 77 tag(TAG_APP_ID_APP_OPS) { 78 appIdAppOpModes.forEachIndexed { _, appId, appOpModes -> 79 serializeAppId(appId, appOpModes) 80 } 81 } 82 } 83 84 private fun BinaryXmlSerializer.serializeAppId( 85 appId: Int, 86 appOpModes: IndexedMap<String, Int> 87 ) { 88 tag(TAG_APP_ID) { 89 attributeInt(ATTR_ID, appId) 90 serializeAppOps(appOpModes) 91 } 92 } 93 94 companion object { 95 private val LOG_TAG = AppIdAppOpPersistence::class.java.simpleName 96 97 private const val TAG_APP_ID = "app-id" 98 private const val TAG_APP_ID_APP_OPS = "app-id-app-ops" 99 100 private const val ATTR_ID = "id" 101 } 102 } 103