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 auto dest = obtain(type, vectorSize);
59
60 dest->prop = propId;
61 dest->areaId = src.areaId;
62 dest->status = src.status;
63 dest->timestamp = src.timestamp;
64 copyVehicleRawValue(&dest->value, src.value);
65
66 return dest;
67 }
68
obtainInt32(int32_t value)69 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainInt32(int32_t value) {
70 auto val = obtain(VehiclePropertyType::INT32);
71 val->value.int32Values[0] = value;
72 return val;
73 }
74
obtainInt64(int64_t value)75 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainInt64(int64_t value) {
76 auto val = obtain(VehiclePropertyType::INT64);
77 val->value.int64Values[0] = value;
78 return val;
79 }
80
obtainFloat(float value)81 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainFloat(float value) {
82 auto val = obtain(VehiclePropertyType::FLOAT);
83 val->value.floatValues[0] = value;
84 return val;
85 }
86
obtainString(const char * cstr)87 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainString(const char* cstr) {
88 auto val = obtain(VehiclePropertyType::STRING);
89 val->value.stringValue = cstr;
90 return val;
91 }
92
obtainComplex()93 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainComplex() {
94 return obtain(VehiclePropertyType::MIXED);
95 }
96
obtainRecyclable(VehiclePropertyType type,size_t vectorSize)97 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainRecyclable(
98 VehiclePropertyType type, size_t vectorSize) {
99 std::scoped_lock<std::mutex> lock(mLock);
100 assert(vectorSize > 0);
101
102 // VehiclePropertyType is not overlapping with vectorSize.
103 int32_t key = static_cast<int32_t>(type) | static_cast<int32_t>(vectorSize);
104 auto it = mValueTypePools.find(key);
105
106 if (it == mValueTypePools.end()) {
107 auto newPool(std::make_unique<InternalPool>(type, vectorSize, mMaxPoolObjectsSize,
108 getVehiclePropValueSize));
109 it = mValueTypePools.emplace(key, std::move(newPool)).first;
110 }
111 return it->second->obtain();
112 }
113
obtainBoolean(bool value)114 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainBoolean(bool value) {
115 return obtainInt32(value);
116 }
117
obtainDisposable(VehiclePropertyType valueType,size_t vectorSize) const118 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainDisposable(
119 VehiclePropertyType valueType, size_t vectorSize) const {
120 return RecyclableType{createVehiclePropValueVec(valueType, vectorSize).release(),
121 mDisposableDeleter};
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(RawPropValues * v)141 bool VehiclePropValuePool::InternalPool::check(RawPropValues* 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->byteValues, VehiclePropertyType::BYTES == mPropType) &&
150 v->stringValue.size() == 0;
151 }
152
createObject()153 VehiclePropValue* VehiclePropValuePool::InternalPool::createObject() {
154 return createVehiclePropValueVec(mPropType, mVectorSize).release();
155 }
156
157 } // namespace vehicle
158 } // namespace automotive
159 } // namespace hardware
160 } // namespace android
161