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