summaryrefslogtreecommitdiffstats
path: root/vehicle
diff options
context:
space:
mode:
authorPavel Maltsev <pavelm@google.com>2016-10-27 15:43:06 -0700
committerPavel Maltsev <pavelm@google.com>2016-11-02 14:31:34 -0700
commitdb179c5ec470269e1c88d8da5fafdff40a539bc6 (patch)
tree8c97ad60053f10f5fb978b10d989b2d3d1f06943 /vehicle
parent4ae948a52ba96cd10995c292a84392a46f436ae2 (diff)
downloadplatform_hardware_interfaces-db179c5ec470269e1c88d8da5fafdff40a539bc6.tar.gz
platform_hardware_interfaces-db179c5ec470269e1c88d8da5fafdff40a539bc6.tar.bz2
platform_hardware_interfaces-db179c5ec470269e1c88d8da5fafdff40a539bc6.zip
Vehicle HAL reference impl Part II
Implemented: - IVehicle::get <-- changed signature - IVehicle::set - status_t replaced with StatusCode - changed error handling to handle errors on SET Test: unit tests provided Bug: b/31971746 Change-Id: I9ea3feab7539adf588f1278fb905c0a458fa1627
Diffstat (limited to 'vehicle')
-rw-r--r--vehicle/2.0/IVehicle.hal13
-rw-r--r--vehicle/2.0/IVehicleCallback.hal17
-rw-r--r--vehicle/2.0/default/Android.mk1
-rw-r--r--vehicle/2.0/default/VehicleHal.h28
-rw-r--r--vehicle/2.0/default/impl/DefaultConfig.h4
-rw-r--r--vehicle/2.0/default/impl/DefaultVehicleHal.cpp42
-rw-r--r--vehicle/2.0/default/impl/DefaultVehicleHal.h19
-rw-r--r--vehicle/2.0/default/tests/SubscriptionManager_test.cpp22
-rw-r--r--vehicle/2.0/default/tests/VehicleHalManager_test.cpp288
-rw-r--r--vehicle/2.0/default/tests/VehicleHalTestUtils.h68
-rw-r--r--vehicle/2.0/default/vehicle_hal_manager/ConcurrentQueue.h7
-rw-r--r--vehicle/2.0/default/vehicle_hal_manager/VehicleCallback.cpp53
-rw-r--r--vehicle/2.0/default/vehicle_hal_manager/VehicleCallback.h56
-rw-r--r--vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.cpp173
-rw-r--r--vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.h33
-rw-r--r--vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h8
-rw-r--r--vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.h2
-rw-r--r--vehicle/2.0/types.hal107
18 files changed, 613 insertions, 328 deletions
diff --git a/vehicle/2.0/IVehicle.hal b/vehicle/2.0/IVehicle.hal
index 4c02447bf6..5b0df67170 100644
--- a/vehicle/2.0/IVehicle.hal
+++ b/vehicle/2.0/IVehicle.hal
@@ -27,9 +27,13 @@ interface IVehicle {
/*
* Returns a list of property configurations for given properties.
+ *
+ * If requested VehicleProperty wasn't found it must return
+ * StatusCode::INVALID_ARG, otherwise a list of vehicle property
+ * configurations with StatusCode::OK
*/
getPropConfigs(vec<VehicleProperty> props)
- generates (vec<VehiclePropConfig> propConfigs);
+ generates (StatusCode status, vec<VehiclePropConfig> propConfigs);
/**
* Get a vehicle property value.
@@ -39,11 +43,14 @@ interface IVehicle {
* For VehiclePropertyChangeMode::ON_CHANGE properties, it must return the
* latest available value.
*
+ * Some properties like AUDIO_VOLUME requires to pass additional data in
+ * GET request in VehiclePropValue object.
+ *
* If there is no data available yet, which can happen during initial stage,
* this call must return immediately with an error code of
* StatusCode::TRY_AGAIN.
*/
- get(VehicleProperty propId, int32_t areaId)
+ get(VehiclePropValue requestedPropValue)
generates (StatusCode status, VehiclePropValue propValue);
/**
@@ -75,7 +82,7 @@ interface IVehicle {
* Unsubscribes from property events.
*
* If this client wasn't subscribed to the given property, this method
- * must return StatusCode::INVALID_ARGUMENT.
+ * must return StatusCode::INVALID_ARG.
*/
unsubscribe(IVehicleCallback callback, VehicleProperty propId)
generates (StatusCode status);
diff --git a/vehicle/2.0/IVehicleCallback.hal b/vehicle/2.0/IVehicleCallback.hal
index 5c1042b26c..504f782017 100644
--- a/vehicle/2.0/IVehicleCallback.hal
+++ b/vehicle/2.0/IVehicleCallback.hal
@@ -43,14 +43,17 @@ interface IVehicleCallback {
oneway onPropertySet(VehiclePropValue propValue);
/*
- * Called by HAL server when error condition has occurred.
+ * Set property value is usually asynchronous operation. Thus even if
+ * client received StatusCode::OK from the IVehicle::set(...) this
+ * doesn't guarantee that the value was successfully propagated to the
+ * vehicle network. If such rare event occurs this method must be called.
*
* @param errorCode - any value from StatusCode enum.
- * @parm property - a property where error has happened. If this is
- * a generic error, this value should be VehicleProperty::INVALID.
- * @param operation Represent the operation where the error has happened.
+ * @param property - a property where error has happened.
+ * @param areaId - bitmask that specifies in which areas the problem has
+ * occurred, must be 0 for global properties
*/
- oneway onError(StatusCode errorCode,
- VehicleProperty propId,
- VehiclePropertyOperation operation);
+ oneway onPropertySetError(StatusCode errorCode,
+ VehicleProperty propId,
+ int32_t areaId);
};
diff --git a/vehicle/2.0/default/Android.mk b/vehicle/2.0/default/Android.mk
index e14cb19114..90353ee091 100644
--- a/vehicle/2.0/default/Android.mk
+++ b/vehicle/2.0/default/Android.mk
@@ -24,7 +24,6 @@ LOCAL_MODULE := $(module_prefix)-manager-lib
LOCAL_SRC_FILES := \
vehicle_hal_manager/SubscriptionManager.cpp \
vehicle_hal_manager/VehicleHalManager.cpp \
- vehicle_hal_manager/VehicleCallback.cpp \
LOCAL_SHARED_LIBRARIES := \
liblog \
diff --git a/vehicle/2.0/default/VehicleHal.h b/vehicle/2.0/default/VehicleHal.h
index 89d8ef8816..2807f28750 100644
--- a/vehicle/2.0/default/VehicleHal.h
+++ b/vehicle/2.0/default/VehicleHal.h
@@ -36,18 +36,15 @@ public:
using HalEventFunction = std::function<void(VehiclePropValuePtr)>;
using HalErrorFunction = std::function<void(
- VehicleProperty property,
- status_t errorCode,
- VehiclePropertyOperation operation)>;
+ StatusCode errorCode, VehicleProperty property, int32_t areaId)>;
virtual ~VehicleHal() {}
virtual std::vector<VehiclePropConfig> listProperties() = 0;
- virtual VehiclePropValuePtr get(VehicleProperty property,
- int32_t areaId,
- status_t* outStatus) = 0;
+ virtual VehiclePropValuePtr get(const VehiclePropValue& requestedPropValue,
+ StatusCode* outStatus) = 0;
- virtual status_t set(const VehiclePropValue& propValue) = 0;
+ virtual StatusCode set(const VehiclePropValue& propValue) = 0;
/**
* Subscribe to HAL property events. This method might be called multiple
@@ -60,7 +57,7 @@ public:
* rate, e.g. for properties with
* VehiclePropertyChangeMode::CONTINUOUS
*/
- virtual status_t subscribe(VehicleProperty property,
+ virtual StatusCode subscribe(VehicleProperty property,
int32_t areas,
float sampleRate) = 0;
@@ -69,7 +66,7 @@ public:
*
* @param property vehicle property to unsubscribe
*/
- virtual status_t unsubscribe(VehicleProperty property) = 0;
+ virtual StatusCode unsubscribe(VehicleProperty property) = 0;
/**
* Override this method if you need to do one-time initialization.
@@ -82,7 +79,7 @@ public:
const HalErrorFunction& onHalError) {
mValuePool = valueObjectPool;
mOnHalEvent = onHalEvent;
- mOnHalError = onHalError;
+ mOnHalPropertySetError = onHalError;
onCreate();
}
@@ -91,19 +88,20 @@ public:
return mValuePool;
}
protected:
+ /* Propagates property change events to vehicle HAL clients. */
void doHalEvent(VehiclePropValuePtr v) {
mOnHalEvent(std::move(v));
}
- void doHalError(VehicleProperty property,
- status_t errorCode,
- VehiclePropertyOperation operation) {
- mOnHalError(property, errorCode, operation);
+ /* Propagates error during set operation to the vehicle HAL clients. */
+ void doHalPropertySetError(StatusCode errorCode,
+ VehicleProperty propId, int32_t areaId) {
+ mOnHalPropertySetError(errorCode, propId, areaId);
}
private:
HalEventFunction mOnHalEvent;
- HalErrorFunction mOnHalError;
+ HalErrorFunction mOnHalPropertySetError;
VehiclePropValuePool* mValuePool;
};
diff --git a/vehicle/2.0/default/impl/DefaultConfig.h b/vehicle/2.0/default/impl/DefaultConfig.h
index 6f04626ba8..e620c28634 100644
--- a/vehicle/2.0/default/impl/DefaultConfig.h
+++ b/vehicle/2.0/default/impl/DefaultConfig.h
@@ -43,11 +43,11 @@ const VehiclePropConfig kVehicleProperties[] = {
VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT),
.areaConfigs = init_hidl_vec({
VehicleAreaConfig {
- .areaId = val(VehicleAreaZone::ROW_2_LEFT),
+ .areaId = toInt(VehicleAreaZone::ROW_2_LEFT),
.minInt32Value = 1,
.maxInt32Value = 7},
VehicleAreaConfig {
- .areaId = val(VehicleAreaZone::ROW_1_RIGHT),
+ .areaId = toInt(VehicleAreaZone::ROW_1_RIGHT),
.minInt32Value = 1,
.maxInt32Value = 5,
}
diff --git a/vehicle/2.0/default/impl/DefaultVehicleHal.cpp b/vehicle/2.0/default/impl/DefaultVehicleHal.cpp
index 6ca0f9fd6e..24d438dc52 100644
--- a/vehicle/2.0/default/impl/DefaultVehicleHal.cpp
+++ b/vehicle/2.0/default/impl/DefaultVehicleHal.cpp
@@ -23,12 +23,13 @@ namespace V2_0 {
namespace impl {
-VehicleHal::VehiclePropValuePtr DefaultVehicleHal::get(VehicleProperty property,
- int32_t areaId,
- status_t* outStatus) {
- *outStatus = OK;
+VehicleHal::VehiclePropValuePtr DefaultVehicleHal::get(
+ const VehiclePropValue& requestedPropValue, StatusCode* outStatus) {
+ *outStatus = StatusCode::OK;
VehiclePropValuePtr v;
+ VehicleProperty property = requestedPropValue.prop;
+ int32_t areaId = requestedPropValue.areaId;
switch (property) {
case VehicleProperty::INFO_MAKE:
@@ -36,7 +37,8 @@ VehicleHal::VehiclePropValuePtr DefaultVehicleHal::get(VehicleProperty property,
break;
case VehicleProperty::HVAC_FAN_SPEED:
int32_t value;
- if ((*outStatus = getHvacFanSpeed(areaId, &value)) == OK) {
+ *outStatus = getHvacFanSpeed(areaId, &value);
+ if (StatusCode::OK == *outStatus) {
v = getValuePool()->obtainInt32(value);
}
break;
@@ -47,10 +49,10 @@ VehicleHal::VehiclePropValuePtr DefaultVehicleHal::get(VehicleProperty property,
v = getValuePool()->obtainInt32(brightness);
break;
default:
- *outStatus = BAD_VALUE;
+ *outStatus = StatusCode::INVALID_ARG;
}
- if (*outStatus == OK && v.get() != nullptr) {
+ if (StatusCode::OK == *outStatus && v.get() != nullptr) {
v->prop = property;
v->areaId = areaId;
v->timestamp = elapsedRealtimeNano();
@@ -59,10 +61,10 @@ VehicleHal::VehiclePropValuePtr DefaultVehicleHal::get(VehicleProperty property,
return v;
}
-status_t DefaultVehicleHal::set(const VehiclePropValue& propValue) {
+StatusCode DefaultVehicleHal::set(const VehiclePropValue& propValue) {
auto property = propValue.prop;
- status_t status = OK;
+ StatusCode status = StatusCode::OK;
switch (property) {
case VehicleProperty::HVAC_FAN_SPEED:
@@ -73,33 +75,33 @@ status_t DefaultVehicleHal::set(const VehiclePropValue& propValue) {
brightness = propValue.value.int32Values[0];
break;
default:
- status = BAD_VALUE;
+ status = StatusCode::INVALID_ARG;
}
return status;
}
-status_t DefaultVehicleHal::getHvacFanSpeed(int32_t areaId,
+StatusCode DefaultVehicleHal::getHvacFanSpeed(int32_t areaId,
int32_t* outValue) {
- if (areaId == val(VehicleAreaZone::ROW_1_LEFT)) {
+ if (areaId == toInt(VehicleAreaZone::ROW_1_LEFT)) {
*outValue = fanSpeedRow1Left;
- } else if (areaId == val(VehicleAreaZone::ROW_2_RIGHT)) {
+ } else if (areaId == toInt(VehicleAreaZone::ROW_2_RIGHT)) {
*outValue = fanSpeedRow1Right;
} else {
- return BAD_VALUE;
+ return StatusCode::INVALID_ARG;
}
- return OK;
+ return StatusCode::OK;
}
-status_t DefaultVehicleHal::setHvacFanSpeed(int32_t areaId, int32_t value) {
- if (areaId == val(VehicleAreaZone::ROW_1_LEFT)) {
+StatusCode DefaultVehicleHal::setHvacFanSpeed(int32_t areaId, int32_t value) {
+ if (areaId == toInt(VehicleAreaZone::ROW_1_LEFT)) {
fanSpeedRow1Left = value;
- } else if (areaId == val(VehicleAreaZone::ROW_2_RIGHT)) {
+ } else if (areaId == toInt(VehicleAreaZone::ROW_2_RIGHT)) {
fanSpeedRow1Right = value;
} else {
- return BAD_VALUE;
+ return StatusCode::INVALID_ARG;
}
- return OK;
+ return StatusCode::OK;
}
} // impl
diff --git a/vehicle/2.0/default/impl/DefaultVehicleHal.h b/vehicle/2.0/default/impl/DefaultVehicleHal.h
index 7d0b7cbf84..4a81da35ca 100644
--- a/vehicle/2.0/default/impl/DefaultVehicleHal.h
+++ b/vehicle/2.0/default/impl/DefaultVehicleHal.h
@@ -35,27 +35,26 @@ public:
std::end(kVehicleProperties));
}
- VehiclePropValuePtr get(VehicleProperty property,
- int32_t areaId,
- status_t* outStatus) override;
+ VehiclePropValuePtr get(const VehiclePropValue& requestedPropValue,
+ StatusCode* outStatus) override;
- status_t set(const VehiclePropValue& propValue) override;
+ StatusCode set(const VehiclePropValue& propValue) override;
- status_t subscribe(VehicleProperty property,
+ StatusCode subscribe(VehicleProperty property,
int32_t areas,
float sampleRate) {
// TODO(pavelm): implement
- return OK;
+ return StatusCode::OK;
}
- status_t unsubscribe(VehicleProperty property) {
+ StatusCode unsubscribe(VehicleProperty property) {
// TODO(pavelm): implement
- return OK;
+ return StatusCode::OK;
}
private:
- status_t getHvacFanSpeed(int32_t areaId, int32_t* outValue);
- status_t setHvacFanSpeed(int32_t areaId, int32_t value);
+ StatusCode getHvacFanSpeed(int32_t areaId, int32_t* outValue);
+ StatusCode setHvacFanSpeed(int32_t areaId, int32_t value);
private:
int32_t fanSpeedRow1Left = 3;
int32_t fanSpeedRow1Right = 5;
diff --git a/vehicle/2.0/default/tests/SubscriptionManager_test.cpp b/vehicle/2.0/default/tests/SubscriptionManager_test.cpp
index c3db993dd8..19b11e6b72 100644
--- a/vehicle/2.0/default/tests/SubscriptionManager_test.cpp
+++ b/vehicle/2.0/default/tests/SubscriptionManager_test.cpp
@@ -50,7 +50,7 @@ public:
{
SubscribeOptions {
.propId = PROP1,
- .vehicleAreas = val(VehicleAreaZone::ROW_1_LEFT),
+ .vehicleAreas = toInt(VehicleAreaZone::ROW_1_LEFT),
.flags = SubscribeFlags::HAL_EVENT
},
});
@@ -67,7 +67,7 @@ public:
{
SubscribeOptions {
.propId = PROP1,
- .vehicleAreas = val(VehicleAreaZone::ROW_1_LEFT),
+ .vehicleAreas = toInt(VehicleAreaZone::ROW_1_LEFT),
.flags = SubscribeFlags::HAL_EVENT
},
SubscribeOptions {
@@ -87,7 +87,7 @@ public:
std::list<sp<HalClient>> clientsToProp1() {
return manager.getSubscribedClients(PROP1,
- val(VehicleAreaZone::ROW_1_LEFT),
+ toInt(VehicleAreaZone::ROW_1_LEFT),
SubscribeFlags::DEFAULT);
}
@@ -104,7 +104,7 @@ TEST_F(SubscriptionManagerTest, multipleClients) {
auto clients = manager.getSubscribedClients(
PROP1,
- val(VehicleAreaZone::ROW_1_LEFT),
+ toInt(VehicleAreaZone::ROW_1_LEFT),
SubscribeFlags::HAL_EVENT);
ASSERT_ALL_EXISTS({cb1, cb2}, extractCallbacks(clients));
@@ -116,21 +116,21 @@ TEST_F(SubscriptionManagerTest, negativeCases) {
// Wrong zone
auto clients = manager.getSubscribedClients(
PROP1,
- val(VehicleAreaZone::ROW_2_LEFT),
+ toInt(VehicleAreaZone::ROW_2_LEFT),
SubscribeFlags::HAL_EVENT);
ASSERT_TRUE(clients.empty());
// Wrong prop
clients = manager.getSubscribedClients(
VehicleProperty::AP_POWER_BOOTUP_REASON,
- val(VehicleAreaZone::ROW_1_LEFT),
+ toInt(VehicleAreaZone::ROW_1_LEFT),
SubscribeFlags::HAL_EVENT);
ASSERT_TRUE(clients.empty());
// Wrong flag
clients = manager.getSubscribedClients(
PROP1,
- val(VehicleAreaZone::ROW_1_LEFT),
+ toInt(VehicleAreaZone::ROW_1_LEFT),
SubscribeFlags::SET_CALL);
ASSERT_TRUE(clients.empty());
}
@@ -140,7 +140,7 @@ TEST_F(SubscriptionManagerTest, mulipleSubscriptions) {
auto clients = manager.getSubscribedClients(
PROP1,
- val(VehicleAreaZone::ROW_1_LEFT),
+ toInt(VehicleAreaZone::ROW_1_LEFT),
SubscribeFlags::DEFAULT);
ASSERT_EQ((size_t) 1, clients.size());
ASSERT_EQ(cb1, clients.front()->getCallback());
@@ -151,18 +151,18 @@ TEST_F(SubscriptionManagerTest, mulipleSubscriptions) {
{
SubscribeOptions {
.propId = PROP1,
- .vehicleAreas = val(VehicleAreaZone::ROW_2),
+ .vehicleAreas = toInt(VehicleAreaZone::ROW_2),
.flags = SubscribeFlags::DEFAULT
}
}));
clients = manager.getSubscribedClients(PROP1,
- val(VehicleAreaZone::ROW_1_LEFT),
+ toInt(VehicleAreaZone::ROW_1_LEFT),
SubscribeFlags::DEFAULT);
ASSERT_ALL_EXISTS({cb1}, extractCallbacks(clients));
clients = manager.getSubscribedClients(PROP1,
- val(VehicleAreaZone::ROW_2),
+ toInt(VehicleAreaZone::ROW_2),
SubscribeFlags::DEFAULT);
ASSERT_ALL_EXISTS({cb1}, extractCallbacks(clients));
}
diff --git a/vehicle/2.0/default/tests/VehicleHalManager_test.cpp b/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
index 1410ddf8c1..6ef12052d1 100644
--- a/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
+++ b/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
@@ -22,6 +22,7 @@
#include <vehicle_hal_manager/VehiclePropConfigIndex.h>
#include <VehicleHal.h>
#include <vehicle_hal_manager/VehicleHalManager.h>
+#include <utils/SystemClock.h>
#include "vehicle_hal_manager/SubscriptionManager.h"
#include "VehicleHalTestUtils.h"
@@ -35,6 +36,9 @@ namespace {
using namespace std::placeholders;
+constexpr char kCarMake[] = "Default Car";
+constexpr int kRetriablePropMockedAttempts = 3;
+
class MockedVehicleHal : public VehicleHal {
public:
MockedVehicleHal() {
@@ -46,35 +50,87 @@ public:
return mConfigs;
}
- VehiclePropValuePtr get(VehicleProperty property,
- int32_t areaId,
- status_t* outStatus) override {
- *outStatus = OK;
- return getValuePool()->obtain(mValues[property]);
+ VehiclePropValuePtr get(const VehiclePropValue& requestedPropValue,
+ StatusCode* outStatus) override {
+ *outStatus = StatusCode::OK;
+ VehiclePropValuePtr pValue;
+ VehicleProperty property = requestedPropValue.prop;
+ int32_t areaId = requestedPropValue.areaId;
+
+ switch (property) {
+ case VehicleProperty::INFO_MAKE:
+ pValue = getValuePool()->obtainString(kCarMake);
+ break;
+ case VehicleProperty::INFO_FUEL_CAPACITY:
+ if (fuelCapacityAttemptsLeft-- > 0) {
+ // Emulate property not ready yet.
+ *outStatus = StatusCode::TRY_AGAIN;
+ } else {
+ pValue = getValuePool()->obtainFloat(42.42);
+ }
+ break;
+ default:
+ auto key = makeKey(property, areaId);
+ if (mValues.count(key) == 0) {
+ ALOGW("");
+ }
+ pValue = getValuePool()->obtain(mValues[key]);
+ }
+
+ if (*outStatus == StatusCode::OK && pValue.get() != nullptr) {
+ pValue->prop = property;
+ pValue->areaId = areaId;
+ pValue->timestamp = elapsedRealtimeNano();
+ }
+
+ return pValue;
}
- status_t set(const VehiclePropValue& propValue) override {
- mValues[propValue.prop] = propValue;
- return OK;
+ StatusCode set(const VehiclePropValue& propValue) override {
+ if (VehicleProperty::MIRROR_FOLD == propValue.prop
+ && mirrorFoldAttemptsLeft-- > 0) {
+ return StatusCode::TRY_AGAIN;
+ }
+
+ mValues[makeKey(propValue)] = propValue;
+ return StatusCode::OK;
}
- status_t subscribe(VehicleProperty property,
+ StatusCode subscribe(VehicleProperty property,
int32_t areas,
float sampleRate) override {
- return OK;
+ return StatusCode::OK;
}
- status_t unsubscribe(VehicleProperty property) override {
- return OK;
+ StatusCode unsubscribe(VehicleProperty property) override {
+ return StatusCode::OK;
}
void sendPropEvent(recyclable_ptr<VehiclePropValue> value) {
doHalEvent(std::move(value));
}
+ void sendHalError(StatusCode error, VehicleProperty property,
+ int32_t areaId) {
+ doHalPropertySetError(error, property, areaId);
+ }
+
+public:
+ int fuelCapacityAttemptsLeft = kRetriablePropMockedAttempts;
+ int mirrorFoldAttemptsLeft = kRetriablePropMockedAttempts;
+
+private:
+ int64_t makeKey(const VehiclePropValue& v) const {
+ return makeKey(v.prop, v.areaId);
+ }
+
+ int64_t makeKey(VehicleProperty prop, int32_t area) const {
+ return (static_cast<int64_t>(prop) << 32) | area;
+ }
+
private:
std::vector<VehiclePropConfig> mConfigs;
- std::unordered_map<VehicleProperty, VehiclePropValue> mValues;
+ std::unordered_map<int64_t, VehiclePropValue> mValues;
};
class VehicleHalManagerTest : public ::testing::Test {
@@ -90,37 +146,70 @@ protected:
manager.reset(nullptr);
hal.reset(nullptr);
}
+public:
+ void invokeGet(VehicleProperty property, int32_t areaId) {
+ VehiclePropValue requestedValue {};
+ requestedValue.prop = property;
+ requestedValue.areaId = areaId;
+
+ invokeGet(requestedValue);
+ }
+
+ void invokeGet(const VehiclePropValue& requestedPropValue) {
+ actualValue = VehiclePropValue {}; // reset previous values
+
+ StatusCode refStatus;
+ VehiclePropValue refValue;
+ bool called = false;
+ manager->get(requestedPropValue, [&refStatus, &refValue, &called]
+ (StatusCode status, const VehiclePropValue& value) {
+ refStatus = status;
+ refValue = value;
+ called = true;
+ });
+ ASSERT_TRUE(called) << "callback wasn't called for prop: "
+ << enumToHexString(requestedPropValue.prop);
+
+ actualValue = refValue;
+ actualStatusCode = refStatus;
+ }
public:
+ VehiclePropValue actualValue;
+ StatusCode actualStatusCode;
+
VehiclePropValuePool* objectPool;
std::unique_ptr<MockedVehicleHal> hal;
std::unique_ptr<VehicleHalManager> manager;
};
-class HalClientVectorTest : public ::testing::Test {
-public:
- HalClientVector clients;
-};
-
TEST_F(VehicleHalManagerTest, getPropConfigs) {
hidl_vec<VehicleProperty> properties = init_hidl_vec(
{ VehicleProperty::HVAC_FAN_SPEED,VehicleProperty::INFO_MAKE} );
bool called = false;
+
manager->getPropConfigs(properties,
- [&called] (const hidl_vec<VehiclePropConfig>& c) {
+ [&called] (StatusCode status,
+ const hidl_vec<VehiclePropConfig>& c) {
+ ASSERT_EQ(StatusCode::OK, status);
ASSERT_EQ(2u, c.size());
called = true;
});
+
ASSERT_TRUE(called); // Verify callback received.
called = false;
manager->getPropConfigs(init_hidl_vec({VehicleProperty::HVAC_FAN_SPEED}),
- [&called] (const hidl_vec<VehiclePropConfig>& c) {
+ [&called] (StatusCode status,
+ const hidl_vec<VehiclePropConfig>& c) {
+ ASSERT_EQ(StatusCode::OK, status);
ASSERT_EQ(1u, c.size());
ASSERT_EQ(toString(kVehicleProperties[1]), toString(c[0]));
called = true;
});
ASSERT_TRUE(called); // Verify callback received.
+
+ // TODO(pavelm): add case case when property was not declared.
}
TEST_F(VehicleHalManagerTest, getAllPropConfigs) {
@@ -138,6 +227,25 @@ TEST_F(VehicleHalManagerTest, getAllPropConfigs) {
ASSERT_TRUE(called); // Verify callback received.
}
+TEST_F(VehicleHalManagerTest, halErrorEvent) {
+ const VehicleProperty PROP = VehicleProperty::DISPLAY_BRIGHTNESS;
+
+ sp<MockedVehicleCallback> cb = new MockedVehicleCallback();
+
+ hidl_vec<SubscribeOptions> options = init_hidl_vec(
+ {
+ SubscribeOptions {
+ .propId = PROP,
+ .flags = SubscribeFlags::DEFAULT
+ },
+ });
+
+ StatusCode res = manager->subscribe(cb, options);
+ ASSERT_EQ(StatusCode::OK, res);
+
+ hal->sendHalError(StatusCode::TRY_AGAIN, PROP, 0 /* area id*/);
+}
+
TEST_F(VehicleHalManagerTest, subscribe) {
const VehicleProperty PROP = VehicleProperty::DISPLAY_BRIGHTNESS;
@@ -161,9 +269,9 @@ TEST_F(VehicleHalManagerTest, subscribe) {
auto& receivedEnvents = cb->getReceivedEvents();
ASSERT_TRUE(cb->waitForExpectedEvents(0)) << " Unexpected events received: "
- << receivedEnvents.size()
- << (receivedEnvents.size() > 0
- ? toString(receivedEnvents.front()[0]) : "");
+ << receivedEnvents.size()
+ << (receivedEnvents.size() > 0
+ ? toString(receivedEnvents.front()[0]) : "");
auto subscribedValue = objectPool->obtain(VehiclePropertyType::INT32);
subscribedValue->prop = PROP;
@@ -174,13 +282,143 @@ TEST_F(VehicleHalManagerTest, subscribe) {
hal->sendPropEvent(std::move(subscribedValue));
ASSERT_TRUE(cb->waitForExpectedEvents(1)) << "Events received: "
- << receivedEnvents.size();
+ << receivedEnvents.size();
ASSERT_EQ(toString(actualValue),
toString(cb->getReceivedEvents().front()[0]));
}
-TEST_F(HalClientVectorTest, basic) {
+TEST_F(VehicleHalManagerTest, subscribe_WriteOnly) {
+ const VehicleProperty PROP = VehicleProperty::HVAC_SEAT_TEMPERATURE;
+
+ sp<MockedVehicleCallback> cb = new MockedVehicleCallback();
+
+ hidl_vec<SubscribeOptions> options = init_hidl_vec(
+ {
+ SubscribeOptions {
+ .propId = PROP,
+ .flags = SubscribeFlags::HAL_EVENT
+ },
+ });
+
+ StatusCode res = manager->subscribe(cb, options);
+ // Unable to subscribe on Hal Events for write-only properties.
+ ASSERT_EQ(StatusCode::INVALID_ARG, res);
+
+
+ options[0].flags = SubscribeFlags::SET_CALL;
+
+ res = manager->subscribe(cb, options);
+ // OK to subscribe on SET method call for write-only properties.
+ ASSERT_EQ(StatusCode::OK, res);
+}
+
+TEST_F(VehicleHalManagerTest, get_StaticString) {
+ invokeGet(VehicleProperty::INFO_MAKE, 0);
+
+ ASSERT_EQ(StatusCode::OK, actualStatusCode);
+ ASSERT_EQ(VehicleProperty::INFO_MAKE, actualValue.prop);
+ ASSERT_STREQ(kCarMake, actualValue.value.stringValue.c_str());
+}
+
+TEST_F(VehicleHalManagerTest, get_NegativeCases) {
+ // Write-only property must fail.
+ invokeGet(VehicleProperty::HVAC_SEAT_TEMPERATURE, 0);
+ ASSERT_EQ(StatusCode::INVALID_ARG, actualStatusCode);
+
+ // Unknown property must fail.
+ invokeGet(VehicleProperty::MIRROR_Z_MOVE, 0);
+ ASSERT_EQ(StatusCode::INVALID_ARG, actualStatusCode);
+}
+
+TEST_F(VehicleHalManagerTest, get_Retriable) {
+ actualStatusCode = StatusCode::TRY_AGAIN;
+ int attempts = 0;
+ while (StatusCode::TRY_AGAIN == actualStatusCode && ++attempts < 10) {
+ invokeGet(VehicleProperty::INFO_FUEL_CAPACITY, 0);
+
+ }
+ ASSERT_EQ(StatusCode::OK, actualStatusCode);
+ ASSERT_EQ(kRetriablePropMockedAttempts + 1, attempts);
+ ASSERT_FLOAT_EQ(42.42, actualValue.value.floatValues[0]);
+}
+
+TEST_F(VehicleHalManagerTest, set_Basic) {
+ const auto PROP = VehicleProperty::DISPLAY_BRIGHTNESS;
+ const auto VAL = 7;
+
+ auto expectedValue = hal->getValuePool()->obtainInt32(VAL);
+ expectedValue->prop = PROP;
+ expectedValue->areaId = 0;
+
+ actualStatusCode = manager->set(*expectedValue.get());
+ ASSERT_EQ(StatusCode::OK, actualStatusCode);
+
+ invokeGet(PROP, 0);
+ ASSERT_EQ(StatusCode::OK, actualStatusCode);
+ ASSERT_EQ(PROP, actualValue.prop);
+ ASSERT_EQ(VAL, actualValue.value.int32Values[0]);
+}
+
+TEST_F(VehicleHalManagerTest, set_DifferentAreas) {
+ const auto PROP = VehicleProperty::HVAC_FAN_SPEED;
+ const auto VAL1 = 1;
+ const auto VAL2 = 2;
+ const auto AREA1 = toInt(VehicleAreaZone::ROW_1_LEFT);
+ const auto AREA2 = toInt(VehicleAreaZone::ROW_1_RIGHT);
+
+ {
+ auto expectedValue1 = hal->getValuePool()->obtainInt32(VAL1);
+ expectedValue1->prop = PROP;
+ expectedValue1->areaId = AREA1;
+ actualStatusCode = manager->set(*expectedValue1.get());
+ ASSERT_EQ(StatusCode::OK, actualStatusCode);
+
+ auto expectedValue2 = hal->getValuePool()->obtainInt32(VAL2);
+ expectedValue2->prop = PROP;
+ expectedValue2->areaId = AREA2;
+ actualStatusCode = manager->set(*expectedValue2.get());
+ ASSERT_EQ(StatusCode::OK, actualStatusCode);
+ }
+
+ {
+ invokeGet(PROP, AREA1);
+ ASSERT_EQ(StatusCode::OK, actualStatusCode);
+ ASSERT_EQ(PROP, actualValue.prop);
+ ASSERT_EQ(AREA1, actualValue.areaId);
+ ASSERT_EQ(VAL1, actualValue.value.int32Values[0]);
+
+ invokeGet(PROP, AREA2);
+ ASSERT_EQ(StatusCode::OK, actualStatusCode);
+ ASSERT_EQ(PROP, actualValue.prop);
+ ASSERT_EQ(AREA2, actualValue.areaId);
+ ASSERT_EQ(VAL2, actualValue.value.int32Values[0]);
+ }
+}
+
+TEST_F(VehicleHalManagerTest, set_Retriable) {
+ const auto PROP = VehicleProperty::MIRROR_FOLD;
+
+ auto v = hal->getValuePool()->obtainBoolean(true);
+ v->prop = PROP;
+ v->areaId = 0;
+
+ actualStatusCode = StatusCode::TRY_AGAIN;
+ int attempts = 0;
+ while (StatusCode::TRY_AGAIN == actualStatusCode && ++attempts < 10) {
+ actualStatusCode = manager->set(*v.get());
+ }
+
+ ASSERT_EQ(StatusCode::OK, actualStatusCode);
+ ASSERT_EQ(kRetriablePropMockedAttempts + 1, attempts);
+
+ invokeGet(PROP, 0);
+ ASSERT_EQ(StatusCode::OK, actualStatusCode);
+ ASSERT_TRUE(actualValue.value.int32Values[0]);
+}
+
+TEST(HalClientVectorTest, basic) {
+ HalClientVector clients;
sp<IVehicleCallback> callback1 = new MockedVehicleCallback();
sp<HalClient> c1 = new HalClient(callback1, 10, 20);
diff --git a/vehicle/2.0/default/tests/VehicleHalTestUtils.h b/vehicle/2.0/default/tests/VehicleHalTestUtils.h
index b3b3ffa979..16d0be912f 100644
--- a/vehicle/2.0/default/tests/VehicleHalTestUtils.h
+++ b/vehicle/2.0/default/tests/VehicleHalTestUtils.h
@@ -44,18 +44,37 @@ const VehiclePropConfig kVehicleProperties[] = {
.supportedAreas = static_cast<int32_t>(
VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT),
.areaConfigs = init_hidl_vec({
- VehicleAreaConfig {
- .areaId = val(
- VehicleAreaZone::ROW_2_LEFT),
- .minInt32Value = 1,
- .maxInt32Value = 7},
- VehicleAreaConfig {
- .areaId = val(
- VehicleAreaZone::ROW_1_RIGHT),
- .minInt32Value = 1,
- .maxInt32Value = 5,
- }
- }),
+ VehicleAreaConfig {
+ .areaId = toInt(VehicleAreaZone::ROW_1_LEFT),
+ .minInt32Value = 1,
+ .maxInt32Value = 7},
+ VehicleAreaConfig {
+ .areaId = toInt(VehicleAreaZone::ROW_1_RIGHT),
+ .minInt32Value = 1,
+ .maxInt32Value = 5,
+ }
+ }),
+ },
+
+ // Write-only property
+ {
+ .prop = VehicleProperty::HVAC_SEAT_TEMPERATURE,
+ .access = VehiclePropertyAccess::WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_SET,
+ .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
+ .supportedAreas = static_cast<int32_t>(
+ VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT),
+ .areaConfigs = init_hidl_vec({
+ VehicleAreaConfig {
+ .areaId = toInt(VehicleAreaZone::ROW_1_LEFT),
+ .minInt32Value = 64,
+ .maxInt32Value = 80},
+ VehicleAreaConfig {
+ .areaId = toInt(VehicleAreaZone::ROW_1_RIGHT),
+ .minInt32Value = 64,
+ .maxInt32Value = 80,
+ }
+ }),
},
{
@@ -82,12 +101,23 @@ const VehiclePropConfig kVehicleProperties[] = {
.maxInt32Value = 10
}
})
+ },
+
+ {
+ .prop = VehicleProperty::MIRROR_FOLD,
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .permissionModel = VehiclePermissionModel::OEM_ONLY,
+
}
};
constexpr auto kTimeout = std::chrono::milliseconds(500);
class MockedVehicleCallback : public IVehicleCallback {
+private:
+ using MuxGuard = std::lock_guard<std::mutex>;
+ using HidlVecOfValues = hidl_vec<VehiclePropValue>;
public:
// Methods from ::android::hardware::vehicle::V2_0::IVehicleCallback follow.
Return<void> onPropertyEvent(
@@ -102,9 +132,9 @@ public:
Return<void> onPropertySet(const VehiclePropValue& value) override {
return Return<void>();
}
- Return<void> onError(StatusCode errorCode,
- VehicleProperty propId,
- VehiclePropertyOperation operation) override {
+ Return<void> onPropertySetError(StatusCode errorCode,
+ VehicleProperty propId,
+ int32_t areaId) override {
return Return<void>();
}
@@ -129,16 +159,14 @@ public:
mReceivedEvents.clear();
}
- const std::vector<hidl_vec<VehiclePropValue>>& getReceivedEvents() {
+ const std::vector<HidlVecOfValues>& getReceivedEvents() {
return mReceivedEvents;
}
private:
- using MuxGuard = std::lock_guard<std::mutex>;
-
std::mutex mLock;
std::condition_variable mEventCond;
- std::vector<hidl_vec<VehiclePropValue>> mReceivedEvents;
+ std::vector<HidlVecOfValues> mReceivedEvents;
};
template<typename T>
@@ -172,7 +200,7 @@ inline void assertAllExistsAnyOrder(
template<typename T>
inline std::string enumToHexString(T value) {
- return hexString(val(value));
+ return hexString(toInt(value));
}
template <typename T>
diff --git a/vehicle/2.0/default/vehicle_hal_manager/ConcurrentQueue.h b/vehicle/2.0/default/vehicle_hal_manager/ConcurrentQueue.h
index a64ef464bd..485f3dc383 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/ConcurrentQueue.h
+++ b/vehicle/2.0/default/vehicle_hal_manager/ConcurrentQueue.h
@@ -113,14 +113,15 @@ public:
void requestStop() {
if (mState.exchange(State::STOP_REQUESTED) != State::RUNNING) {
- mState = State::STOPPED;
- }
+ mState = State::STOPPED;
+ mCondStopped.notify_one();
+ }
}
void waitStopped() {
std::unique_lock<std::mutex> g(mLock);
while (State::STOPPED != mState) {
- mCondStopped.wait_for(g, std::chrono::seconds(1));
+ mCondStopped.wait(g);
}
}
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleCallback.cpp b/vehicle/2.0/default/vehicle_hal_manager/VehicleCallback.cpp
deleted file mode 100644
index 985b7dc5cf..0000000000
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleCallback.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "VehicleCallback.h"
-
-namespace android {
-namespace hardware {
-namespace vehicle {
-namespace V2_0 {
-namespace implementation {
-
-// Methods from ::android::hardware::vehicle::V2_0::IVehicleCallback follow.
-Return<void> VehicleCallback::onPropertyEvent(const hidl_vec<VehiclePropValue>& value) {
- // TODO(pavelm): add default implementation
- return Void();
-}
-
-// Methods from ::android::hardware::vehicle::V2_0::IVehicleCallback follow.
-Return<void> VehicleCallback::onPropertySet(const VehiclePropValue& value) {
- // TODO(pavelm): add default implementation
- return Void();
-}
-
-Return<void> VehicleCallback::onError(StatusCode errorCode,
- VehicleProperty propId,
- VehiclePropertyOperation operation) {
- // TODO(pavelm): add default implementation
- return Void();
-}
-
-
-IVehicleCallback* HIDL_FETCH_IVehicleCallback(const char* /* name */) {
- return new VehicleCallback();
-}
-
-} // namespace implementation
-} // namespace V2_0
-} // namespace vehicle
-} // namespace hardware
-} // namespace android
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleCallback.h b/vehicle/2.0/default/vehicle_hal_manager/VehicleCallback.h
deleted file mode 100644
index d037c94cf8..0000000000
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleCallback.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef HIDL_GENERATED_android_hardware_vehicle_V2_0_VehicleCallback_H_
-#define HIDL_GENERATED_android_hardware_vehicle_V2_0_VehicleCallback_H_
-
-#include <android/hardware/vehicle/2.0/IVehicleCallback.h>
-#include <hidl/Status.h>
-
-#include <hidl/MQDescriptor.h>
-namespace android {
-namespace hardware {
-namespace vehicle {
-namespace V2_0 {
-namespace implementation {
-
-using ::android::hardware::vehicle::V2_0::IVehicleCallback;
-using ::android::hardware::vehicle::V2_0::VehiclePropValue;
-using ::android::hardware::vehicle::V2_0::VehicleProperty;
-using ::android::hardware::vehicle::V2_0::VehiclePropertyOperation;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-using ::android::sp;
-
-struct VehicleCallback : public IVehicleCallback {
- // Methods from ::android::hardware::vehicle::V2_0::IVehicleCallback follow.
- Return<void> onPropertyEvent(const hidl_vec<VehiclePropValue>& values) override;
- Return<void> onPropertySet(const VehiclePropValue& value) override;
- Return<void> onError(StatusCode errorCode, VehicleProperty propId, VehiclePropertyOperation operation) override;
-
-};
-
-extern "C" IVehicleCallback* HIDL_FETCH_IVehicleCallback(const char* name);
-
-} // namespace implementation
-} // namespace V2_0
-} // namespace vehicle
-} // namespace hardware
-} // namespace android
-
-#endif // HIDL_GENERATED_android_hardware_vehicle_V2_0_VehicleCallback_H_
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.cpp b/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.cpp
index 8638131f2a..a84f991df2 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.cpp
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.cpp
@@ -20,6 +20,8 @@
#include <utils/Errors.h>
#include <utils/Log.h>
#include <hidl/Status.h>
+#include <future>
+#include <bitset>
#include "VehicleHalManager.h"
@@ -32,6 +34,8 @@ using namespace std::placeholders;
constexpr std::chrono::milliseconds kHalEventBatchingTimeWindow(10);
+const VehiclePropValue kEmptyValue{};
+
/**
* Indicates what's the maximum size of hidl_vec<VehiclePropValue> we want
* to store in reusable object pool.
@@ -40,6 +44,7 @@ constexpr auto kMaxHidlVecOfVehiclPropValuePoolSize = 20;
Return<void> VehicleHalManager::getAllPropConfigs(
getAllPropConfigs_cb _hidl_cb) {
+ ALOGI("getAllPropConfigs called");
hidl_vec<VehiclePropConfig> hidlConfigs;
auto& halConfig = mConfigIndex->getAllConfigs();
@@ -47,45 +52,72 @@ Return<void> VehicleHalManager::getAllPropConfigs(
const_cast<VehiclePropConfig *>(halConfig.data()),
halConfig.size());
+ ALOGI("getAllPropConfigs calling callback");
_hidl_cb(hidlConfigs);
- return hardware::Return<void>();
+ ALOGI("getAllPropConfigs done");
+ return Void();
}
Return<void> VehicleHalManager::getPropConfigs(
const hidl_vec<VehicleProperty> &properties,
getPropConfigs_cb _hidl_cb) {
- Vector<VehiclePropConfig> configs;
+ std::vector<VehiclePropConfig> configs;
for (size_t i = 0; i < properties.size(); i++) {
VehicleProperty prop = properties[i];
if (mConfigIndex->hasConfig(prop)) {
- configs.add(mConfigIndex->getConfig(prop));
+ configs.push_back(mConfigIndex->getConfig(prop));
} else {
- // TODO: return error
+ ALOGW("Requested config for undefined property: 0x%x", prop);
+ _hidl_cb(StatusCode::INVALID_ARG, hidl_vec<VehiclePropConfig>());
}
}
- hidl_vec<VehiclePropConfig> hidlConfigs;
- hidlConfigs.setToExternal(
- const_cast<VehiclePropConfig*>(configs.array()),
- configs.size());
-
- _hidl_cb(hidlConfigs);
+ _hidl_cb(StatusCode::OK, configs);
- return hardware::Return<void>();
+ return Void();
}
Return<void> VehicleHalManager::get(
- VehicleProperty propId, int32_t areaId, get_cb _hidl_cb) {
+ const VehiclePropValue& requestedPropValue, get_cb _hidl_cb) {
+ const auto* config = getPropConfigOrNull(requestedPropValue.prop);
+ if (config == nullptr) {
+ ALOGE("Failed to get value: config not found, property: 0x%x",
+ requestedPropValue.prop);
+ _hidl_cb(StatusCode::INVALID_ARG, kEmptyValue);
+ return Void();
+ }
- return hardware::Return<void>();
+ if (!checkReadPermission(*config, getCallee())) {
+ _hidl_cb(StatusCode::INVALID_ARG, kEmptyValue);
+ return Void();
+ }
+
+ StatusCode status;
+ auto value = mHal->get(requestedPropValue, &status);
+ _hidl_cb(status, value.get() ? *value : kEmptyValue);
+
+
+ return Void();
}
Return<StatusCode> VehicleHalManager::set(const VehiclePropValue &value) {
- // TODO(pavelm): check permission, etc
- // TODO(pavelm): check SET subscription
- // TODO(pavelm): propagate SET call to VehicleHal
- return hardware::Return<StatusCode>(StatusCode::OK);
+ auto prop = value.prop;
+ const auto* config = getPropConfigOrNull(prop);
+ if (config == nullptr) {
+ ALOGE("Failed to set value: config not found, property: 0x%x", prop);
+ return StatusCode::INVALID_ARG;
+ }
+
+ if (!checkWritePermission(*config, getCallee())) {
+ return StatusCode::INVALID_ARG;
+ }
+
+ handlePropertySetEvent(value);
+
+ auto status = mHal->set(value);
+
+ return Return<StatusCode>(status);
}
Return<StatusCode> VehicleHalManager::subscribe(
@@ -96,45 +128,40 @@ Return<StatusCode> VehicleHalManager::subscribe(
SubscribeOptions& ops = verifiedOptions[i];
VehicleProperty prop = ops.propId;
- if (!mConfigIndex->hasConfig(prop)) {
- ALOGE("Failed to subscribe: config not found for property: 0x%x",
+ const auto* config = getPropConfigOrNull(prop);
+ if (config == nullptr) {
+ ALOGE("Failed to subscribe: config not found, property: 0x%x",
prop);
- return invalidArg();
+ return StatusCode::INVALID_ARG;
}
- const VehiclePropConfig& config = mConfigIndex->getConfig(prop);
- if (!isSubscribable(config)) {
- ALOGE("Failed to subscribe: property is not subscribable: 0x%x",
+ if (!isSubscribable(*config, ops.flags)) {
+ ALOGE("Failed to subscribe: property 0x%x is not subscribable",
prop);
- return invalidArg();
+ return StatusCode::INVALID_ARG;
}
-
int32_t areas = isGlobalProp(prop) ? 0 : ops.vehicleAreas;
- if (areas != 0 && ((areas & config.supportedAreas) != areas)) {
+ if (areas != 0 && ((areas & config->supportedAreas) != areas)) {
ALOGE("Failed to subscribe property 0x%x. Requested areas 0x%x are "
"out of supported range of 0x%x", prop, ops.vehicleAreas,
- config.supportedAreas);
- return invalidArg();
+ config->supportedAreas);
+ return StatusCode::INVALID_ARG;
}
ops.vehicleAreas = areas;
- ops.sampleRate = checkSampleRate(config, ops.sampleRate);
+ ops.sampleRate = checkSampleRate(*config, ops.sampleRate);
}
- std::list<SubscribeOptions> updatedOptions =
- mSubscriptionManager.addOrUpdateSubscription(callback,
- verifiedOptions);
+ std::list<SubscribeOptions> updatedOptions =
+ mSubscriptionManager.addOrUpdateSubscription(callback, verifiedOptions);
for (auto opt : updatedOptions) {
mHal->subscribe(opt.propId, opt.vehicleAreas, opt.sampleRate);
}
-
- // TODO(pavelm): call immediately onHalEvent method during subscription
- // when appropriate
// TODO(pavelm): link to death callback (not implemented yet in HIDL)
- return ok();
+ return StatusCode::OK;
}
Return<StatusCode> VehicleHalManager::unsubscribe(
@@ -142,12 +169,12 @@ Return<StatusCode> VehicleHalManager::unsubscribe(
if (mSubscriptionManager.unsubscribe(callback, propId)) {
mHal->unsubscribe(propId);
}
- return ok();
+ return StatusCode::OK;
}
Return<void> VehicleHalManager::debugDump(IVehicle::debugDump_cb _hidl_cb) {
_hidl_cb("");
- return hardware::Return<void>();
+ return Void();
}
void VehicleHalManager::init() {
@@ -155,6 +182,7 @@ void VehicleHalManager::init() {
mHidlVecOfVehiclePropValuePool.resize(kMaxHidlVecOfVehiclPropValuePoolSize);
+
mBatchingConsumer.run(&mEventQueue,
kHalEventBatchingTimeWindow,
std::bind(&VehicleHalManager::onBatchHalEvent,
@@ -162,7 +190,8 @@ void VehicleHalManager::init() {
mHal->init(&mValueObjectPool,
std::bind(&VehicleHalManager::onHalEvent, this, _1),
- std::bind(&VehicleHalManager::onHalError, this, _1, _2, _3));
+ std::bind(&VehicleHalManager::onHalPropertySetError, this,
+ _1, _2, _3));
// Initialize index with vehicle configurations received from VehicleHal.
mConfigIndex.reset(new VehiclePropConfigIndex(mHal->listProperties()));
@@ -181,9 +210,15 @@ void VehicleHalManager::onHalEvent(VehiclePropValuePtr v) {
mEventQueue.push(std::move(v));
}
-void VehicleHalManager::onHalError(VehicleProperty property, status_t errorCode,
- VehiclePropertyOperation operation) {
- // TODO(pavelm): find subscribed clients and propagate error
+void VehicleHalManager::onHalPropertySetError(StatusCode errorCode,
+ VehicleProperty property,
+ int32_t areaId) {
+ const auto& clients = mSubscriptionManager.getSubscribedClients(
+ property, 0, SubscribeFlags::HAL_EVENT);
+
+ for (auto client : clients) {
+ client->getCallback()->onPropertySetError(errorCode, property, areaId);
+ }
}
void VehicleHalManager::onBatchHalEvent(
@@ -192,7 +227,7 @@ void VehicleHalManager::onBatchHalEvent(
values, SubscribeFlags::HAL_EVENT);
for (const HalClientValues& cv : clientValues) {
- int vecSize = cv.values.size();
+ auto vecSize = cv.values.size();
hidl_vec<VehiclePropValue> vec;
if (vecSize < kMaxHidlVecOfVehiclPropValuePoolSize) {
vec.setToExternal(&mHidlVecOfVehiclePropValuePool[0], vecSize);
@@ -236,9 +271,12 @@ float VehicleHalManager::checkSampleRate(const VehiclePropConfig &config,
return sampleRate; // Provided sample rate was good, no changes.
}
-bool VehicleHalManager::isSubscribable(const VehiclePropConfig& config) {
- if (!(config.access & VehiclePropertyAccess::READ)) {
- ALOGW("Cannot subscribe, property 0x%x is write only", config.prop);
+bool VehicleHalManager::isSubscribable(const VehiclePropConfig& config,
+ SubscribeFlags flags) {
+ bool isReadable = config.access & VehiclePropertyAccess::READ;
+
+ if (!isReadable && (SubscribeFlags::HAL_EVENT & flags)) {
+ ALOGW("Cannot subscribe, property 0x%x is not readable", config.prop);
return false;
}
if (config.changeMode == VehiclePropertyChangeMode::STATIC) {
@@ -254,6 +292,49 @@ bool VehicleHalManager::isSubscribable(const VehiclePropConfig& config) {
return true;
}
+bool VehicleHalManager::checkWritePermission(const VehiclePropConfig &config,
+ const Callee& callee) {
+ if (!(config.access & VehiclePropertyAccess::WRITE)) {
+ ALOGW("Property 0%x has no write access", config.prop);
+ return false;
+ }
+ //TODO(pavelm): check pid/uid has write access
+ return true;
+}
+
+bool VehicleHalManager::checkReadPermission(const VehiclePropConfig &config,
+ const Callee& callee) {
+ if (!(config.access & VehiclePropertyAccess::READ)) {
+ ALOGW("Property 0%x has no read access", config.prop);
+ return false;
+ }
+ //TODO(pavelm): check pid/uid has read access
+ return true;
+}
+
+void VehicleHalManager::handlePropertySetEvent(const VehiclePropValue& value) {
+ auto clients = mSubscriptionManager.getSubscribedClients(
+ value.prop, value.areaId, SubscribeFlags::SET_CALL);
+ for (auto client : clients) {
+ client->getCallback()->onPropertySet(value);
+ }
+}
+
+const VehiclePropConfig* VehicleHalManager::getPropConfigOrNull(
+ VehicleProperty prop) const {
+ return mConfigIndex->hasConfig(prop)
+ ? &mConfigIndex->getConfig(prop) : nullptr;
+}
+
+Callee VehicleHalManager::getCallee() {
+ Callee callee;
+ IPCThreadState* self = IPCThreadState::self();
+ callee.pid = self->getCallingPid();
+ callee.uid = self->getCallingUid();
+
+ return callee;
+}
+
} // namespace V2_0
} // namespace vehicle
} // namespace hardware
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.h b/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.h
index 0353a153a4..8353679807 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.h
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.h
@@ -40,6 +40,11 @@ namespace hardware {
namespace vehicle {
namespace V2_0 {
+struct Callee {
+ pid_t pid;
+ uid_t uid;
+};
+
/**
* This class is a thick proxy between IVehicle HIDL interface and vendor's implementation.
*
@@ -62,7 +67,8 @@ public:
Return<void> getAllPropConfigs(getAllPropConfigs_cb _hidl_cb) override;
Return<void> getPropConfigs(const hidl_vec<VehicleProperty>& properties,
getPropConfigs_cb _hidl_cb) override;
- Return<void> get(VehicleProperty propId, int32_t areaId, get_cb _hidl_cb) override;
+ Return<void> get(const VehiclePropValue& requestedPropValue,
+ get_cb _hidl_cb) override;
Return<StatusCode> set(const VehiclePropValue& value) override;
Return<StatusCode> subscribe(const sp<IVehicleCallback>& callback,
const hidl_vec<SubscribeOptions>& options) override;
@@ -72,29 +78,34 @@ public:
private:
using VehiclePropValuePtr = VehicleHal::VehiclePropValuePtr;
+ // Returns true if needs to call again shortly.
+ using RetriableAction = std::function<bool()>;
// ---------------------------------------------------------------------------------------------
// Events received from VehicleHal
void onHalEvent(VehiclePropValuePtr v);
- void onHalError(VehicleProperty property,
- status_t errorCode,
- VehiclePropertyOperation operation);
+ void onHalPropertySetError(StatusCode errorCode, VehicleProperty property,
+ int32_t areaId);
// ---------------------------------------------------------------------------------------------
// This method will be called from BatchingConsumer thread
void onBatchHalEvent(const std::vector<VehiclePropValuePtr >& values);
- static bool isSubscribable(const VehiclePropConfig& config);
+ void handlePropertySetEvent(const VehiclePropValue& value);
+
+ const VehiclePropConfig* getPropConfigOrNull(VehicleProperty prop) const;
+
+ static bool isSubscribable(const VehiclePropConfig& config,
+ SubscribeFlags flags);
static bool isSampleRateFixed(VehiclePropertyChangeMode mode);
static float checkSampleRate(const VehiclePropConfig& config,
float sampleRate);
+ static bool checkWritePermission(const VehiclePropConfig &config,
+ const Callee& callee);
+ static bool checkReadPermission(const VehiclePropConfig &config,
+ const Callee& callee);
- static Return<StatusCode> ok() {
- return Return<StatusCode>(StatusCode::OK);
- }
- static Return<StatusCode> invalidArg() {
- return Return<StatusCode>(StatusCode::INVALID_ARG);
- }
+ static Callee getCallee();
private:
VehicleHal* mHal;
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h
index 02bfb3f4f9..b4a4b3e1f9 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h
@@ -194,6 +194,10 @@ public:
}
RecyclableType obtain(const VehiclePropValue& src) {
+ if (src.prop == VehicleProperty::INVALID) {
+ ALOGE("Unable to obtain an object from pool for unknown property");
+ return RecyclableType();
+ }
VehiclePropertyType type = getPropType(src.prop);
size_t vecSize = getVehicleRawValueVectorSize(src.value, type);;
auto dest = obtain(type, vecSize);
@@ -206,6 +210,10 @@ public:
return dest;
}
+ RecyclableType obtainBoolean(bool value) {
+ return obtainInt32(value);
+ }
+
RecyclableType obtainInt32(int32_t value) {
auto val = obtain(VehiclePropertyType::INT32);
val->value.int32Values[0] = value;
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.h b/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.h
index f23a235c3f..5751eb1f3b 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.h
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.h
@@ -54,7 +54,7 @@ inline typename std::underlying_type<ENUM>::type operator &(ENUM v1, ENUM v2) {
/** Returns underlying (integer) value for given enum. */
template <typename ENUM>
-inline typename std::underlying_type<ENUM>::type val(ENUM const value) {
+inline typename std::underlying_type<ENUM>::type toInt(ENUM const value) {
return static_cast<typename std::underlying_type<ENUM>::type>(value);
}
diff --git a/vehicle/2.0/types.hal b/vehicle/2.0/types.hal
index 03c1021c06..adcc90ce36 100644
--- a/vehicle/2.0/types.hal
+++ b/vehicle/2.0/types.hal
@@ -611,20 +611,24 @@ enum VehicleProperty: int32_t {
* Property to control audio volume of each audio context.
*
* VehiclePropConfig
- * configArray[0] : bit flags of all supported audio contexts. If this
- * is 0, audio volume is controlled per physical stream
+ * configArray[0] : bit flags of all supported audio contexts from
+ * VehicleAudioContextFlag. If this is 0, audio volume is
+ * controlled per physical stream.
* configArray[1] : flags defined in VehicleAudioVolumeCapabilityFlag to
- * represent audio module's capability.
+ * represent audio module's capability.
+ * configArray[2..3] : reserved
+ * configArray[4..N+3] : maximum values for each audio context, where N is
+ * the number of audio contexts provided in
+ * configArray[0], minimum value is always 0 which
+ * indicates mute state.
*
* Data type looks like:
* int32Values[0] : stream context as defined in VehicleAudioContextFlag.
* If only physical stream is supported
* (configArray[0] == 0), this must represent physical
- stream number.
- * int32Values[1] : volume level, valid range is 0 to int32MaxValue
- * defined in config.
- * 0 must be mute state. int32MinValue config must be
- * always 0.
+ * stream number.
+ * int32Values[1] : volume level, valid range is 0 (mute) to max level
+ * defined in the config.
* int32Values[2] : One of VehicleAudioVolumeState.
*
* This property requires per stream based get. HAL implementation must
@@ -765,7 +769,7 @@ enum VehicleProperty: int32_t {
* will be set to 0x2|0x4.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:WRITE|VehiclePropertyAccess:READ_WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
* @config_string List of all avaiable external source in the system.
*/
AUDIO_EXT_ROUTING_HINT = (
@@ -790,7 +794,7 @@ enum VehicleProperty: int32_t {
* to other displays.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ|VehiclePropertyAccess:READ_WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
DISPLAY_BRIGHTNESS = (
0x0A01
@@ -909,7 +913,7 @@ enum VehicleProperty: int32_t {
* ability to write this property.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
DOOR_POS = (
0x0B00
@@ -921,7 +925,7 @@ enum VehicleProperty: int32_t {
* Door move
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
DOOR_MOVE = (
0x0B01
@@ -963,7 +967,7 @@ enum VehicleProperty: int32_t {
* Positive value indicates tilt upwards, negative value is downwards
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
MIRROR_Z_MOVE = (
0x0B41
@@ -991,7 +995,7 @@ enum VehicleProperty: int32_t {
* Positive value indicate tilt right, negative value is left
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
MIRROR_Y_MOVE = (
0x0B43
@@ -1042,11 +1046,15 @@ enum VehicleProperty: int32_t {
| VehicleArea:GLOBAL),
/*
- * Seat memory set
+ * Seat memory select
*
- * This setting allows the user to save the current seat position settings
- * into the selected preset slot. The maxValue for each seat position shall
- * match the maxValue for SEAT_MEMORY_SELECT.
+ * This parameter selects the memory preset to use to select the seat
+ * position. The minValue is always 0, and the maxValue determines the
+ * number of seat positions available.
+ *
+ * For instance, if the driver's seat has 3 memory presets, the maxValue
+ * will be 3. When the user wants to select a preset, the desired preset
+ * number (1, 2, or 3) is set.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
* @access VehiclePropertyAccess:WRITE
@@ -1082,7 +1090,7 @@ enum VehicleProperty: int32_t {
* no known cars at this time, but you never know...
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
SEAT_BELT_BUCKLED = (
0x0B82
@@ -1110,7 +1118,7 @@ enum VehicleProperty: int32_t {
* Seatbelt height move
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
SEAT_BELT_HEIGHT_MOVE = (
0x0B84
@@ -1140,7 +1148,7 @@ enum VehicleProperty: int32_t {
* Moves the seat position forward and aft.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
SEAT_FORE_AFT_MOVE = (
0x0B86
@@ -1170,7 +1178,7 @@ enum VehicleProperty: int32_t {
* Moves the backrest forward or recline.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
SEAT_BACKREST_ANGLE_1_MOVE = (
0x0B88
@@ -1200,7 +1208,7 @@ enum VehicleProperty: int32_t {
* Moves the backrest forward or recline.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
SEAT_BACKREST_ANGLE_2_MOVE = (
0x0B8A
@@ -1230,7 +1238,7 @@ enum VehicleProperty: int32_t {
* Moves the seat height.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
SEAT_HEIGHT_MOVE = (
0x0B8C
@@ -1260,7 +1268,7 @@ enum VehicleProperty: int32_t {
* Adjusts the seat depth.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
SEAT_DEPTH_MOVE = (
0x0B8E
@@ -1290,7 +1298,7 @@ enum VehicleProperty: int32_t {
* Tilts the seat.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
SEAT_TILT_MOVE = (
0x0B90
@@ -1320,7 +1328,7 @@ enum VehicleProperty: int32_t {
* Adjusts the lumbar support.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
SEAT_LUMBAR_FORE_AFT_MOVE = (
0x0B92
@@ -1350,7 +1358,7 @@ enum VehicleProperty: int32_t {
* Adjusts the amount of lateral lumbar support.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
SEAT_LUMBAR_SIDE_SUPPORT_MOVE = (
0x0B94
@@ -1380,7 +1388,7 @@ enum VehicleProperty: int32_t {
* Moves the headrest up and down.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
SEAT_HEADREST_HEIGHT_MOVE = (
0x0B96
@@ -1410,7 +1418,7 @@ enum VehicleProperty: int32_t {
* Adjusts the angle of the headrest
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
SEAT_HEADREST_ANGLE_MOVE = (
0x0B98
@@ -1432,7 +1440,7 @@ enum VehicleProperty: int32_t {
/*
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
SEAT_HEADREST_FORE_AFT_MOVE = (
0x0B9A
@@ -1464,7 +1472,7 @@ enum VehicleProperty: int32_t {
* the window.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
WINDOW_MOVE = (
0x0BC1
@@ -1498,7 +1506,7 @@ enum VehicleProperty: int32_t {
* Min = vent closed
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE|VehiclePropertyAccess:WRITE
+ * @access VehiclePropertyAccess:READ_WRITE
*/
WINDOW_VENT_MOVE = (
0x0BC3
@@ -1716,8 +1724,8 @@ enum VehicleAudioVolumeCapabilityFlag : int32_t {
/*
* External audio module or vehicle hal has persistent storage
* to keep the volume level. This must be set only when per context
- * volume level is supproted. When this is set, audio volume level per
- * each context will be retrieved from the property when systen starts up.
+ * volume level is supported. When this is set, audio volume level per
+ * each context will be retrieved from the property when system starts up.
* And external audio module is also expected to adjust volume automatically
* whenever there is an audio context change.
* When this flag is not set, android side will assume that there is no
@@ -1755,7 +1763,7 @@ enum VehicleAudioVolumeState : int32_t {
enum VehicleAudioVolumeIndex : int32_t {
INDEX_STREAM = 0,
INDEX_VOLUME = 1,
- NDEX_STATE = 2,
+ INDEX_STATE = 2,
};
/*
@@ -2336,12 +2344,15 @@ enum VehiclePropertyOperation : int32_t {
enum SubscribeFlags {
UNDEFINED = 0x0,
- /* Subscribe to event that was originated in vehicle HAL (most luckly this
+ /*
+ * Subscribe to event that was originated in vehicle HAL (most luckly this
* event came from vehicle itself). */
HAL_EVENT = 0x1,
- /* Use this flag to subscribe on events when IVehicle#set(...) was called by
- * vehicle HAL's client (e.g. Car Service). */
+ /*
+ * Use this flag to subscribe on events when IVehicle#set(...) was called by
+ * vehicle HAL's client (e.g. Car Service).
+ */
SET_CALL = 0x2,
DEFAULT = HAL_EVENT,
@@ -2352,10 +2363,12 @@ enum SubscribeFlags {
*/
struct SubscribeOptions {
/* Property to subscribe */
-
VehicleProperty propId;
- /* Area ids - this must be a bit mask of areas to subscribe or 0 to subscribe to all areas. */
+ /*
+ * Area ids - this must be a bit mask of areas to subscribe or 0 to subscribe
+ * to all areas.
+ */
int32_t vehicleAreas;
/*
@@ -2380,15 +2393,21 @@ enum StatusCode {
OK = 0,
/* Try again. */
- TRY_AGAIN = -11,
+ TRY_AGAIN = 1,
/* Invalid argument provided. */
- INVALID_ARG = -22,
+ INVALID_ARG = 2,
/*
* This code must be returned when device that associated with the vehicle
* property is not available. For example, when client tries to set HVAC
* temperature when the whole HVAC unit is turned OFF.
*/
- NOT_AVAILABLE = -108,
+ NOT_AVAILABLE = 3,
+
+ /* Access denied */
+ ACCESS_DENIED = 4,
+
+ /* Something unexpected has happened in Vehicle HAL */
+ INTERNAL_ERROR = 5,
};