• 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 or OnValuesChangeCallback if the new property value
52          * (ignoring timestamp) is different than the existing value.
53          *
54          * This should be used for regular cases.
55          */
56         ON_VALUE_CHANGE,
57         /**
58          * Always invoke OnValueChangeCallback or OnValuesChangeCallback.
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 or OnValuesChangeCalblack.
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     // Callback when one or more property values have been updated or new values added.
86     using OnValuesChangeCallback = std::function<void(
87             std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>)>;
88 
89     // Function that used to calculate unique token for given VehiclePropValue.
90     using TokenFunction = std::function<int64_t(
91             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value)>;
92 
93     // Register the given property according to the config. A property has to be registered first
94     // before write/read. If tokenFunc is not nullptr, it would be used to generate a unique
95     // property token to act as the key the property store. Otherwise, {propertyID, areaID} would be
96     // used as the key.
97     void registerProperty(
98             const aidl::android::hardware::automotive::vehicle::VehiclePropConfig& config,
99             TokenFunction tokenFunc = nullptr) EXCLUDES(mLock);
100 
101     // Stores provided value. Returns error if config wasn't registered. If 'updateStatus' is
102     // true, the 'status' in 'propValue' would be stored. Otherwise, if this is a new value,
103     // 'status' would be initialized to {@code VehiclePropertyStatus::AVAILABLE}, if this is to
104     // override an existing value, the status for the existing value would be used for the
105     // overridden value.
106     // 'EventMode' controls whether the 'OnValueChangeCallback' or 'OnValuesChangeCallback' will be
107     // called for this operation.
108     // If 'useCurrentTimestamp' is true, the property value will be set to the current timestamp.
109     VhalResult<void> writeValue(VehiclePropValuePool::RecyclableType propValue,
110                                 bool updateStatus = false,
111                                 EventMode mode = EventMode::ON_VALUE_CHANGE,
112                                 bool useCurrentTimestamp = false) EXCLUDES(mLock);
113 
114     // Refresh the timestamp for the stored property value for [propId, areaId]. If eventMode is
115     // always, generates the property update event, otherwise, only update the stored timestamp
116     // without generating event. This operation is atomic with other writeValue operations.
117     void refreshTimestamp(int32_t propId, int32_t areaId, EventMode eventMode) EXCLUDES(mLock);
118 
119     // Refresh the timestamp for multiple [propId, areaId]s.
120     void refreshTimestamps(
121             std::unordered_map<PropIdAreaId, EventMode, PropIdAreaIdHash> eventModeByPropIdAreaId)
122             EXCLUDES(mLock);
123 
124     // Remove a given property value from the property store. The 'propValue' would be used to
125     // generate the key for the value to remove.
126     void removeValue(
127             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue)
128             EXCLUDES(mLock);
129 
130     // Remove all the values for the property.
131     void removeValuesForProperty(int32_t propId) EXCLUDES(mLock);
132 
133     // Read all the stored values.
134     std::vector<VehiclePropValuePool::RecyclableType> readAllValues() const EXCLUDES(mLock);
135 
136     // Read all the values for the property.
137     ValuesResultType readValuesForProperty(int32_t propId) const EXCLUDES(mLock);
138 
139     // Read the value for the requested property. Returns {@code StatusCode::NOT_AVAILABLE} if the
140     // value has not been set yet. Returns {@code StatusCode::INVALID_ARG} if the property is
141     // not configured.
142     ValueResultType readValue(
143             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& request) const
144             EXCLUDES(mLock);
145 
146     // Read the value for the requested property. Returns {@code StatusCode::NOT_AVAILABLE} if the
147     // value has not been set yet. Returns {@code StatusCode::INVALID_ARG} if the property is
148     // not configured.
149     ValueResultType readValue(int32_t prop, int32_t area = 0, int64_t token = 0) const
150             EXCLUDES(mLock);
151 
152     // Get all property configs.
153     std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig> getAllConfigs()
154             const EXCLUDES(mLock);
155 
156     // Deprecated, use getPropConfig instead. This is unsafe to use if registerProperty overwrites
157     // an existing config.
158     android::base::Result<const aidl::android::hardware::automotive::vehicle::VehiclePropConfig*,
159                           VhalError>
160     getConfig(int32_t propId) const EXCLUDES(mLock);
161 
162     // Get the property config for the requested property.
163     android::base::Result<aidl::android::hardware::automotive::vehicle::VehiclePropConfig,
164                           VhalError>
165     getPropConfig(int32_t propId) const EXCLUDES(mLock);
166 
167     // Set a callback that would be called when a property value has been updated.
168     void setOnValueChangeCallback(const OnValueChangeCallback& callback) EXCLUDES(mLock);
169 
170     // Set a callback that would be called when one or more property values have been updated.
171     // For backward compatibility, this is optional. If this is not set, then multiple property
172     // updates will be delivered through multiple OnValueChangeCallback instead.
173     // It is recommended to set this and batch the property update events for better performance.
174     // If this is set, then OnValueChangeCallback will not be used.
175     void setOnValuesChangeCallback(const OnValuesChangeCallback& callback) EXCLUDES(mLock);
176 
getValuePool()177     inline std::shared_ptr<VehiclePropValuePool> getValuePool() { return mValuePool; }
178 
179   private:
180     struct RecordId {
181         int32_t area;
182         int64_t token;
183 
184         std::string toString() const;
185 
186         bool operator==(const RecordId& other) const;
187     };
188 
189     struct RecordIdHash {
190         size_t operator()(RecordId const& recordId) const;
191     };
192 
193     struct Record {
194         aidl::android::hardware::automotive::vehicle::VehiclePropConfig propConfig;
195         TokenFunction tokenFunction;
196         std::unordered_map<RecordId, VehiclePropValuePool::RecyclableType, RecordIdHash> values;
197     };
198 
199     // {@code VehiclePropValuePool} is thread-safe.
200     std::shared_ptr<VehiclePropValuePool> mValuePool;
201     mutable std::mutex mLock;
202     std::unordered_map<int32_t, Record> mRecordsByPropId GUARDED_BY(mLock);
203     OnValueChangeCallback mOnValueChangeCallback GUARDED_BY(mLock);
204     OnValuesChangeCallback mOnValuesChangeCallback GUARDED_BY(mLock);
205 
206     const Record* getRecordLocked(int32_t propId) const;
207 
208     Record* getRecordLocked(int32_t propId);
209 
210     RecordId getRecordIdLocked(
211             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue,
212             const Record& record) const;
213 
214     ValueResultType readValueLocked(const RecordId& recId, const Record& record) const;
215 };
216 
217 }  // namespace vehicle
218 }  // namespace automotive
219 }  // namespace hardware
220 }  // namespace android
221 
222 #endif  // android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehiclePropertyStore_H_
223