diff --git a/automotive/vehicle/TEST_MAPPING b/automotive/vehicle/TEST_MAPPING index e1a90cba39..117c872abf 100644 --- a/automotive/vehicle/TEST_MAPPING +++ b/automotive/vehicle/TEST_MAPPING @@ -55,5 +55,10 @@ { "name": "VehicleHalProtoMessageConverterTest" } + ], + "postsubmit": [ + { + "name": "VehicleHalProtoMessageConverterTest" + } ] } diff --git a/automotive/vehicle/aidl/impl/grpc/Android.bp b/automotive/vehicle/aidl/impl/grpc/Android.bp index fd1d1ca75a..7a8da59074 100644 --- a/automotive/vehicle/aidl/impl/grpc/Android.bp +++ b/automotive/vehicle/aidl/impl/grpc/Android.bp @@ -22,7 +22,7 @@ genrule { "aprotoc", "protoc-gen-grpc-cpp-plugin", ], - cmd: "$(location aprotoc) -I$$(dirname $(location proto/VehicleServer.proto)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(location proto/VehicleServer.proto) --grpc_out=$(genDir) --cpp_out=$(genDir)", + cmd: "$(location aprotoc) -I$$(dirname $(location proto/VehicleServer.proto)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(location proto/VehicleServer.proto) --grpc_opt=generate_mock_code=true --grpc_out=$(genDir) --cpp_out=$(genDir)", srcs: [ "proto/VehicleServer.proto", ":libprotobuf-internal-protos", @@ -31,6 +31,7 @@ genrule { out: [ "VehicleServer.pb.h", "VehicleServer.grpc.pb.h", + "VehicleServer_mock.grpc.pb.h", ], visibility: ["//visibility:private"], } diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp index 07422835d2..2e5d2e46c3 100644 --- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp +++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp @@ -39,6 +39,13 @@ GRPCVehicleHardware::GRPCVehicleHardware(std::string service_addr) mGrpcStub(proto::VehicleServer::NewStub(mGrpcChannel)), mValuePollingThread([this] { ValuePollingLoop(); }) {} +// Only used for unit testing. +GRPCVehicleHardware::GRPCVehicleHardware(std::unique_ptr stub) + : mServiceAddr(""), + mGrpcChannel(nullptr), + mGrpcStub(std::move(stub)), + mValuePollingThread([] {}) {} + GRPCVehicleHardware::~GRPCVehicleHardware() { { std::lock_guard lck(mShutdownMutex); @@ -181,6 +188,24 @@ aidlvhal::StatusCode GRPCVehicleHardware::checkHealth() { return static_cast(protoStatus.status_code()); } +aidlvhal::StatusCode GRPCVehicleHardware::subscribe(aidlvhal::SubscribeOptions options) { + proto::SubscribeRequest request; + ::grpc::ClientContext context; + proto::VehicleHalCallStatus protoStatus; + proto_msg_converter::aidlToProto(options, request.mutable_options()); + auto grpc_status = mGrpcStub->Subscribe(&context, request, &protoStatus); + if (!grpc_status.ok()) { + if (grpc_status.error_code() == ::grpc::StatusCode::UNIMPLEMENTED) { + // This is a legacy sever. It should handle updateSampleRate. + LOG(INFO) << __func__ << ": GRPC Subscribe is not supported by the server"; + return aidlvhal::StatusCode::OK; + } + LOG(ERROR) << __func__ << ": GRPC Subscribe Failed: " << grpc_status.error_message(); + return aidlvhal::StatusCode::INTERNAL_ERROR; + } + return static_cast(protoStatus.status_code()); +} + aidlvhal::StatusCode GRPCVehicleHardware::updateSampleRate(int32_t propId, int32_t areaId, float sampleRate) { ::grpc::ClientContext context; diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h index ddd620ea2e..bec957cc97 100644 --- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h +++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h @@ -43,6 +43,9 @@ class GRPCVehicleHardware : public IVehicleHardware { public: explicit GRPCVehicleHardware(std::string service_addr); + // Only used for unit testing. + explicit GRPCVehicleHardware(std::unique_ptr stub); + ~GRPCVehicleHardware(); // Get all the property configs. @@ -80,6 +83,8 @@ class GRPCVehicleHardware : public IVehicleHardware { aidlvhal::StatusCode updateSampleRate(int32_t propId, int32_t areaId, float sampleRate) override; + aidlvhal::StatusCode subscribe(aidlvhal::SubscribeOptions options) override; + bool waitForConnected(std::chrono::milliseconds waitTime); protected: @@ -91,7 +96,7 @@ class GRPCVehicleHardware : public IVehicleHardware { std::string mServiceAddr; std::shared_ptr<::grpc::Channel> mGrpcChannel; - std::unique_ptr mGrpcStub; + std::unique_ptr mGrpcStub; std::thread mValuePollingThread; std::unique_ptr mOnSetErr; diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp index af3dd595a1..558ab2f250 100644 --- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp +++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp @@ -164,6 +164,17 @@ GrpcVehicleProxyServer::GrpcVehicleProxyServer(std::string serverAddr, return ::grpc::Status::OK; } +::grpc::Status GrpcVehicleProxyServer::Subscribe(::grpc::ServerContext* context, + const proto::SubscribeRequest* request, + proto::VehicleHalCallStatus* status) { + const auto& protoSubscribeOptions = request->options(); + aidlvhal::SubscribeOptions aidlSubscribeOptions = {}; + proto_msg_converter::protoToAidl(protoSubscribeOptions, &aidlSubscribeOptions); + const auto status_code = mHardware->subscribe(aidlSubscribeOptions); + status->set_status_code(static_cast(status_code)); + return ::grpc::Status::OK; +} + ::grpc::Status GrpcVehicleProxyServer::CheckHealth(::grpc::ServerContext* context, const ::google::protobuf::Empty*, proto::VehicleHalCallStatus* status) { diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h index 3596354539..4f0c1e4bcb 100644 --- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h +++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h @@ -57,6 +57,9 @@ class GrpcVehicleProxyServer : public proto::VehicleServer::Service { const proto::UpdateSampleRateRequest* request, proto::VehicleHalCallStatus* status) override; + ::grpc::Status Subscribe(::grpc::ServerContext* context, const proto::SubscribeRequest* request, + proto::VehicleHalCallStatus* status) override; + ::grpc::Status CheckHealth(::grpc::ServerContext* context, const ::google::protobuf::Empty*, proto::VehicleHalCallStatus* status) override; diff --git a/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto b/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto index 22b11d8c87..d4b5642c06 100644 --- a/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto +++ b/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto @@ -20,6 +20,7 @@ package android.hardware.automotive.vehicle.proto; import "android/hardware/automotive/vehicle/DumpOptions.proto"; import "android/hardware/automotive/vehicle/DumpResult.proto"; +import "android/hardware/automotive/vehicle/SubscribeRequest.proto"; import "android/hardware/automotive/vehicle/StatusCode.proto"; import "android/hardware/automotive/vehicle/VehiclePropConfig.proto"; import "android/hardware/automotive/vehicle/VehiclePropValue.proto"; @@ -40,4 +41,6 @@ service VehicleServer { rpc Dump(DumpOptions) returns (DumpResult) {} rpc StartPropertyValuesStream(google.protobuf.Empty) returns (stream VehiclePropValues) {} + + rpc Subscribe(SubscribeRequest) returns (VehicleHalCallStatus) {} } diff --git a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp index f578021f1b..24f078e524 100644 --- a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp +++ b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp @@ -15,6 +15,7 @@ #include "GRPCVehicleHardware.h" #include "VehicleServer.grpc.pb.h" #include "VehicleServer.pb.h" +#include "VehicleServer_mock.grpc.pb.h" #include #include @@ -26,6 +27,17 @@ namespace android::hardware::automotive::vehicle::virtualization { +namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle; + +using ::testing::_; +using ::testing::DoAll; +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::SaveArg; +using ::testing::SetArgPointee; + +using proto::MockVehicleServerStub; + const std::string kFakeServerAddr = "0.0.0.0:54321"; class FakeVehicleServer : public proto::VehicleServer::Service { @@ -91,4 +103,82 @@ TEST(GRPCVehicleHardwareUnitTest, Reconnect) { } } +class GRPCVehicleHardwareMockServerUnitTest : public ::testing::Test { + protected: + NiceMock* mGrpcStub; + std::unique_ptr mHardware; + + void SetUp() override { + auto stub = std::make_unique>(); + ; + mGrpcStub = stub.get(); + mHardware = std::make_unique(std::move(stub)); + } + + void TearDown() override { mHardware.reset(); } +}; + +MATCHER_P(RepeatedInt32Eq, expected_values, "") { + return std::vector(arg.begin(), arg.end()) == expected_values; +} + +TEST_F(GRPCVehicleHardwareMockServerUnitTest, Subscribe) { + proto::VehicleHalCallStatus protoStatus; + protoStatus.set_status_code(proto::StatusCode::OK); + proto::SubscribeRequest actualRequest; + + EXPECT_CALL(*mGrpcStub, Subscribe(_, _, _)) + .WillOnce(DoAll(SaveArg<1>(&actualRequest), SetArgPointee<2>(protoStatus), + Return(::grpc::Status::OK))); + + aidlvhal::SubscribeOptions options = {.propId = 1, + .areaIds = {1, 2, 3, 4}, + .sampleRate = 1.234, + .resolution = 0.01, + .enableVariableUpdateRate = true}; + auto status = mHardware->subscribe(options); + + EXPECT_EQ(status, aidlvhal::StatusCode::OK); + const auto& protoOptions = actualRequest.options(); + EXPECT_EQ(protoOptions.prop_id(), 1); + EXPECT_THAT(protoOptions.area_ids(), RepeatedInt32Eq(std::vector({1, 2, 3, 4}))); + EXPECT_FLOAT_EQ(protoOptions.sample_rate(), 1.234); + EXPECT_FLOAT_EQ(protoOptions.resolution(), 0.01); + EXPECT_EQ(protoOptions.enable_variable_update_rate(), true); +} + +TEST_F(GRPCVehicleHardwareMockServerUnitTest, SubscribeLegacyServer) { + EXPECT_CALL(*mGrpcStub, Subscribe(_, _, _)) + .WillOnce(Return(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""))); + + aidlvhal::SubscribeOptions options; // Your options here (consider adding sample data) + auto status = mHardware->subscribe(options); + + EXPECT_EQ(status, aidlvhal::StatusCode::OK); +} + +TEST_F(GRPCVehicleHardwareMockServerUnitTest, SubscribeGrpcFailure) { + EXPECT_CALL(*mGrpcStub, Subscribe(_, _, _)) + .WillOnce(Return(::grpc::Status(::grpc::StatusCode::INTERNAL, "GRPC Error"))); + + aidlvhal::SubscribeOptions options; + auto status = mHardware->subscribe(options); + + EXPECT_EQ(status, aidlvhal::StatusCode::INTERNAL_ERROR); +} + +TEST_F(GRPCVehicleHardwareMockServerUnitTest, SubscribeProtoFailure) { + proto::VehicleHalCallStatus protoStatus; + protoStatus.set_status_code(proto::StatusCode::NOT_AVAILABLE_SPEED_LOW); + + EXPECT_CALL(*mGrpcStub, Subscribe(_, _, _)) + .WillOnce(DoAll(SetArgPointee<2>(protoStatus), // Set the output status + Return(::grpc::Status::OK))); + + aidlvhal::SubscribeOptions options; + auto status = mHardware->subscribe(options); + + EXPECT_EQ(status, aidlvhal::StatusCode::NOT_AVAILABLE_SPEED_LOW); +} + } // namespace android::hardware::automotive::vehicle::virtualization diff --git a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp index 49e6fc9d21..61dabb9ed2 100644 --- a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp +++ b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp @@ -30,6 +30,13 @@ namespace android::hardware::automotive::vehicle::virtualization { +namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle; + +using ::testing::_; +using ::testing::DoAll; +using ::testing::Return; +using ::testing::SaveArg; + const std::string kFakeServerAddr = "0.0.0.0:54321"; class VehicleHardwareForTest : public IVehicleHardware { @@ -39,38 +46,30 @@ class VehicleHardwareForTest : public IVehicleHardware { mOnProp = std::move(callback); } - void onPropertyEvent( - std::vector values) { + void onPropertyEvent(std::vector values) { if (mOnProp) { (*mOnProp)(std::move(values)); } } // Functions that we do not care. - std::vector - getAllPropertyConfigs() const override { - return {}; - } + std::vector getAllPropertyConfigs() const override { return {}; } - aidl::android::hardware::automotive::vehicle::StatusCode setValues( + aidlvhal::StatusCode setValues( std::shared_ptr callback, - const std::vector& - requests) override { - return aidl::android::hardware::automotive::vehicle::StatusCode::OK; + const std::vector& requests) override { + return aidlvhal::StatusCode::OK; } - aidl::android::hardware::automotive::vehicle::StatusCode getValues( + aidlvhal::StatusCode getValues( std::shared_ptr callback, - const std::vector& - requests) const override { - return aidl::android::hardware::automotive::vehicle::StatusCode::OK; + const std::vector& requests) const override { + return aidlvhal::StatusCode::OK; } DumpResult dump(const std::vector& options) override { return {}; } - aidl::android::hardware::automotive::vehicle::StatusCode checkHealth() override { - return aidl::android::hardware::automotive::vehicle::StatusCode::OK; - } + aidlvhal::StatusCode checkHealth() override { return aidlvhal::StatusCode::OK; } void registerOnPropertySetErrorEvent( std::unique_ptr callback) override {} @@ -79,6 +78,35 @@ class VehicleHardwareForTest : public IVehicleHardware { std::unique_ptr mOnProp; }; +class MockVehicleHardware : public IVehicleHardware { + public: + // Mock methods from IVehicleHardware + MOCK_METHOD(std::vector, getAllPropertyConfigs, (), + (const, override)); + + MOCK_METHOD((aidlvhal::StatusCode), setValues, + (std::shared_ptr callback, + const std::vector& requests), + (override)); + + MOCK_METHOD((aidlvhal::StatusCode), getValues, + (std::shared_ptr callback, + const std::vector& requests), + (const, override)); + + MOCK_METHOD(DumpResult, dump, (const std::vector& options), (override)); + MOCK_METHOD(aidlvhal::StatusCode, checkHealth, (), (override)); + MOCK_METHOD(void, registerOnPropertyChangeEvent, + (std::unique_ptr callback), (override)); + MOCK_METHOD(void, registerOnPropertySetErrorEvent, + (std::unique_ptr callback), (override)); + MOCK_METHOD(std::chrono::nanoseconds, getPropertyOnChangeEventBatchingWindow, (), (override)); + MOCK_METHOD(aidlvhal::StatusCode, subscribe, (aidlvhal::SubscribeOptions options), (override)); + MOCK_METHOD(aidlvhal::StatusCode, unsubscribe, (int32_t propId, int32_t areaId), (override)); + MOCK_METHOD(aidlvhal::StatusCode, updateSampleRate, + (int32_t propId, int32_t areaId, float sampleRate), (override)); +}; + TEST(GRPCVehicleProxyServerUnitTest, ClientConnectDisconnect) { auto testHardware = std::make_unique(); // HACK: manipulate the underlying hardware via raw pointer for testing. @@ -144,4 +172,51 @@ TEST(GRPCVehicleProxyServerUnitTest, ClientConnectDisconnect) { vehicleServer->Shutdown().Wait(); } +TEST(GRPCVehicleProxyServerUnitTest, Subscribe) { + auto mockHardware = std::make_unique(); + // We make sure this is alive inside the function scope. + MockVehicleHardware* mockHardwarePtr = mockHardware.get(); + GrpcVehicleProxyServer server = GrpcVehicleProxyServer("", std::move(mockHardware)); + ::grpc::ServerContext context; + proto::SubscribeRequest request; + proto::VehicleHalCallStatus returnStatus; + aidlvhal::SubscribeOptions aidlOptions; + request.mutable_options()->set_prop_id(1); + request.mutable_options()->add_area_ids(2); + request.mutable_options()->set_sample_rate(1.234); + request.mutable_options()->set_resolution(0.01); + request.mutable_options()->set_enable_variable_update_rate(true); + + EXPECT_CALL(*mockHardwarePtr, subscribe(_)) + .WillOnce(DoAll(SaveArg<0>(&aidlOptions), Return(aidlvhal::StatusCode::OK))); + + auto grpcStatus = server.Subscribe(&context, &request, &returnStatus); + + EXPECT_TRUE(grpcStatus.ok()); + EXPECT_EQ(returnStatus.status_code(), proto::StatusCode::OK); + EXPECT_EQ(aidlOptions.propId, 1); + EXPECT_EQ(aidlOptions.areaIds, std::vector{2}); + EXPECT_FLOAT_EQ(aidlOptions.sampleRate, 1.234); + EXPECT_FLOAT_EQ(aidlOptions.resolution, 0.01); + EXPECT_TRUE(aidlOptions.enableVariableUpdateRate); +} + +TEST(GRPCVehicleProxyServerUnitTest, SubscribeNotAvailable) { + auto mockHardware = std::make_unique(); + // We make sure this is alive inside the function scope. + MockVehicleHardware* mockHardwarePtr = mockHardware.get(); + GrpcVehicleProxyServer server = GrpcVehicleProxyServer("", std::move(mockHardware)); + ::grpc::ServerContext context; + proto::SubscribeRequest request; + proto::VehicleHalCallStatus returnStatus; + + EXPECT_CALL(*mockHardwarePtr, subscribe(_)) + .WillOnce(Return(aidlvhal::StatusCode::NOT_AVAILABLE)); + + auto grpcStatus = server.Subscribe(&context, &request, &returnStatus); + + EXPECT_TRUE(grpcStatus.ok()); + EXPECT_EQ(returnStatus.status_code(), proto::StatusCode::NOT_AVAILABLE); +} + } // namespace android::hardware::automotive::vehicle::virtualization diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp index d10aa3e67f..94c09aa149 100644 --- a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp +++ b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp @@ -42,23 +42,21 @@ cc_library { host_supported: true, } -cc_test { +cc_test_host { name: "VehicleHalProtoMessageConverterTest", srcs: [ "test/*.cpp", ], vendor: true, defaults: ["VehicleHalDefaults"], - shared_libs: [ - "libprotobuf-cpp-full", - "libjsoncpp", - ], static_libs: [ "VehicleHalJsonConfigLoaderEnableTestProperties", "VehicleHalProtoMessageConverter", "VehicleHalProtos", "VehicleHalUtils", "libgtest", + "libprotobuf-cpp-full", + "libjsoncpp", ], data: [ ":VehicleHalDefaultProperties_JSON", diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h index 1c26fe868b..25c07ef2ca 100644 --- a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h +++ b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h @@ -18,6 +18,7 @@ #define android_hardware_automotive_vehicle_aidl_impl_grpc_utils_proto_message_converter_include_ProtoMessageConverter_H_ #include +#include #include #include #include @@ -46,6 +47,12 @@ void aidlToProto(const ::aidl::android::hardware::automotive::vehicle::VehiclePr void protoToAidl( const ::android::hardware::automotive::vehicle::proto::VehiclePropValue& inProtoVal, ::aidl::android::hardware::automotive::vehicle::VehiclePropValue* outAidlVal); +// Convert AIDL SubscribeOptions to Protobuf SubscribeOptions. +void aidlToProto(const ::aidl::android::hardware::automotive::vehicle::SubscribeOptions& in, + ::android::hardware::automotive::vehicle::proto::SubscribeOptions* out); +// Convert Protobuf SubscribeOptions to AIDL SubscribeOptions. +void protoToAidl(const ::android::hardware::automotive::vehicle::proto::SubscribeOptions& in, + ::aidl::android::hardware::automotive::vehicle::SubscribeOptions* out); } // namespace proto_msg_converter } // namespace vehicle diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp index 1ea0df4716..c40004a096 100644 --- a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp +++ b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp @@ -152,6 +152,24 @@ void protoToAidl(const proto::VehiclePropValue& in, aidl_vehicle::VehiclePropVal COPY_PROTOBUF_VEC_TO_VHAL_TYPE(in, float_values, out, value.floatValues); } +void aidlToProto(const aidl_vehicle::SubscribeOptions& in, proto::SubscribeOptions* out) { + out->set_prop_id(in.propId); + for (int areaId : in.areaIds) { + out->add_area_ids(areaId); + } + out->set_sample_rate(in.sampleRate); + out->set_resolution(in.resolution); + out->set_enable_variable_update_rate(in.enableVariableUpdateRate); +} + +void protoToAidl(const proto::SubscribeOptions& in, aidl_vehicle::SubscribeOptions* out) { + out->propId = in.prop_id(); + COPY_PROTOBUF_VEC_TO_VHAL_TYPE(in, area_ids, out, areaIds); + out->sampleRate = in.sample_rate(); + out->resolution = in.resolution(); + out->enableVariableUpdateRate = in.enable_variable_update_rate(); +} + #undef COPY_PROTOBUF_VEC_TO_VHAL_TYPE #undef CAST_COPY_PROTOBUF_VEC_TO_VHAL_TYPE diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp index 308be4601a..2efda5b69a 100644 --- a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp +++ b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -114,6 +115,21 @@ INSTANTIATE_TEST_SUITE_P(TestValues, PropValueConversionTest, return ::fmt::format("property_{:d}", info.param.prop); }); +TEST_F(PropValueConversionTest, testConvertSubscribeOption) { + proto::SubscribeOptions protoOptions; + aidl_vehicle::SubscribeOptions aidlOptions = {.propId = 1, + .areaIds = {1, 2}, + .sampleRate = 1.234, + .resolution = 0.01, + .enableVariableUpdateRate = true}; + aidl_vehicle::SubscribeOptions outputOptions; + + aidlToProto(aidlOptions, &protoOptions); + protoToAidl(protoOptions, &outputOptions); + + EXPECT_EQ(aidlOptions, outputOptions); +} + } // namespace proto_msg_converter } // namespace vehicle } // namespace automotive diff --git a/automotive/vehicle/aidl/impl/proto/Android.bp b/automotive/vehicle/aidl/impl/proto/Android.bp index 56fad7ed91..c636bb98d8 100644 --- a/automotive/vehicle/aidl/impl/proto/Android.bp +++ b/automotive/vehicle/aidl/impl/proto/Android.bp @@ -50,6 +50,8 @@ genrule { "android/hardware/automotive/vehicle/VehiclePropertyStatus.pb.h", "android/hardware/automotive/vehicle/VehiclePropValue.pb.h", "android/hardware/automotive/vehicle/VehiclePropValueRequest.pb.h", + "android/hardware/automotive/vehicle/SubscribeOptions.pb.h", + "android/hardware/automotive/vehicle/SubscribeRequest.pb.h", ], } @@ -74,6 +76,8 @@ genrule { "android/hardware/automotive/vehicle/VehiclePropertyStatus.pb.cc", "android/hardware/automotive/vehicle/VehiclePropValue.pb.cc", "android/hardware/automotive/vehicle/VehiclePropValueRequest.pb.cc", + "android/hardware/automotive/vehicle/SubscribeOptions.pb.cc", + "android/hardware/automotive/vehicle/SubscribeRequest.pb.cc", ], } diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeOptions.proto b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeOptions.proto new file mode 100644 index 0000000000..3fc6581fcb --- /dev/null +++ b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeOptions.proto @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 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. + */ + +syntax = "proto3"; + +package android.hardware.automotive.vehicle.proto; + +message SubscribeOptions { + int32 prop_id = 1; + repeated int32 area_ids = 2; + float sample_rate = 3; + float resolution = 4; + bool enable_variable_update_rate = 5; +} \ No newline at end of file diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeRequest.proto b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeRequest.proto new file mode 100644 index 0000000000..4ce63359e7 --- /dev/null +++ b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeRequest.proto @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2024 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. + */ + +syntax = "proto3"; + +package android.hardware.automotive.vehicle.proto; + +import "android/hardware/automotive/vehicle/SubscribeOptions.proto"; + +message SubscribeRequest { + SubscribeOptions options = 1; +} \ No newline at end of file