diff --git a/automotive/remoteaccess/hal/default/Android.bp b/automotive/remoteaccess/hal/default/Android.bp index 250207983a..51be330331 100644 --- a/automotive/remoteaccess/hal/default/Android.bp +++ b/automotive/remoteaccess/hal/default/Android.bp @@ -36,6 +36,9 @@ cc_binary { "libgrpc++", "libprotobuf-cpp-full", ], + defaults: [ + "vhalclient_defaults", + ], cflags: [ "-Wno-unused-parameter", "-DGRPC_SERVICE_ADDRESS=\"localhost:50051\"", @@ -53,6 +56,10 @@ cc_library { whole_static_libs: [ "android.hardware.automotive.remoteaccess-V1-ndk", "wakeup_client_protos", + "libvhalclient", + ], + defaults: [ + "vhalclient_defaults", ], shared_libs: [ "libbase", diff --git a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h index 207c09369f..74c2af4c9f 100644 --- a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h +++ b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h @@ -16,6 +16,7 @@ #pragma once +#include #include #include #include @@ -102,6 +103,8 @@ class RemoteAccessService void runTaskLoop(); void maybeStartTaskLoop(); void maybeStopTaskLoop(); + ndk::ScopedAStatus getDeviceIdWithClient( + android::frameworks::automotive::vhal::IVhalClient& client, std::string* deviceId); void setRetryWaitInMs(size_t retryWaitInMs) { mRetryWaitInMs = retryWaitInMs; } void dumpHelp(int fd); diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp index cc8b50cb67..72f37d78b2 100644 --- a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp +++ b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp @@ -16,6 +16,8 @@ #include "RemoteAccessService.h" +#include +#include #include #include #include @@ -33,9 +35,12 @@ namespace { using ::aidl::android::hardware::automotive::remoteaccess::ApState; using ::aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback; +using ::aidl::android::hardware::automotive::vehicle::VehicleProperty; using ::android::base::ScopedLockAssertion; using ::android::base::StringAppendF; using ::android::base::StringPrintf; +using ::android::frameworks::automotive::vhal::IVhalClient; +using ::android::hardware::automotive::vehicle::toInt; using ::grpc::ClientContext; using ::grpc::ClientReaderInterface; using ::grpc::Status; @@ -47,6 +52,7 @@ constexpr char COMMAND_SET_AP_STATE[] = "--set-ap-state"; constexpr char COMMAND_START_DEBUG_CALLBACK[] = "--start-debug-callback"; constexpr char COMMAND_STOP_DEBUG_CALLBACK[] = "--stop-debug-callback"; constexpr char COMMAND_SHOW_TASK[] = "--show-task"; +constexpr char COMMAND_GET_DEVICE_ID[] = "--get-device-id"; std::vector stringToBytes(const std::string& s) { const char* data = s.data(); @@ -70,6 +76,10 @@ bool checkBoolFlag(const char* flag) { return !strcmp(flag, "1") || !strcmp(flag, "0"); } +void dprintErrorStatus(int fd, const char* detail, const ScopedAStatus& status) { + dprintf(fd, "%s, code: %d, error: %s\n", detail, status.getStatus(), status.getMessage()); +} + } // namespace RemoteAccessService::RemoteAccessService(WakeupClient::StubInterface* grpcStub) @@ -164,7 +174,25 @@ void RemoteAccessService::runTaskLoop() { } ScopedAStatus RemoteAccessService::getDeviceId(std::string* deviceId) { - // TODO(b/241483300): Call VHAL to get VIN. + auto vhalClient = IVhalClient::tryCreate(); + if (vhalClient == nullptr) { + ALOGE("Failed to connect to VHAL"); + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + /*errorCode=*/0, "Failed to connect to VHAL to get device ID"); + } + return getDeviceIdWithClient(*vhalClient.get(), deviceId); +} + +ScopedAStatus RemoteAccessService::getDeviceIdWithClient(IVhalClient& vhalClient, + std::string* deviceId) { + auto result = vhalClient.getValueSync( + *vhalClient.createHalPropValue(toInt(VehicleProperty::INFO_VIN))); + if (!result.ok()) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + /*errorCode=*/0, + ("failed to get INFO_VIN from VHAL: " + result.error().message()).c_str()); + } + *deviceId = (*result)->getStringValue(); return ScopedAStatus::ok(); } @@ -216,7 +244,8 @@ void RemoteAccessService::dumpHelp(int fd) { COMMAND_START_DEBUG_CALLBACK + " Start a debug callback that will record the received tasks\n" + COMMAND_STOP_DEBUG_CALLBACK + " Stop the debug callback\n" + COMMAND_SHOW_TASK + - " Show tasks received by debug callback\n") + " Show tasks received by debug callback\n" + COMMAND_GET_DEVICE_ID + + " Get device id\n") .c_str()); } @@ -258,8 +287,7 @@ binder_status_t RemoteAccessService::dump(int fd, const char** args, uint32_t nu } auto status = notifyApStateChange(apState); if (!status.isOk()) { - dprintf(fd, "Failed to set AP state, code: %d, error: %s\n", status.getStatus(), - status.getMessage()); + dprintErrorStatus(fd, "Failed to set AP state", status); } else { dprintf(fd, "successfully set the new AP state\n"); } @@ -280,6 +308,14 @@ binder_status_t RemoteAccessService::dump(int fd, const char** args, uint32_t nu dprintf(fd, "Debug callback is not currently used, use \"%s\" first.\n", COMMAND_START_DEBUG_CALLBACK); } + } else if (!strcmp(args[0], COMMAND_GET_DEVICE_ID)) { + std::string deviceId; + auto status = getDeviceId(&deviceId); + if (!status.isOk()) { + dprintErrorStatus(fd, "Failed to get device ID", status); + } else { + dprintf(fd, "Device Id: %s\n", deviceId.c_str()); + } } else { dumpHelp(fd); } diff --git a/automotive/remoteaccess/hal/default/test/Android.bp b/automotive/remoteaccess/hal/default/test/Android.bp index bf7d0b6b43..227175a611 100644 --- a/automotive/remoteaccess/hal/default/test/Android.bp +++ b/automotive/remoteaccess/hal/default/test/Android.bp @@ -37,6 +37,9 @@ cc_test { "libgtest", "libgmock", ], + defaults: [ + "vhalclient_defaults", + ], cflags: [ "-Wno-unused-parameter", ], diff --git a/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp b/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp index 11523f69db..8c4fa080eb 100644 --- a/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp +++ b/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp @@ -16,8 +16,11 @@ #include "RemoteAccessService.h" +#include +#include #include #include +#include #include #include #include @@ -30,10 +33,20 @@ namespace hardware { namespace automotive { namespace remoteaccess { +namespace { + using ::android::base::ScopedLockAssertion; +using ::android::frameworks::automotive::vhal::AidlHalPropValue; +using ::android::frameworks::automotive::vhal::IHalPropConfig; +using ::android::frameworks::automotive::vhal::IHalPropValue; +using ::android::frameworks::automotive::vhal::ISubscriptionCallback; +using ::android::frameworks::automotive::vhal::ISubscriptionClient; +using ::android::frameworks::automotive::vhal::IVhalClient; +using ::android::frameworks::automotive::vhal::VhalClientResult; using ::aidl::android::hardware::automotive::remoteaccess::ApState; using ::aidl::android::hardware::automotive::remoteaccess::BnRemoteTaskCallback; +using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue; using ::grpc::ClientAsyncReaderInterface; using ::grpc::ClientAsyncResponseReaderInterface; @@ -49,6 +62,10 @@ using ::testing::DoAll; using ::testing::Return; using ::testing::SetArgPointee; +constexpr char kTestVin[] = "test_VIN"; + +} // namespace + class MockGrpcClientStub : public WakeupClient::StubInterface { public: MOCK_METHOD(ClientReaderInterface*, GetRemoteTasksRaw, @@ -73,6 +90,62 @@ class MockGrpcClientStub : public WakeupClient::StubInterface { CompletionQueue* cq)); }; +class FakeVhalClient final : public android::frameworks::automotive::vhal::IVhalClient { + public: + inline bool isAidlVhal() { return true; } + + VhalClientResult> getValueSync( + const IHalPropValue& requestValue) override { + auto propValue = std::make_unique(requestValue.getPropId()); + propValue->setStringValue(kTestVin); + return propValue; + } + + std::unique_ptr createHalPropValue(int32_t propId) override { + return std::make_unique(propId); + } + + // Functions we do not care. + std::unique_ptr createHalPropValue([[maybe_unused]] int32_t propId, + [[maybe_unused]] int32_t areaId) override { + return nullptr; + } + + void getValue([[maybe_unused]] const IHalPropValue& requestValue, + [[maybe_unused]] std::shared_ptr callback) override {} + + void setValue([[maybe_unused]] const IHalPropValue& requestValue, + [[maybe_unused]] std::shared_ptr callback) override {} + + VhalClientResult setValueSync([[maybe_unused]] const IHalPropValue& requestValue) { + return {}; + } + + VhalClientResult addOnBinderDiedCallback( + [[maybe_unused]] std::shared_ptr callback) override { + return {}; + } + + VhalClientResult removeOnBinderDiedCallback( + [[maybe_unused]] std::shared_ptr callback) override { + return {}; + } + + VhalClientResult>> getAllPropConfigs() override { + return std::vector>(); + } + + VhalClientResult>> getPropConfigs( + [[maybe_unused]] std::vector propIds) override { + return std::vector>(); + } + + std::unique_ptr getSubscriptionClient( + [[maybe_unused]] std::shared_ptr callback) override { + return nullptr; + } +}; + class FakeRemoteTaskCallback : public BnRemoteTaskCallback { public: ScopedAStatus onRemoteTaskRequested(const std::string& clientId, @@ -114,10 +187,13 @@ class RemoteAccessServiceUnitTest : public ::testing::Test { void setRetryWaitInMs(size_t retryWaitInMs) { mService->setRetryWaitInMs(retryWaitInMs); } + ScopedAStatus getDeviceIdWithClient(IVhalClient& vhalClient, std::string* deviceId) { + return mService->getDeviceIdWithClient(vhalClient, deviceId); + } + private: std::unique_ptr mGrpcWakeupClientStub; std::shared_ptr mService; - MockClientReader* mMockTaskReader; }; TEST_F(RemoteAccessServiceUnitTest, TestGetWakeupServiceName) { @@ -282,6 +358,15 @@ TEST_F(RemoteAccessServiceUnitTest, TestGetRemoteTasksNotReadyAfterReady) { std::this_thread::sleep_for(std::chrono::milliseconds(150)); } +TEST_F(RemoteAccessServiceUnitTest, testGetDeviceId) { + std::string deviceId; + + FakeVhalClient vhalClient; + + ASSERT_TRUE(getDeviceIdWithClient(vhalClient, &deviceId).isOk()); + ASSERT_EQ(deviceId, kTestVin); +} + } // namespace remoteaccess } // namespace automotive } // namespace hardware