1 /*
2 * Copyright (C) 2017 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 #define LOG_TAG "VehiclePropertyStore"
17 #include <log/log.h>
18
19 #include <common/include/vhal_v2_0/VehicleUtils.h>
20 #include "VehiclePropertyStore.h"
21
22 namespace android {
23 namespace hardware {
24 namespace automotive {
25 namespace vehicle {
26 namespace V2_0 {
27
operator ==(const VehiclePropertyStore::RecordId & other) const28 bool VehiclePropertyStore::RecordId::operator==(const VehiclePropertyStore::RecordId& other) const {
29 return prop == other.prop && area == other.area && token == other.token;
30 }
31
operator <(const VehiclePropertyStore::RecordId & other) const32 bool VehiclePropertyStore::RecordId::operator<(const VehiclePropertyStore::RecordId& other) const {
33 return prop < other.prop
34 || (prop == other.prop && area < other.area)
35 || (prop == other.prop && area == other.area && token < other.token);
36 }
37
registerProperty(const VehiclePropConfig & config,VehiclePropertyStore::TokenFunction tokenFunc)38 void VehiclePropertyStore::registerProperty(const VehiclePropConfig& config,
39 VehiclePropertyStore::TokenFunction tokenFunc) {
40 MuxGuard g(mLock);
41 mConfigs.insert({ config.prop, RecordConfig { config, tokenFunc } });
42 }
43
writeValue(const VehiclePropValue & propValue,bool updateStatus)44 bool VehiclePropertyStore::writeValue(const VehiclePropValue& propValue,
45 bool updateStatus) {
46 MuxGuard g(mLock);
47 if (!mConfigs.count(propValue.prop)) return false;
48
49 RecordId recId = getRecordIdLocked(propValue);
50 VehiclePropValue* valueToUpdate = const_cast<VehiclePropValue*>(getValueOrNullLocked(recId));
51 if (valueToUpdate == nullptr) {
52 mPropertyValues.insert({ recId, propValue });
53 } else {
54 valueToUpdate->timestamp = propValue.timestamp;
55 valueToUpdate->value = propValue.value;
56 if (updateStatus) {
57 valueToUpdate->status = propValue.status;
58 }
59 }
60 return true;
61 }
62
removeValue(const VehiclePropValue & propValue)63 void VehiclePropertyStore::removeValue(const VehiclePropValue& propValue) {
64 MuxGuard g(mLock);
65 RecordId recId = getRecordIdLocked(propValue);
66 auto it = mPropertyValues.find(recId);
67 if (it != mPropertyValues.end()) {
68 mPropertyValues.erase(it);
69 }
70 }
71
removeValuesForProperty(int32_t propId)72 void VehiclePropertyStore::removeValuesForProperty(int32_t propId) {
73 MuxGuard g(mLock);
74 auto range = findRangeLocked(propId);
75 mPropertyValues.erase(range.first, range.second);
76 }
77
readAllValues() const78 std::vector<VehiclePropValue> VehiclePropertyStore::readAllValues() const {
79 MuxGuard g(mLock);
80 std::vector<VehiclePropValue> allValues;
81 allValues.reserve(mPropertyValues.size());
82 for (auto&& it : mPropertyValues) {
83 allValues.push_back(it.second);
84 }
85 return allValues;
86 }
87
readValuesForProperty(int32_t propId) const88 std::vector<VehiclePropValue> VehiclePropertyStore::readValuesForProperty(int32_t propId) const {
89 std::vector<VehiclePropValue> values;
90 MuxGuard g(mLock);
91 auto range = findRangeLocked(propId);
92 for (auto it = range.first; it != range.second; ++it) {
93 values.push_back(it->second);
94 }
95
96 return values;
97 }
98
readValueOrNull(const VehiclePropValue & request) const99 std::unique_ptr<VehiclePropValue> VehiclePropertyStore::readValueOrNull(
100 const VehiclePropValue& request) const {
101 MuxGuard g(mLock);
102 RecordId recId = getRecordIdLocked(request);
103 const VehiclePropValue* internalValue = getValueOrNullLocked(recId);
104 return internalValue ? std::make_unique<VehiclePropValue>(*internalValue) : nullptr;
105 }
106
readValueOrNull(int32_t prop,int32_t area,int64_t token) const107 std::unique_ptr<VehiclePropValue> VehiclePropertyStore::readValueOrNull(
108 int32_t prop, int32_t area, int64_t token) const {
109 RecordId recId = {prop, isGlobalProp(prop) ? 0 : area, token };
110 MuxGuard g(mLock);
111 const VehiclePropValue* internalValue = getValueOrNullLocked(recId);
112 return internalValue ? std::make_unique<VehiclePropValue>(*internalValue) : nullptr;
113 }
114
115
getAllConfigs() const116 std::vector<VehiclePropConfig> VehiclePropertyStore::getAllConfigs() const {
117 MuxGuard g(mLock);
118 std::vector<VehiclePropConfig> configs;
119 configs.reserve(mConfigs.size());
120 for (auto&& recordConfigIt: mConfigs) {
121 configs.push_back(recordConfigIt.second.propConfig);
122 }
123 return configs;
124 }
125
getConfigOrNull(int32_t propId) const126 const VehiclePropConfig* VehiclePropertyStore::getConfigOrNull(int32_t propId) const {
127 MuxGuard g(mLock);
128 auto recordConfigIt = mConfigs.find(propId);
129 return recordConfigIt != mConfigs.end() ? &recordConfigIt->second.propConfig : nullptr;
130 }
131
getConfigOrDie(int32_t propId) const132 const VehiclePropConfig* VehiclePropertyStore::getConfigOrDie(int32_t propId) const {
133 auto cfg = getConfigOrNull(propId);
134 if (!cfg) {
135 ALOGW("%s: config not found for property: 0x%x", __func__, propId);
136 abort();
137 }
138 return cfg;
139 }
140
getRecordIdLocked(const VehiclePropValue & valuePrototype) const141 VehiclePropertyStore::RecordId VehiclePropertyStore::getRecordIdLocked(
142 const VehiclePropValue& valuePrototype) const {
143 RecordId recId = {
144 .prop = valuePrototype.prop,
145 .area = isGlobalProp(valuePrototype.prop) ? 0 : valuePrototype.areaId,
146 .token = 0
147 };
148
149 auto it = mConfigs.find(recId.prop);
150 if (it == mConfigs.end()) return {};
151
152 if (it->second.tokenFunction != nullptr) {
153 recId.token = it->second.tokenFunction(valuePrototype);
154 }
155 return recId;
156 }
157
getValueOrNullLocked(const VehiclePropertyStore::RecordId & recId) const158 const VehiclePropValue* VehiclePropertyStore::getValueOrNullLocked(
159 const VehiclePropertyStore::RecordId& recId) const {
160 auto it = mPropertyValues.find(recId);
161 return it == mPropertyValues.end() ? nullptr : &it->second;
162 }
163
findRangeLocked(int32_t propId) const164 VehiclePropertyStore::PropertyMapRange VehiclePropertyStore::findRangeLocked(int32_t propId) const {
165 // Based on the fact that mPropertyValues is a sorted map by RecordId.
166 auto beginIt = mPropertyValues.lower_bound( RecordId { propId, INT32_MIN, 0 });
167 auto endIt = mPropertyValues.lower_bound( RecordId { propId + 1, INT32_MIN, 0 });
168
169 return PropertyMapRange { beginIt, endIt };
170 }
171
172 } // namespace V2_0
173 } // namespace vehicle
174 } // namespace automotive
175 } // namespace hardware
176 } // namespace android
177