Implement getAllPropConfigs for VHAL cpp client.
Test: atest libvhalclient_test
Bug: 214635003
Change-Id: Idfc808730d9dc5a124eb1a4ffae6a0f5cf9df5f0
diff --git a/cpp/vhal/client/include/AidlVhalClient.h b/cpp/vhal/client/include/AidlVhalClient.h
index c09ab7e..e94bf30 100644
--- a/cpp/vhal/client/include/AidlVhalClient.h
+++ b/cpp/vhal/client/include/AidlVhalClient.h
@@ -72,6 +72,8 @@
::android::base::Result<std::vector<std::unique_ptr<IHalPropConfig>>> getAllPropConfigs()
override;
+ ::android::base::Result<std::vector<std::unique_ptr<IHalPropConfig>>> getPropConfigs(
+ std::vector<int32_t> propIds) override;
std::unique_ptr<ISubscriptionClient> getSubscriptionClient(
std::shared_ptr<ISubscriptionCallback> callback) override;
@@ -112,6 +114,9 @@
void onBinderDiedWithContext();
void onBinderUnlinkedWithContext();
+ ::android::base::Result<std::vector<std::unique_ptr<IHalPropConfig>>> parseVehiclePropConfigs(
+ const ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs& configs);
+
// Test-only functions:
AidlVhalClient(std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicle> hal,
int64_t timeoutInMs, std::unique_ptr<ILinkUnlinkToDeath> linkUnlinkImpl);
diff --git a/cpp/vhal/client/include/IVhalClient.h b/cpp/vhal/client/include/IVhalClient.h
index 6156503..9b1775f 100644
--- a/cpp/vhal/client/include/IVhalClient.h
+++ b/cpp/vhal/client/include/IVhalClient.h
@@ -89,6 +89,9 @@
virtual ::android::base::Result<std::vector<std::unique_ptr<IHalPropConfig>>>
getAllPropConfigs() = 0;
+ virtual ::android::base::Result<std::vector<std::unique_ptr<IHalPropConfig>>> getPropConfigs(
+ std::vector<int32_t> propIds) = 0;
+
virtual std::unique_ptr<ISubscriptionClient> getSubscriptionClient(
std::shared_ptr<ISubscriptionCallback> callback) = 0;
};
diff --git a/cpp/vhal/client/src/AidlVhalClient.cpp b/cpp/vhal/client/src/AidlVhalClient.cpp
index cd59ece..ddf5362 100644
--- a/cpp/vhal/client/src/AidlVhalClient.cpp
+++ b/cpp/vhal/client/src/AidlVhalClient.cpp
@@ -16,6 +16,9 @@
#include "AidlVhalClient.h"
+#include <android-base/strings.h>
+
+#include <AidlHalPropConfig.h>
#include <AidlHalPropValue.h>
#include <ParcelableUtils.h>
#include <VehicleUtils.h>
@@ -26,7 +29,10 @@
namespace automotive {
namespace vhal {
+namespace {
+
using ::android::base::Error;
+using ::android::base::Join;
using ::android::base::Result;
using ::android::hardware::automotive::vehicle::fromStableLargeParcelable;
using ::android::hardware::automotive::vehicle::PendingRequestPool;
@@ -43,6 +49,8 @@
using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
@@ -50,6 +58,16 @@
using ::ndk::ScopedAIBinder_DeathRecipient;
using ::ndk::ScopedAStatus;
+std::string toString(const std::vector<int32_t>& values) {
+ std::vector<std::string> strings;
+ for (int32_t value : values) {
+ strings.push_back(std::to_string(value));
+ }
+ return "[" + Join(strings, ",") + "]";
+}
+
+} // namespace
+
AidlVhalClient::AidlVhalClient(std::shared_ptr<IVehicle> hal) :
AidlVhalClient(hal, DEFAULT_TIMEOUT_IN_SEC * 1'000) {}
@@ -117,8 +135,39 @@
}
Result<std::vector<std::unique_ptr<IHalPropConfig>>> AidlVhalClient::getAllPropConfigs() {
- // TODO(b/214635003): implement this.
- return {};
+ VehiclePropConfigs configs;
+ if (ScopedAStatus status = mHal->getAllPropConfigs(&configs); !status.isOk()) {
+ return Error(status.getServiceSpecificError())
+ << "failed to get all property configs, error: " << status.getMessage();
+ }
+ return parseVehiclePropConfigs(configs);
+}
+
+Result<std::vector<std::unique_ptr<IHalPropConfig>>> AidlVhalClient::getPropConfigs(
+ std::vector<int32_t> propIds) {
+ VehiclePropConfigs configs;
+ if (ScopedAStatus status = mHal->getPropConfigs(propIds, &configs); !status.isOk()) {
+ return Error(status.getServiceSpecificError())
+ << "failed to prop configs for prop IDs: " << toString(propIds)
+ << ", error: " << status.getMessage();
+ }
+ return parseVehiclePropConfigs(configs);
+}
+
+Result<std::vector<std::unique_ptr<IHalPropConfig>>> AidlVhalClient::parseVehiclePropConfigs(
+ const VehiclePropConfigs& configs) {
+ auto parcelableResult = fromStableLargeParcelable(configs);
+ if (!parcelableResult.ok()) {
+ return Error(toInt(StatusCode::INTERNAL_ERROR))
+ << "failed to parse VehiclePropConfigs returned from VHAL, error: "
+ << parcelableResult.error().getMessage();
+ }
+ std::vector<std::unique_ptr<IHalPropConfig>> out;
+ for (const VehiclePropConfig& config : parcelableResult.value().getObject()->payloads) {
+ VehiclePropConfig configCopy = config;
+ out.push_back(std::make_unique<AidlHalPropConfig>(std::move(configCopy)));
+ }
+ return out;
}
void AidlVhalClient::onBinderDied(void* cookie) {
diff --git a/cpp/vhal/client/test/AidlVhalClientTest.cpp b/cpp/vhal/client/test/AidlVhalClientTest.cpp
index 2f7810b..9185c18 100644
--- a/cpp/vhal/client/test/AidlVhalClientTest.cpp
+++ b/cpp/vhal/client/test/AidlVhalClientTest.cpp
@@ -51,6 +51,7 @@
using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
@@ -66,7 +67,12 @@
mCv.wait_for(lk, std::chrono::milliseconds(1000), [this] { return mThreadCount == 0; });
}
- ScopedAStatus getAllPropConfigs([[maybe_unused]] VehiclePropConfigs* returnConfigs) override {
+ ScopedAStatus getAllPropConfigs(VehiclePropConfigs* returnConfigs) override {
+ if (mStatus != StatusCode::OK) {
+ return ScopedAStatus::fromServiceSpecificError(toInt(mStatus));
+ }
+
+ returnConfigs->payloads = mPropConfigs;
return ScopedAStatus::ok();
}
@@ -120,8 +126,14 @@
return ScopedAStatus::ok();
}
- ScopedAStatus getPropConfigs([[maybe_unused]] const std::vector<int32_t>& props,
- [[maybe_unused]] VehiclePropConfigs* returnConfigs) override {
+ ScopedAStatus getPropConfigs(const std::vector<int32_t>& props,
+ VehiclePropConfigs* returnConfigs) override {
+ mGetPropConfigPropIds = props;
+ if (mStatus != StatusCode::OK) {
+ return ScopedAStatus::fromServiceSpecificError(toInt(mStatus));
+ }
+
+ returnConfigs->payloads = mPropConfigs;
return ScopedAStatus::ok();
}
@@ -155,12 +167,18 @@
void setStatus(StatusCode status) { mStatus = status; }
+ void setPropConfigs(std::vector<VehiclePropConfig> configs) { mPropConfigs = configs; }
+
+ std::vector<int32_t> getGetPropConfigPropIds() { return mGetPropConfigPropIds; }
+
private:
std::mutex mLock;
std::vector<GetValueResult> mGetValueResults;
std::vector<GetValueRequest> mGetValueRequests;
std::vector<SetValueResult> mSetValueResults;
std::vector<SetValueRequest> mSetValueRequests;
+ std::vector<VehiclePropConfig> mPropConfigs;
+ std::vector<int32_t> mGetPropConfigPropIds;
int64_t mWaitTimeInMs = 0;
StatusCode mStatus = StatusCode::OK;
std::condition_variable mCv;
@@ -191,6 +209,7 @@
constexpr static int32_t TEST_PROP_ID = 1;
constexpr static int32_t TEST_AREA_ID = 2;
+ constexpr static int32_t TEST_PROP_ID_2 = 3;
constexpr static int64_t TEST_TIMEOUT_IN_MS = 100;
void SetUp() override {
@@ -624,6 +643,92 @@
ASSERT_EQ(countOnBinderDiedCallbacks(), static_cast<size_t>(0));
}
+TEST_F(AidlVhalClientTest, testGetAllPropConfigs) {
+ getVhal()->setPropConfigs({
+ VehiclePropConfig{
+ .prop = TEST_PROP_ID,
+ .areaConfigs = {{
+ .areaId = TEST_AREA_ID,
+ .minInt32Value = 0,
+ .maxInt32Value = 1,
+ }},
+ },
+ VehiclePropConfig{
+ .prop = TEST_PROP_ID_2,
+ },
+ });
+
+ auto result = getClient()->getAllPropConfigs();
+
+ ASSERT_TRUE(result.ok());
+ std::vector<std::unique_ptr<IHalPropConfig>> configs = std::move(result.value());
+
+ ASSERT_EQ(configs.size(), static_cast<size_t>(2));
+ ASSERT_EQ(configs[0]->getPropId(), TEST_PROP_ID);
+ ASSERT_EQ(configs[0]->getAreaConfigSize(), static_cast<size_t>(1));
+
+ const IHalAreaConfig* areaConfig = configs[0]->getAreaConfigs();
+ ASSERT_EQ(areaConfig->getAreaId(), TEST_AREA_ID);
+ ASSERT_EQ(areaConfig->getMinInt32Value(), 0);
+ ASSERT_EQ(areaConfig->getMaxInt32Value(), 1);
+
+ ASSERT_EQ(configs[1]->getPropId(), TEST_PROP_ID_2);
+ ASSERT_EQ(configs[1]->getAreaConfigSize(), static_cast<size_t>(0));
+}
+
+TEST_F(AidlVhalClientTest, testGetAllPropConfigsError) {
+ getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
+
+ auto result = getClient()->getAllPropConfigs();
+
+ ASSERT_FALSE(result.ok());
+ ASSERT_EQ(result.error().code(), toInt(StatusCode::INTERNAL_ERROR));
+}
+
+TEST_F(AidlVhalClientTest, testGetPropConfigs) {
+ getVhal()->setPropConfigs({
+ VehiclePropConfig{
+ .prop = TEST_PROP_ID,
+ .areaConfigs = {{
+ .areaId = TEST_AREA_ID,
+ .minInt32Value = 0,
+ .maxInt32Value = 1,
+ }},
+ },
+ VehiclePropConfig{
+ .prop = TEST_PROP_ID_2,
+ },
+ });
+
+ std::vector<int32_t> propIds = {TEST_PROP_ID, TEST_PROP_ID_2};
+ auto result = getClient()->getPropConfigs(propIds);
+
+ ASSERT_EQ(getVhal()->getGetPropConfigPropIds(), propIds);
+ ASSERT_TRUE(result.ok());
+ std::vector<std::unique_ptr<IHalPropConfig>> configs = std::move(result.value());
+
+ ASSERT_EQ(configs.size(), static_cast<size_t>(2));
+ ASSERT_EQ(configs[0]->getPropId(), TEST_PROP_ID);
+ ASSERT_EQ(configs[0]->getAreaConfigSize(), static_cast<size_t>(1));
+
+ const IHalAreaConfig* areaConfig = configs[0]->getAreaConfigs();
+ ASSERT_EQ(areaConfig->getAreaId(), TEST_AREA_ID);
+ ASSERT_EQ(areaConfig->getMinInt32Value(), 0);
+ ASSERT_EQ(areaConfig->getMaxInt32Value(), 1);
+
+ ASSERT_EQ(configs[1]->getPropId(), TEST_PROP_ID_2);
+ ASSERT_EQ(configs[1]->getAreaConfigSize(), static_cast<size_t>(0));
+}
+
+TEST_F(AidlVhalClientTest, testGetPropConfigsError) {
+ getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
+
+ std::vector<int32_t> propIds = {TEST_PROP_ID, TEST_PROP_ID_2};
+ auto result = getClient()->getPropConfigs(propIds);
+
+ ASSERT_FALSE(result.ok());
+}
+
} // namespace test
} // namespace vhal
} // namespace automotive