• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 kotlinx.coroutines.flow.MutableStateFlow
33 import kotlinx.coroutines.flow.StateFlow
34 
35 /** [ChronicleManager] instance that connects to the Chronicle backend. */
36 class ChronicleManager private constructor (
37     private val connectionProviders: Set<ConnectionProvider>,
38     private val policies: Set<Policy>,
39     private val connectionContext: TypedMap = TypedMap()
40 ) {
41     private val flags = MutableStateFlow(Flags())
42     private val flagsReader: FlagsReader = object : FlagsReader {
43         override val config: StateFlow<Flags> = this@ChronicleManager.flags
44     }
45 
46     val chronicle = DefaultChronicle(
47         chronicleContext =
48             DefaultChronicleContext(
49                 connectionProviders = connectionProviders,
50                 processorNodes = emptySet(),
51                 policySet = DefaultPolicySet(policies),
52                 dataTypeDescriptorSet =
53                     DefaultDataTypeDescriptorSet(
<lambda>null54                     connectionProviders.map { it.dataType.descriptor }.toSet()
55                 ),
56                 connectionContext = connectionContext
57             ),
58         policyEngine = ChroniclePolicyEngine(),
59         config =
60             DefaultChronicle.Config(
61                 policyMode = DefaultChronicle.Config.PolicyMode.STRICT,
62                 policyConformanceCheck = DefaultPolicyConformanceCheck()
63             ),
64         flags = flagsReader
65     )
66 
67     companion object {
68         @JvmField
69         @Volatile
70         @VisibleForTesting
71         var instance: ChronicleManager? = null
72 
73         @JvmOverloads
74         @JvmStatic
getInstancenull75         fun getInstance(connectionProviders: Set<ConnectionProvider>,
76                 policies: Set<Policy>,
77                 connectionContext: TypedMap = TypedMap()) =
78             instance
79                 ?: synchronized(this) {
80                     // double-checked locking
81                     instance
82                         ?: ChronicleManager(
83                             connectionProviders, policies, connectionContext).also{ instance = it }
84                 }
85     }
86 
<lambda>null87     fun failNewConnections(failNewConnections: Boolean) = updateFlags {
88         it.copy(failNewConnections = failNewConnections)
89     }
90 
updateFlagsnull91     private inline fun updateFlags(block: (Flags) -> Flags) {
92         do {
93             val before = flags.value
94             val after = block(before)
95         } while (!flags.compareAndSet(before, after))
96     }
97 }
98