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)44 bool VehiclePropertyStore::writeValue(const VehiclePropValue& propValue) {
45 MuxGuard g(mLock);
46 if (!mConfigs.count(propValue.prop)) return false;
47
48 RecordId recId = getRecordIdLocked(propValue);
49 VehiclePropValue* valueToUpdate = const_cast<VehiclePropValue*>(getValueOrNullLocked(recId));
50 if (valueToUpdate == nullptr) {
51 mPropertyValues.insert({ recId, propValue });
52 } else {
53 valueToUpdate->timestamp = propValue.timestamp;
54 valueToUpdate->value = propValue.value;
55 }
56 return true;
57 }
58
removeValue(const VehiclePropValue & propValue)59 void VehiclePropertyStore::removeValue(const VehiclePropValue& propValue) {
60 MuxGuard g(mLock);
61 RecordId recId = getRecordIdLocked(propValue);
62 auto it = mPropertyValues.find(recId);
63 if (it != mPropertyValues.end()) {
64 mPropertyValues.erase(it);
65 }
66 }
67
removeValuesForProperty(int32_t propId)68 void VehiclePropertyStore::removeValuesForProperty(int32_t propId) {
69 MuxGuard g(mLock);
70 auto range = findRangeLocked(propId);
71 mPropertyValues.erase(range.first, range.second);
72 }
73
readAllValues() const74 std::vector<VehiclePropValue> VehiclePropertyStore::readAllValues() const {
75 MuxGuard g(mLock);
76 std::vector<VehiclePropValue> allValues;
77 allValues.reserve(mPropertyValues.size());
78 for (auto&& it : mPropertyValues) {
79 allValues.push_back(it.second);
80 }
81 return allValues;
82 }
83
readValuesForProperty(int32_t propId) const84 std::vector<VehiclePropValue> VehiclePropertyStore::readValuesForProperty(int32_t propId) const {
85 std::vector<VehiclePropValue> values;
86 MuxGuard g(mLock);
87 auto range = findRangeLocked(propId);
88 for (auto it = range.first; it != range.second; ++it) {
89 values.push_back(it->second);
90 }
91
92 return values;
93 }
94
readValueOrNull(const VehiclePropValue & request) const95 std::unique_ptr<VehiclePropValue> VehiclePropertyStore::readValueOrNull(
96 const VehiclePropValue& request) const {
97 MuxGuard g(mLock);
98 RecordId recId = getRecordIdLocked(request);
99 const VehiclePropValue* internalValue = getValueOrNullLocked(recId);
100 return internalValue ? std::make_unique<VehiclePropValue>(*internalValue) : nullptr;
101 }
102
readValueOrNull(int32_t prop,int32_t area,int64_t token) const103 std::unique_ptr<VehiclePropValue> VehiclePropertyStore::readValueOrNull(
104 int32_t prop, int32_t area, int64_t token) const {
105 RecordId recId = {prop, isGlobalProp(prop) ? 0 : area, token };
106 MuxGuard g(mLock);
107 const VehiclePropValue* internalValue = getValueOrNullLocked(recId);
108 return internalValue ? std::make_unique<VehiclePropValue>(*internalValue) : nullptr;
109 }
110
111
getAllConfigs() const112 std::vector<VehiclePropConfig> VehiclePropertyStore::getAllConfigs() const {
113 MuxGuard g(mLock);
114 std::vector<VehiclePropConfig> configs;
115 configs.reserve(mConfigs.size());
116 for (auto&& recordConfigIt: mConfigs) {
117 configs.push_back(recordConfigIt.second.propConfig);
118 }
119 return configs;
120 }
121
getConfigOrNull(int32_t propId) const122 const VehiclePropConfig* VehiclePropertyStore::getConfigOrNull(int32_t propId) const {
123 MuxGuard g(mLock);
124 auto recordConfigIt = mConfigs.find(propId);
125 return recordConfigIt != mConfigs.end() ? &recordConfigIt->second.propConfig : nullptr;
126 }
127
getConfigOrDie(int32_t propId) const128 const VehiclePropConfig* VehiclePropertyStore::getConfigOrDie(int32_t propId) const {
129 auto cfg = getConfigOrNull(propId);
130 if (!cfg) {
131 ALOGW("%s: config not found for property: 0x%x", __func__, propId);
132 abort();
133 }
134 return cfg;
135 }
136
getRecordIdLocked(const VehiclePropValue & valuePrototype) const137 VehiclePropertyStore::RecordId VehiclePropertyStore::getRecordIdLocked(
138 const VehiclePropValue& valuePrototype) const {
139 RecordId recId = {
140 .prop = valuePrototype.prop,
141 .area = isGlobalProp(valuePrototype.prop) ? 0 : valuePrototype.areaId,
142 .token = 0
143 };
144
145 auto it = mConfigs.find(recId.prop);
146 if (it == mConfigs.end()) return {};
147
148 if (it->second.tokenFunction != nullptr) {
149 recId.token = it->second.tokenFunction(valuePrototype);
150 }
151 return recId;
152 }
153
getValueOrNullLocked(const VehiclePropertyStore::RecordId & recId) const154 const VehiclePropValue* VehiclePropertyStore::getValueOrNullLocked(
155 const VehiclePropertyStore::RecordId& recId) const {
156 auto it = mPropertyValues.find(recId);
157 return it == mPropertyValues.end() ? nullptr : &it->second;
158 }
159
findRangeLocked(int32_t propId) const160 VehiclePropertyStore::PropertyMapRange VehiclePropertyStore::findRangeLocked(int32_t propId) const {
161 // Based on the fact that mPropertyValues is a sorted map by RecordId.
162 auto beginIt = mPropertyValues.lower_bound( RecordId { propId, INT32_MIN, 0 });
163 auto endIt = mPropertyValues.lower_bound( RecordId { propId + 1, INT32_MIN, 0 });
164
165 return PropertyMapRange { beginIt, endIt };
166 }
167
168 } // namespace V2_0
169 } // namespace vehicle
170 } // namespace automotive
171 } // namespace hardware
172 } // namespace android
173