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->timestamp = src.timestamp;
51 copyVehicleRawValue(&dest->value, src.value);
52
53 return dest;
54 }
55
obtainInt32(int32_t value)56 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainInt32(
57 int32_t value) {
58 auto val = obtain(VehiclePropertyType::INT32);
59 val->value.int32Values[0] = value;
60 return val;
61 }
62
obtainInt64(int64_t value)63 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainInt64(
64 int64_t value) {
65 auto val = obtain(VehiclePropertyType::INT64);
66 val->value.int64Values[0] = value;
67 return val;
68 }
69
obtainFloat(float value)70 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainFloat(
71 float value) {
72 auto val = obtain(VehiclePropertyType::FLOAT);
73 val->value.floatValues[0] = value;
74 return val;
75 }
76
obtainString(const char * cstr)77 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainString(
78 const char* cstr) {
79 auto val = obtain(VehiclePropertyType::STRING);
80 val->value.stringValue = cstr;
81 return val;
82 }
83
obtainComplex()84 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainComplex() {
85 return obtain(VehiclePropertyType::COMPLEX);
86 }
87
obtainRecylable(VehiclePropertyType type,size_t vecSize)88 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainRecylable(
89 VehiclePropertyType type, size_t vecSize) {
90 // VehiclePropertyType is not overlapping with vectorSize.
91 int32_t key = static_cast<int32_t>(type)
92 | static_cast<int32_t>(vecSize);
93
94 std::lock_guard<std::mutex> g(mLock);
95 auto it = mValueTypePools.find(key);
96
97 if (it == mValueTypePools.end()) {
98 auto newPool(std::make_unique<InternalPool>(type, vecSize));
99 it = mValueTypePools.emplace(key, std::move(newPool)).first;
100 }
101 return it->second->obtain();
102 }
103
obtainBoolean(bool value)104 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainBoolean(
105 bool value) {
106 return obtainInt32(value);
107 }
108
obtainDisposable(VehiclePropertyType valueType,size_t vectorSize) const109 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainDisposable(
110 VehiclePropertyType valueType, size_t vectorSize) const {
111 return RecyclableType {
112 createVehiclePropValue(valueType, vectorSize).release(),
113 mDisposableDeleter
114 };
115 }
116
obtain(VehiclePropertyType type)117 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtain(
118 VehiclePropertyType type) {
119 return obtain(type, 1);
120 }
121
122
recycle(VehiclePropValue * o)123 void VehiclePropValuePool::InternalPool::recycle(VehiclePropValue* o) {
124 if (o == nullptr) {
125 ALOGE("Attempt to recycle nullptr");
126 return;
127 }
128
129 if (!check(&o->value)) {
130 ALOGE("Discarding value for prop 0x%x because it contains "
131 "data that is not consistent with this pool. "
132 "Expected type: %d, vector size: %zu",
133 o->prop, mPropType, mVectorSize);
134 delete o;
135 } else {
136 ObjectPool<VehiclePropValue>::recycle(o);
137 }
138 }
139
check(VehiclePropValue::RawValue * v)140 bool VehiclePropValuePool::InternalPool::check(VehiclePropValue::RawValue* v) {
141 return check(&v->int32Values,
142 (VehiclePropertyType::INT32 == mPropType
143 || VehiclePropertyType::INT32_VEC == mPropType
144 || VehiclePropertyType::BOOLEAN == mPropType))
145 && check(&v->floatValues,
146 (VehiclePropertyType::FLOAT == mPropType
147 || VehiclePropertyType::FLOAT_VEC == mPropType))
148 && check(&v->int64Values,
149 VehiclePropertyType::INT64 == mPropType)
150 && check(&v->bytes,
151 VehiclePropertyType::BYTES == mPropType)
152 && v->stringValue.size() == 0;
153 }
154
createObject()155 VehiclePropValue* VehiclePropValuePool::InternalPool::createObject() {
156 return createVehiclePropValue(mPropType, mVectorSize).release();
157 }
158
159 } // namespace V2_0
160 } // namespace vehicle
161 } // namespace automotive
162 } // namespace hardware
163 } // namespace android
164