1 /*
2  * 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.Log
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.collection.* // ktlint-disable no-wildcard-imports
24 import com.android.server.permission.access.util.attributeInt
25 import com.android.server.permission.access.util.attributeInterned
26 import com.android.server.permission.access.util.forEachTag
27 import com.android.server.permission.access.util.getAttributeIntOrThrow
28 import com.android.server.permission.access.util.getAttributeValueOrThrow
29 import com.android.server.permission.access.util.tag
30 import com.android.server.permission.access.util.tagName
31 
32 abstract class BaseAppOpPersistence {
33     abstract fun BinaryXmlPullParser.parseUserState(state: AccessState, userId: Int)
34 
35     abstract fun BinaryXmlSerializer.serializeUserState(state: AccessState, userId: Int)
36 
37     protected fun BinaryXmlPullParser.parseAppOps(appOpModes: IndexedMap<String, Int>) {
38         forEachTag {
39             when (tagName) {
40                 TAG_APP_OP -> parseAppOp(appOpModes)
41                 else -> Log.w(LOG_TAG, "Ignoring unknown tag $name when parsing app-op state")
42             }
43         }
44     }
45 
46     private fun BinaryXmlPullParser.parseAppOp(appOpModes: IndexedMap<String, Int>) {
47         val name = getAttributeValueOrThrow(ATTR_NAME).intern()
48         val mode = getAttributeIntOrThrow(ATTR_MODE)
49         appOpModes[name] = mode
50     }
51 
52     protected fun BinaryXmlSerializer.serializeAppOps(appOpModes: IndexedMap<String, Int>) {
53         appOpModes.forEachIndexed { _, name, mode ->
54             serializeAppOp(name, mode)
55         }
56     }
57 
58     private fun BinaryXmlSerializer.serializeAppOp(name: String, mode: Int) {
59         tag(TAG_APP_OP) {
60             attributeInterned(ATTR_NAME, name)
61             attributeInt(ATTR_MODE, mode)
62         }
63     }
64 
65     companion object {
66         private val LOG_TAG = BaseAppOpPersistence::class.java.simpleName
67 
68         private const val TAG_APP_OP = "app-op"
69 
70         private const val ATTR_MODE = "mode"
71         private const val ATTR_NAME = "name"
72     }
73 }
74