• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #ifndef android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehiclePropertyStore_H_
18 #define android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehiclePropertyStore_H_
19 
20 #include <cstdint>
21 #include <map>
22 #include <memory>
23 #include <mutex>
24 #include <unordered_map>
25 
26 #include <VehicleHalTypes.h>
27 #include <VehicleObjectPool.h>
28 #include <VehicleUtils.h>
29 #include <android-base/result.h>
30 #include <android-base/thread_annotations.h>
31 
32 namespace android {
33 namespace hardware {
34 namespace automotive {
35 namespace vehicle {
36 
37 // Encapsulates work related to storing and accessing configuration, storing and modifying
38 // vehicle property values.
39 //
40 // VehiclePropertyValues stored in a sorted map thus it makes easier to get range of values, e.g.
41 // to get value for all areas for particular property.
42 //
43 // This class is thread-safe, however it uses blocking synchronization across all methods.
44 class VehiclePropertyStore final {
45   public:
46     using ValueResultType = VhalResult<VehiclePropValuePool::RecyclableType>;
47     using ValuesResultType = VhalResult<std::vector<VehiclePropValuePool::RecyclableType>>;
48 
49     enum class EventMode : uint8_t {
50         /**
51          * Only invoke OnValueChangeCallback if the new property value (ignoring timestamp) is
52          * different than the existing value.
53          *
54          * This should be used for regular cases.
55          */
56         ON_VALUE_CHANGE,
57         /**
58          * Always invoke OnValueChangeCallback.
59          *
60          * This should be used for the special properties that are used for delivering event, e.g.
61          * HW_KEY_INPUT.
62          */
63         ALWAYS,
64         /**
65          * Never invoke OnValueChangeCallback.
66          *
67          * This should be used for continuous property subscription when the sample rate for the
68          * subscription is smaller than the refresh rate for the property. E.g., the vehicle speed
69          * is refreshed at 20hz, but we are only subscribing at 10hz. In this case, we want to
70          * generate the property change event at 10hz, not 20hz, but we still want to refresh the
71          * timestamp (via writeValue) at 20hz.
72          */
73         NEVER,
74     };
75 
VehiclePropertyStore(std::shared_ptr<VehiclePropValuePool> valuePool)76     explicit VehiclePropertyStore(std::shared_ptr<VehiclePropValuePool> valuePool)
77         : mValuePool(valuePool) {}
78 
79     ~VehiclePropertyStore();
80 
81     // Callback when a property value has been updated or a new value added.
82     using OnValueChangeCallback = std::function<void(
83             const aidl::android::hardware::automotive::vehicle::VehiclePropValue&)>;
84 
85     // Function that used to calculate unique token for given VehiclePropValue.
86     using TokenFunction = std::function<int64_t(
87             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value)>;
88 
89     // Register the given property according to the config. A property has to be registered first
90     // before write/read. If tokenFunc is not nullptr, it would be used to generate a unique
91     // property token to act as the key the property store. Otherwise, {propertyID, areaID} would be
92     // used as the key.
93     void registerProperty(
94             const aidl::android::hardware::automotive::vehicle::VehiclePropConfig& config,
95             TokenFunction tokenFunc = nullptr);
96 
97     // Stores provided value. Returns error if config wasn't registered. If 'updateStatus' is
98     // true, the 'status' in 'propValue' would be stored. Otherwise, if this is a new value,
99     // 'status' would be initialized to {@code VehiclePropertyStatus::AVAILABLE}, if this is to
100     // override an existing value, the status for the existing value would be used for the
101     // overridden value.
102     // 'EventMode' controls whether the 'OnValueChangeCallback' will be called for this operation.
103     VhalResult<void> writeValue(VehiclePropValuePool::RecyclableType propValue,
104                                 bool updateStatus = false,
105                                 EventMode mode = EventMode::ON_VALUE_CHANGE);
106 
107     // Remove a given property value from the property store. The 'propValue' would be used to
108     // generate the key for the value to remove.
109     void removeValue(
110             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue);
111 
112     // Remove all the values for the property.
113     void removeValuesForProperty(int32_t propId);
114 
115     // Read all the stored values.
116     std::vector<VehiclePropValuePool::RecyclableType> readAllValues() const;
117 
118     // Read all the values for the property.
119     ValuesResultType readValuesForProperty(int32_t propId) const;
120 
121     // Read the value for the requested property. Returns {@code StatusCode::NOT_AVAILABLE} if the
122     // value has not been set yet. Returns {@code StatusCode::INVALID_ARG} if the property is
123     // not configured.
124     ValueResultType readValue(
125             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& request) const;
126 
127     // Read the value for the requested property. Returns {@code StatusCode::NOT_AVAILABLE} if the
128     // value has not been set yet. Returns {@code StatusCode::INVALID_ARG} if the property is
129     // not configured.
130     ValueResultType readValue(int32_t prop, int32_t area = 0, int64_t token = 0) const;
131 
132     // Get all property configs.
133     std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig> getAllConfigs()
134             const;
135 
136     // Get the property config for the requested property.
137     android::base::Result<const aidl::android::hardware::automotive::vehicle::VehiclePropConfig*,
138                           VhalError>
139     getConfig(int32_t propId) const;
140 
141     // Set a callback that would be called when a property value has been updated.
142     void setOnValueChangeCallback(const OnValueChangeCallback& callback);
143 
getValuePool()144     inline std::shared_ptr<VehiclePropValuePool> getValuePool() { return mValuePool; }
145 
146   private:
147     struct RecordId {
148         int32_t area;
149         int64_t token;
150 
151         std::string toString() const;
152 
153         bool operator==(const RecordId& other) const;
154     };
155 
156     struct RecordIdHash {
157         size_t operator()(RecordId const& recordId) const;
158     };
159 
160     struct Record {
161         aidl::android::hardware::automotive::vehicle::VehiclePropConfig propConfig;
162         TokenFunction tokenFunction;
163         std::unordered_map<RecordId, VehiclePropValuePool::RecyclableType, RecordIdHash> values;
164     };
165 
166     // {@code VehiclePropValuePool} is thread-safe.
167     std::shared_ptr<VehiclePropValuePool> mValuePool;
168     mutable std::mutex mLock;
169     std::unordered_map<int32_t, Record> mRecordsByPropId GUARDED_BY(mLock);
170     OnValueChangeCallback mOnValueChangeCallback GUARDED_BY(mLock);
171 
172     const Record* getRecordLocked(int32_t propId) const;
173 
174     Record* getRecordLocked(int32_t propId);
175 
176     RecordId getRecordIdLocked(
177             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue,
178             const Record& record) const;
179 
180     ValueResultType readValueLocked(const RecordId& recId, const Record& record) const;
181 };
182 
183 }  // namespace vehicle
184 }  // namespace automotive
185 }  // namespace hardware
186 }  // namespace android
187 
188 #endif  // android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehiclePropertyStore_H_
189