10e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev/*
20e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev * Copyright (C) 2016 The Android Open Source Project
30e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev *
40e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev * Licensed under the Apache License, Version 2.0 (the "License");
50e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev * you may not use this file except in compliance with the License.
60e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev * You may obtain a copy of the License at
70e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev *
80e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev *      http://www.apache.org/licenses/LICENSE-2.0
90e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev *
100e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev * Unless required by applicable law or agreed to in writing, software
110e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev * distributed under the License is distributed on an "AS IS" BASIS,
120e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev * See the License for the specific language governing permissions and
140e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev * limitations under the License.
150e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev */
160e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
172579fb792b4d47555515459f372f63c4305ee2caPavel Maltsev#define LOG_TAG "automotive.vehicle@2.0-impl"
180e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
190e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev#include "VehicleObjectPool.h"
200e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
213ff5260601184d52a8c9a028d6a3af150d2a6757Mark Salyzyn#include <log/log.h>
220e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
230e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev#include "VehicleUtils.h"
240e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
250e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsevnamespace android {
260e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsevnamespace hardware {
272579fb792b4d47555515459f372f63c4305ee2caPavel Maltsevnamespace automotive {
280e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsevnamespace vehicle {
290e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsevnamespace V2_0 {
300e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
310e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel MaltsevVehiclePropValuePool::RecyclableType VehiclePropValuePool::obtain(
320e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        VehiclePropertyType type, size_t vecSize) {
330e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    return isDisposable(type, vecSize)
340e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev           ? obtainDisposable(type, vecSize)
350e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev           : obtainRecylable(type, vecSize);
360e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}
370e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
380e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel MaltsevVehiclePropValuePool::RecyclableType VehiclePropValuePool::obtain(
390e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        const VehiclePropValue& src) {
408e624b323c9808c6454cd2e76ffd3ca2ede5679cPavel Maltsev    if (src.prop == toInt(VehicleProperty::INVALID)) {
410e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        ALOGE("Unable to obtain an object from pool for unknown property");
420e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        return RecyclableType();
430e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    }
440e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    VehiclePropertyType type = getPropType(src.prop);
450e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    size_t vecSize = getVehicleRawValueVectorSize(src.value, type);;
460e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    auto dest = obtain(type, vecSize);
470e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
480e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    dest->prop = src.prop;
490e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    dest->areaId = src.areaId;
5054f2ac6994ffe6a12f54aa1404150af0640c1a60Steve Paik    dest->status = src.status;
510e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    dest->timestamp = src.timestamp;
520e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    copyVehicleRawValue(&dest->value, src.value);
530e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
540e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    return dest;
550e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}
560e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
570e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel MaltsevVehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainInt32(
580e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        int32_t value) {
590e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    auto val = obtain(VehiclePropertyType::INT32);
600e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    val->value.int32Values[0] = value;
610e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    return val;
620e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}
630e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
640e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel MaltsevVehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainInt64(
650e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        int64_t value) {
660e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    auto val = obtain(VehiclePropertyType::INT64);
670e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    val->value.int64Values[0] = value;
680e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    return val;
690e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}
700e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
710e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel MaltsevVehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainFloat(
720e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        float value)  {
730e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    auto val = obtain(VehiclePropertyType::FLOAT);
740e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    val->value.floatValues[0] = value;
750e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    return val;
760e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}
770e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
780e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel MaltsevVehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainString(
790e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        const char* cstr) {
800e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    auto val = obtain(VehiclePropertyType::STRING);
810e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    val->value.stringValue = cstr;
820e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    return val;
830e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}
840e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
85f21639f6e391c45c13345eee6cbf1df6579817d2Pavel MaltsevVehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainComplex() {
861ae977d6e87a88e1689d406636982e8296d68175Steve Paik    return obtain(VehiclePropertyType::MIXED);
87f21639f6e391c45c13345eee6cbf1df6579817d2Pavel Maltsev}
88f21639f6e391c45c13345eee6cbf1df6579817d2Pavel Maltsev
890e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel MaltsevVehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainRecylable(
900e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        VehiclePropertyType type, size_t vecSize) {
910e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    // VehiclePropertyType is not overlapping with vectorSize.
920e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    int32_t key = static_cast<int32_t>(type)
930e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev                  | static_cast<int32_t>(vecSize);
940e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
950e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    std::lock_guard<std::mutex> g(mLock);
960e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    auto it = mValueTypePools.find(key);
970e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
980e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    if (it == mValueTypePools.end()) {
990e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        auto newPool(std::make_unique<InternalPool>(type, vecSize));
1000e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        it = mValueTypePools.emplace(key, std::move(newPool)).first;
1010e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    }
1020e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    return it->second->obtain();
1030e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}
1040e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
1050e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel MaltsevVehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainBoolean(
1060e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        bool value)  {
1070e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    return obtainInt32(value);
1080e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}
1090e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
1100e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel MaltsevVehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainDisposable(
1110e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        VehiclePropertyType valueType, size_t vectorSize) const {
1120e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    return RecyclableType {
1130e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        createVehiclePropValue(valueType, vectorSize).release(),
1140e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        mDisposableDeleter
1150e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    };
1160e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}
1170e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
1180e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel MaltsevVehiclePropValuePool::RecyclableType VehiclePropValuePool::obtain(
1190e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        VehiclePropertyType type) {
1200e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    return obtain(type, 1);
1210e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}
1220e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
1230e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
1240e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsevvoid VehiclePropValuePool::InternalPool::recycle(VehiclePropValue* o) {
1250e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    if (o == nullptr) {
1260e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        ALOGE("Attempt to recycle nullptr");
1270e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        return;
1280e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    }
1290e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
1300e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    if (!check(&o->value)) {
1310e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        ALOGE("Discarding value for prop 0x%x because it contains "
1320e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev                  "data that is not consistent with this pool. "
133308515f65fcbc0592b3b7053dfbf7de6fbb9a806Pavel Maltsev                  "Expected type: %d, vector size: %zu",
1340e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev              o->prop, mPropType, mVectorSize);
1350e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        delete o;
1360e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    } else {
1370e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev        ObjectPool<VehiclePropValue>::recycle(o);
1380e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    }
1390e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}
1400e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
1410e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsevbool VehiclePropValuePool::InternalPool::check(VehiclePropValue::RawValue* v) {
1421ae977d6e87a88e1689d406636982e8296d68175Steve Paik    return check(&v->int32Values, (VehiclePropertyType::INT32 == mPropType ||
1431ae977d6e87a88e1689d406636982e8296d68175Steve Paik                                   VehiclePropertyType::INT32_VEC == mPropType ||
1441ae977d6e87a88e1689d406636982e8296d68175Steve Paik                                   VehiclePropertyType::BOOLEAN == mPropType)) &&
1451ae977d6e87a88e1689d406636982e8296d68175Steve Paik           check(&v->floatValues, (VehiclePropertyType::FLOAT == mPropType ||
1461ae977d6e87a88e1689d406636982e8296d68175Steve Paik                                   VehiclePropertyType::FLOAT_VEC == mPropType)) &&
1471ae977d6e87a88e1689d406636982e8296d68175Steve Paik           check(&v->int64Values, (VehiclePropertyType::INT64 == mPropType ||
1481ae977d6e87a88e1689d406636982e8296d68175Steve Paik                                   VehiclePropertyType::INT64_VEC == mPropType)) &&
1491ae977d6e87a88e1689d406636982e8296d68175Steve Paik           check(&v->bytes, VehiclePropertyType::BYTES == mPropType) && v->stringValue.size() == 0;
1500e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}
1510e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
1520e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel MaltsevVehiclePropValue* VehiclePropValuePool::InternalPool::createObject() {
1530e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev    return createVehiclePropValue(mPropType, mVectorSize).release();
1540e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}
1550e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev
1560e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}  // namespace V2_0
1570e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}  // namespace vehicle
1582579fb792b4d47555515459f372f63c4305ee2caPavel Maltsev}  // namespace automotive
1590e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}  // namespace hardware
1600e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev}  // namespace android
161