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