Add complex data type to Vehicle HAL

Bug: b/33751068

Test: unit test provided, properties with complex data types
      should be covered with VTS

Change-Id: I12cfdbe1572018b941d3154b6d3bfdeb251ec55b
diff --git a/vehicle/2.0/default/tests/VehicleHalManager_test.cpp b/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
index 964c7c8..dffcfbb 100644
--- a/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
+++ b/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
@@ -67,6 +67,14 @@
                     pValue = getValuePool()->obtainFloat(42.42);
                 }
                 break;
+            case VehicleProperty::VEHICLE_MAPS_DATA_SERVICE:
+                pValue = getValuePool()->obtainComplex();
+                pValue->value.int32Values = hidl_vec<int32_t> { 10, 20 };
+                pValue->value.int64Values = hidl_vec<int64_t> { 30, 40 };
+                pValue->value.floatValues = hidl_vec<float_t> { 1.1, 2.2 };
+                pValue->value.bytes = hidl_vec<uint8_t> { 1, 2, 3 };
+                pValue->value.stringValue = kCarMake;
+                break;
             default:
                 auto key = makeKey(property, areaId);
                 if (mValues.count(key) == 0) {
@@ -308,6 +316,32 @@
     ASSERT_EQ(StatusCode::OK, res);
 }
 
+TEST_F(VehicleHalManagerTest, get_Complex) {
+    invokeGet(VehicleProperty::VEHICLE_MAPS_DATA_SERVICE, 0);
+
+    ASSERT_EQ(StatusCode::OK, actualStatusCode);
+    ASSERT_EQ(VehicleProperty::VEHICLE_MAPS_DATA_SERVICE, actualValue.prop);
+
+    ASSERT_EQ(3, actualValue.value.bytes.size());
+    ASSERT_EQ(1, actualValue.value.bytes[0]);
+    ASSERT_EQ(2, actualValue.value.bytes[1]);
+    ASSERT_EQ(3, actualValue.value.bytes[2]);
+
+    ASSERT_EQ(2, actualValue.value.int32Values.size());
+    ASSERT_EQ(10, actualValue.value.int32Values[0]);
+    ASSERT_EQ(20, actualValue.value.int32Values[1]);
+
+    ASSERT_EQ(2, actualValue.value.floatValues.size());
+    ASSERT_FLOAT_EQ(1.1, actualValue.value.floatValues[0]);
+    ASSERT_FLOAT_EQ(2.2, actualValue.value.floatValues[1]);
+
+    ASSERT_EQ(2, actualValue.value.int64Values.size());
+    ASSERT_FLOAT_EQ(30, actualValue.value.int64Values[0]);
+    ASSERT_FLOAT_EQ(40, actualValue.value.int64Values[1]);
+
+    ASSERT_STREQ(kCarMake, actualValue.value.stringValue.c_str());
+}
+
 TEST_F(VehicleHalManagerTest, get_StaticString) {
     invokeGet(VehicleProperty::INFO_MAKE, 0);
 
diff --git a/vehicle/2.0/default/tests/VehicleHalTestUtils.h b/vehicle/2.0/default/tests/VehicleHalTestUtils.h
index 77541fc..e1e355e 100644
--- a/vehicle/2.0/default/tests/VehicleHalTestUtils.h
+++ b/vehicle/2.0/default/tests/VehicleHalTestUtils.h
@@ -103,6 +103,13 @@
         .access = VehiclePropertyAccess::READ_WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
 
+    },
+
+    // Complex data type.
+    {
+        .prop = VehicleProperty::VEHICLE_MAPS_DATA_SERVICE,
+        .access = VehiclePropertyAccess::READ_WRITE,
+        .changeMode = VehiclePropertyChangeMode::ON_CHANGE
     }
 };
 
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.cpp b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.cpp
index 70b93e7..463b333 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.cpp
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.cpp
@@ -80,6 +80,10 @@
     return val;
 }
 
+VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainComplex() {
+    return obtain(VehiclePropertyType::COMPLEX);
+}
+
 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainRecylable(
         VehiclePropertyType type, size_t vecSize) {
     // VehiclePropertyType is not overlapping with vectorSize.
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h
index 1ca9211..d9231c3 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h
@@ -184,13 +184,15 @@
     RecyclableType obtainInt64(int64_t value);
     RecyclableType obtainFloat(float value);
     RecyclableType obtainString(const char* cstr);
+    RecyclableType obtainComplex();
 
     VehiclePropValuePool(VehiclePropValuePool& ) = delete;
     VehiclePropValuePool& operator=(VehiclePropValuePool&) = delete;
 private:
     bool isDisposable(VehiclePropertyType type, size_t vecSize) const {
         return vecSize > mMaxRecyclableVectorSize ||
-               VehiclePropertyType::STRING == type;
+               VehiclePropertyType::STRING == type ||
+               VehiclePropertyType::COMPLEX == type;
     }
 
     RecyclableType obtainDisposable(VehiclePropertyType valueType,
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.cpp b/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.cpp
index c461833..ab1d908 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.cpp
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.cpp
@@ -47,6 +47,7 @@
             val->value.bytes.resize(vecSize);
             break;
         case VehiclePropertyType::STRING:
+        case VehiclePropertyType::COMPLEX:
             break; // Valid, but nothing to do.
         default:
             ALOGE("createVehiclePropValue: unknown type: %d", type);