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.ondevicepersonalization.services.policyengine.api 18 19 import com.android.internal.annotations.VisibleForTesting; 20 21 import com.android.libraries.pcc.chronicle.analysis.DefaultChronicleContext 22 import com.android.libraries.pcc.chronicle.analysis.DefaultPolicySet 23 import com.android.libraries.pcc.chronicle.analysis.impl.ChroniclePolicyEngine 24 import com.android.libraries.pcc.chronicle.api.ConnectionProvider 25 import com.android.libraries.pcc.chronicle.api.flags.Flags 26 import com.android.libraries.pcc.chronicle.api.flags.FlagsReader 27 import com.android.libraries.pcc.chronicle.api.integration.DefaultChronicle 28 import com.android.libraries.pcc.chronicle.api.integration.DefaultDataTypeDescriptorSet 29 import com.android.libraries.pcc.chronicle.api.policy.DefaultPolicyConformanceCheck 30 import com.android.libraries.pcc.chronicle.api.policy.Policy 31 import com.android.libraries.pcc.chronicle.util.TypedMap 32 import com.android.ondevicepersonalization.services.policyengine.data.impl.UserDataConnectionProvider 33 import com.android.ondevicepersonalization.services.policyengine.policy.DataIngressPolicy 34 import kotlinx.coroutines.flow.MutableStateFlow 35 import kotlinx.coroutines.flow.StateFlow 36 37 /** [ChronicleManager] instance that connects to the Chronicle backend. */ 38 class ChronicleManager private constructor ( 39 private val connectionProviders: Set<ConnectionProvider>, 40 private val policies: Set<Policy>, 41 private val connectionContext: TypedMap = TypedMap() 42 ) { 43 private val flags = MutableStateFlow(Flags()) 44 private val flagsReader: FlagsReader = object : FlagsReader { 45 override val config: StateFlow<Flags> = this@ChronicleManager.flags 46 } 47 48 val chronicle = DefaultChronicle( 49 chronicleContext = 50 DefaultChronicleContext( 51 connectionProviders = connectionProviders, 52 processorNodes = emptySet(), 53 policySet = DefaultPolicySet(policies), 54 dataTypeDescriptorSet = 55 DefaultDataTypeDescriptorSet( <lambda>null56 connectionProviders.map { it.dataType.descriptor }.toSet() 57 ), 58 connectionContext = connectionContext 59 ), 60 policyEngine = ChroniclePolicyEngine(), 61 config = 62 DefaultChronicle.Config( 63 policyMode = DefaultChronicle.Config.PolicyMode.STRICT, 64 policyConformanceCheck = DefaultPolicyConformanceCheck() 65 ), 66 flags = flagsReader 67 ) 68 69 companion object { 70 @JvmField 71 @Volatile 72 @VisibleForTesting 73 var instance: ChronicleManager? = null 74 75 @JvmOverloads 76 @JvmStatic getInstancenull77 fun getInstance() = 78 instance 79 ?: synchronized(this) { 80 // double-checked locking 81 instance 82 ?: ChronicleManager( 83 setOf(UserDataConnectionProvider()), 84 setOf(DataIngressPolicy.NPA_DATA_POLICY), 85 TypedMap()).also{ instance = it } 86 } 87 } 88 <lambda>null89 fun failNewConnections(failNewConnections: Boolean) = updateFlags { 90 it.copy(failNewConnections = failNewConnections) 91 } 92 updateFlagsnull93 private inline fun updateFlags(block: (Flags) -> Flags) { 94 do { 95 val before = flags.value 96 val after = block(before) 97 } while (!flags.compareAndSet(before, after)) 98 } 99 } 100