1 /*
2  * Copyright (C) 2016 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 #define LOG_TAG "automotive.vehicle@2.0-impl"
18 
19 #include "VehicleObjectPool.h"
20 
21 #include <log/log.h>
22 
23 #include "VehicleUtils.h"
24 
25 namespace android {
26 namespace hardware {
27 namespace automotive {
28 namespace vehicle {
29 namespace V2_0 {
30 
obtain(VehiclePropertyType type,size_t vecSize)31 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtain(
32         VehiclePropertyType type, size_t vecSize) {
33     return isDisposable(type, vecSize)
34            ? obtainDisposable(type, vecSize)
35            : obtainRecylable(type, vecSize);
36 }
37 
obtain(const VehiclePropValue & src)38 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtain(
39         const VehiclePropValue& src) {
40     if (src.prop == toInt(VehicleProperty::INVALID)) {
41         ALOGE("Unable to obtain an object from pool for unknown property");
42         return RecyclableType();
43     }
44     VehiclePropertyType type = getPropType(src.prop);
45     size_t vecSize = getVehicleRawValueVectorSize(src.value, type);;
46     auto dest = obtain(type, vecSize);
47 
48     dest->prop = src.prop;
49     dest->areaId = src.areaId;
50     dest->status = src.status;
51     dest->timestamp = src.timestamp;
52     copyVehicleRawValue(&dest->value, src.value);
53 
54     return dest;
55 }
56 
obtainInt32(int32_t value)57 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainInt32(
58         int32_t value) {
59     auto val = obtain(VehiclePropertyType::INT32);
60     val->value.int32Values[0] = value;
61     return val;
62 }
63 
obtainInt64(int64_t value)64 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainInt64(
65         int64_t value) {
66     auto val = obtain(VehiclePropertyType::INT64);
67     val->value.int64Values[0] = value;
68     return val;
69 }
70 
obtainFloat(float value)71 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainFloat(
72         float value)  {
73     auto val = obtain(VehiclePropertyType::FLOAT);
74     val->value.floatValues[0] = value;
75     return val;
76 }
77 
obtainString(const char * cstr)78 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainString(
79         const char* cstr) {
80     auto val = obtain(VehiclePropertyType::STRING);
81     val->value.stringValue = cstr;
82     return val;
83 }
84 
obtainComplex()85 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainComplex() {
86     return obtain(VehiclePropertyType::MIXED);
87 }
88 
obtainRecylable(VehiclePropertyType type,size_t vecSize)89 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainRecylable(
90         VehiclePropertyType type, size_t vecSize) {
91     // VehiclePropertyType is not overlapping with vectorSize.
92     int32_t key = static_cast<int32_t>(type)
93                   | static_cast<int32_t>(vecSize);
94 
95     std::lock_guard<std::mutex> g(mLock);
96     auto it = mValueTypePools.find(key);
97 
98     if (it == mValueTypePools.end()) {
99         auto newPool(std::make_unique<InternalPool>(type, vecSize));
100         it = mValueTypePools.emplace(key, std::move(newPool)).first;
101     }
102     return it->second->obtain();
103 }
104 
obtainBoolean(bool value)105 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainBoolean(
106         bool value)  {
107     return obtainInt32(value);
108 }
109 
obtainDisposable(VehiclePropertyType valueType,size_t vectorSize) const110 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainDisposable(
111         VehiclePropertyType valueType, size_t vectorSize) const {
112     return RecyclableType {
113         createVehiclePropValue(valueType, vectorSize).release(),
114         mDisposableDeleter
115     };
116 }
117 
obtain(VehiclePropertyType type)118 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtain(
119         VehiclePropertyType type) {
120     return obtain(type, 1);
121 }
122 
123 
recycle(VehiclePropValue * o)124 void VehiclePropValuePool::InternalPool::recycle(VehiclePropValue* o) {
125     if (o == nullptr) {
126         ALOGE("Attempt to recycle nullptr");
127         return;
128     }
129 
130     if (!check(&o->value)) {
131         ALOGE("Discarding value for prop 0x%x because it contains "
132                   "data that is not consistent with this pool. "
133                   "Expected type: %d, vector size: %zu",
134               o->prop, toInt(mPropType), mVectorSize);
135         delete o;
136     } else {
137         ObjectPool<VehiclePropValue>::recycle(o);
138     }
139 }
140 
check(VehiclePropValue::RawValue * v)141 bool VehiclePropValuePool::InternalPool::check(VehiclePropValue::RawValue* v) {
142     return check(&v->int32Values, (VehiclePropertyType::INT32 == mPropType ||
143                                    VehiclePropertyType::INT32_VEC == mPropType ||
144                                    VehiclePropertyType::BOOLEAN == mPropType)) &&
145            check(&v->floatValues, (VehiclePropertyType::FLOAT == mPropType ||
146                                    VehiclePropertyType::FLOAT_VEC == mPropType)) &&
147            check(&v->int64Values, (VehiclePropertyType::INT64 == mPropType ||
148                                    VehiclePropertyType::INT64_VEC == mPropType)) &&
149            check(&v->bytes, VehiclePropertyType::BYTES == mPropType) && v->stringValue.size() == 0;
150 }
151 
createObject()152 VehiclePropValue* VehiclePropValuePool::InternalPool::createObject() {
153     return createVehiclePropValue(mPropType, mVectorSize).release();
154 }
155 
156 }  // namespace V2_0
157 }  // namespace vehicle
158 }  // namespace automotive
159 }  // namespace hardware
160 }  // namespace android
161