1 /*
2  * Copyright (C) 2015 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 #ifndef ANDROID_VEHICLE_NETWORK_DATA_TYPES_H
18 #define ANDROID_VEHICLE_NETWORK_DATA_TYPES_H
19 
20 #include <stdint.h>
21 #include <sys/types.h>
22 #include <assert.h>
23 
24 #include <memory>
25 
26 #include <binder/Parcel.h>
27 #include <hardware/vehicle.h>
28 
29 #include <utils/List.h>
30 #include <utils/RefBase.h>
31 #include <utils/Errors.h>
32 
33 /**
34  * Define this macro to make the process crash when memory alloc fails.
35  * Enabling this can be useful to track memory leak. When this macro is not define,
36  * memory alloc failure will lead into returning from the current function
37  * with behavior like returning NO_MEMORY error.
38  */
39 #define ASSERT_ON_NO_MEMORY
40 #ifdef ASSERT_ON_NO_MEMORY
41 #define ASSERT_OR_HANDLE_NO_MEMORY(ptr, action) assert((ptr) != NULL)
42 #else
43 #define ASSERT_OR_HANDLE_NO_MEMORY(ptr, action) if ((ptr) == NULL) { action; }
44 #endif
45 
46 #define ASSERT_ALWAYS_ON_NO_MEMORY(ptr) assert((ptr) != NULL)
47 
48 namespace android {
49 
50 // ----------------------------------------------------------------------------
51 
52 /**
53  * Collection of help utilities for vehicle_prop_config_t
54  */
55 class VehiclePropertiesUtil {
56 public:
57     /**
58      * Helper utility to delete vehicle_prop_config_t manually. Client does not need to do this for
59      * VehiclePropertiesHolder. This is for the case where client creates vehicle_prop_config_t
60      * directly.
61      */
deleteMembers(vehicle_prop_config_t * config)62     static void deleteMembers(vehicle_prop_config_t* config) {
63         if (config->config_string.data != NULL && config->config_string.len > 0){
64             delete[] config->config_string.data;
65         }
66         switch (config->prop) {
67             case VEHICLE_VALUE_TYPE_ZONED_INT32:
68             case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2:
69             case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3:
70             case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4: {
71                 delete[] config->int32_max_values;
72                 delete[] config->int32_min_values;
73             } break;
74             case VEHICLE_VALUE_TYPE_ZONED_FLOAT:
75             case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2:
76             case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3:
77             case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4: {
78                 delete[] config->float_max_values;
79                 delete[] config->float_min_values;
80             } break;
81         }
82     };
83 
isTheSame(const vehicle_prop_config_t & l,const vehicle_prop_config_t & r)84     static bool isTheSame(const vehicle_prop_config_t& l, const vehicle_prop_config_t& r) {
85         if (l.prop != r.prop) {
86             return false;
87         }
88         if (l.access != r.access) {
89             return false;
90         }
91         if (l.change_mode != r.change_mode) {
92             return false;
93         }
94         if (l.value_type != r.value_type) {
95             return false;
96         }
97         if (l.permission_model != r.permission_model) {
98             return false;
99         }
100         if (l.config_flags != r.config_flags) {
101             return false;
102         }
103         //TODO config_string
104         if (l.float_min_value != r.float_min_value) {
105             return false;
106         }
107         if (l.float_max_value != r.float_max_value) {
108             return false;
109         }
110         if (l.min_sample_rate != r.min_sample_rate) {
111             return false;
112         }
113         if (l.max_sample_rate != r.max_sample_rate) {
114             return false;
115         }
116         return true;
117     }
118 };
119 // ----------------------------------------------------------------------------
120 
121 /**
122  * Ref counted container for array of vehicle_prop_config_t.
123  */
124 class VehiclePropertiesHolder : public virtual RefBase {
125 public:
126 
127     VehiclePropertiesHolder(bool deleteConfigsInDestructor = true)
mDeleteConfigsInDestructor(deleteConfigsInDestructor)128         : mDeleteConfigsInDestructor(deleteConfigsInDestructor) {
129     };
130 
~VehiclePropertiesHolder()131     virtual ~VehiclePropertiesHolder() {
132         if (!mDeleteConfigsInDestructor) {
133             return; // should not delete members
134         }
135         for (auto& e : mList) {
136             vehicle_prop_config_t* eDelete = const_cast<vehicle_prop_config_t*>(e);
137             VehiclePropertiesUtil::deleteMembers(eDelete);
138             delete eDelete;
139         }
140         mList.clear();
141     };
142 
getList()143     List<vehicle_prop_config_t const *>& getList() {
144         return mList;
145     };
146 
147 private:
148     List<vehicle_prop_config_t const *> mList;
149     bool mDeleteConfigsInDestructor;
150 };
151 
152 // ----------------------------------------------------------------------------
153 
154 /**
155  * Collection of help utilities for vehicle_prop_value_t
156  */
157 class VehiclePropValueUtil {
158 public:
159     /**
160      * This one only deletes pointer member, so that vehicle_prop_value_t can be stack variable.
161      */
deleteMembers(vehicle_prop_value_t * v)162     static void deleteMembers(vehicle_prop_value_t* v) {
163         if (v == NULL) {
164             return;
165         }
166         switch (v->value_type) {
167             case VEHICLE_VALUE_TYPE_BYTES:
168             case VEHICLE_VALUE_TYPE_STRING: {
169                 delete[] v->value.str_value.data;
170                 v->value.str_value.data = NULL;
171             } break;
172         }
173     };
174 
175     static status_t copyVehicleProp(vehicle_prop_value_t* dest, const vehicle_prop_value_t& src,
176             bool deleteOldData = false) {
177         switch (src.value_type) {
178         case VEHICLE_VALUE_TYPE_BYTES:
179         case VEHICLE_VALUE_TYPE_STRING: {
180             if (deleteOldData && dest->value.str_value.data != NULL &&
181                     dest->value.str_value.len > 0) {
182                 delete[] dest->value.str_value.data;
183             }
184             memcpy(dest, &src, sizeof(vehicle_prop_value_t));
185             if (dest->value.str_value.len > 0) {
186                 dest->value.str_value.data = new uint8_t[dest->value.str_value.len];
187                 ASSERT_OR_HANDLE_NO_MEMORY(dest->value.str_value.data, return NO_MEMORY);
188                 memcpy(dest->value.str_value.data, src.value.str_value.data,
189                         dest->value.str_value.len);
190             } else {
191                 dest->value.str_value.data = NULL;
192             }
193         } break;
194         default: {
195             memcpy(dest, &src, sizeof(vehicle_prop_value_t));
196         } break;
197         }
198         return NO_ERROR;
199     }
200 
201     /**
202      * Create a deep copy of vehicle_prop_value_t.
203      */
allocVehicleProp(const vehicle_prop_value_t & v)204     static vehicle_prop_value_t* allocVehicleProp(const vehicle_prop_value_t& v) {
205         std::unique_ptr<vehicle_prop_value_t> copy(new vehicle_prop_value_t());
206         ASSERT_OR_HANDLE_NO_MEMORY(copy.get(), return NO_MEMORY);
207         status_t r = copyVehicleProp(copy.get(), v);
208         if (r != NO_ERROR) {
209             return NULL;
210         }
211         return copy.release();
212     };
213 };
214 
215 // ----------------------------------------------------------------------------
216 
217 /**
218  * This is utility class to have local vehicle_prop_value_t to hold data temporarily,
219  * and to release all data without memory leak.
220  * Usage is:
221  *     ScopedVehiclePropValue value;
222  *     // use value.value
223  *     Then things allocated to value.value will be all cleaned up properly.
224  */
225 class ScopedVehiclePropValue {
226 public:
227     vehicle_prop_value_t value;
228 
ScopedVehiclePropValue()229     ScopedVehiclePropValue() {
230         memset(&value, 0, sizeof(value));
231     };
232 
~ScopedVehiclePropValue()233     ~ScopedVehiclePropValue() {
234         VehiclePropValueUtil::deleteMembers(&value);
235     };
236 };
237 
238 // ----------------------------------------------------------------------------
239 /**
240  * Reference counted container of List holding vehicle_prop_value_t*.
241  */
242 class VehiclePropValueListHolder : public virtual RefBase {
243 public:
244     VehiclePropValueListHolder(List<vehicle_prop_value_t* > * list, bool deleteInDestructor = true)
mList(list)245       : mList(list),
246         mDeleteInDestructor(deleteInDestructor) {};
247 
getList()248     List<vehicle_prop_value_t*>& getList() {
249         return *mList;
250     };
251 
~VehiclePropValueListHolder()252     virtual ~VehiclePropValueListHolder() {
253         if (mDeleteInDestructor && mList != NULL) {
254             for (auto pv : *mList) {
255                 VehiclePropValueUtil::deleteMembers(pv);
256                 delete pv;
257             }
258             delete mList;
259         }
260     };
261 
262 private:
263     List<vehicle_prop_value_t*>* mList;
264     bool mDeleteInDestructor;
265 };
266 
267 // ----------------------------------------------------------------------------
268 class VehicleHalError {
269 public:
270     int32_t errorCode;
271     int32_t property;
272     int32_t operation;
VehicleHalError(int32_t aErrorCode,int32_t aProperty,int32_t aOperation)273     VehicleHalError(int32_t aErrorCode, int32_t aProperty, int32_t aOperation) :
274         errorCode(aErrorCode),
275         property(aProperty),
276         operation(aOperation) {};
277 };
278 }; //namespace android
279 
280 #endif /* ANDROID_VEHICLE_NETWORK_DATA_TYPES_H*/
281