Home | History | Annotate | Download | only in src
      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 
     28 bool VehiclePropertyStore::RecordId::operator==(const VehiclePropertyStore::RecordId& other) const {
     29     return prop == other.prop && area == other.area && token == other.token;
     30 }
     31 
     32 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 
     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 
     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 
     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 
     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 
     78 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 
     88 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 
     99 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 
    107 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 
    116 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 
    126 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 
    132 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 
    141 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 
    158 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 
    164 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