Talk with VHAL to get device ID.

Test: In adb root shell:
dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default
Bug: 241483300

Change-Id: I884cb75a493550afe4b1b412e6cc95ebe61b8cd3
This commit is contained in:
Yu Shan
2022-09-15 19:01:52 -07:00
parent dc54b8c24e
commit bc2ed2a3c7
5 changed files with 139 additions and 5 deletions

View File

@@ -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",

View File

@@ -16,6 +16,7 @@
#pragma once
#include <IVhalClient.h>
#include <aidl/android/hardware/automotive/remoteaccess/ApState.h>
#include <aidl/android/hardware/automotive/remoteaccess/BnRemoteAccess.h>
#include <aidl/android/hardware/automotive/remoteaccess/BnRemoteTaskCallback.h>
@@ -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);

View File

@@ -16,6 +16,8 @@
#include "RemoteAccessService.h"
#include <VehicleUtils.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
#include <android-base/stringprintf.h>
#include <android/binder_status.h>
#include <grpc++/grpc++.h>
@@ -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<uint8_t> 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);
}

View File

@@ -37,6 +37,9 @@ cc_test {
"libgtest",
"libgmock",
],
defaults: [
"vhalclient_defaults",
],
cflags: [
"-Wno-unused-parameter",
],

View File

@@ -16,8 +16,11 @@
#include "RemoteAccessService.h"
#include <AidlHalPropValue.h>
#include <IVhalClient.h>
#include <aidl/android/hardware/automotive/remoteaccess/ApState.h>
#include <aidl/android/hardware/automotive/remoteaccess/BnRemoteTaskCallback.h>
#include <aidl/android/hardware/automotive/vehicle/VehiclePropValue.h>
#include <gmock/gmock.h>
#include <grpcpp/test/mock_stream.h>
#include <gtest/gtest.h>
@@ -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<GetRemoteTasksResponse>*, 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<std::unique_ptr<IHalPropValue>> getValueSync(
const IHalPropValue& requestValue) override {
auto propValue = std::make_unique<AidlHalPropValue>(requestValue.getPropId());
propValue->setStringValue(kTestVin);
return propValue;
}
std::unique_ptr<IHalPropValue> createHalPropValue(int32_t propId) override {
return std::make_unique<AidlHalPropValue>(propId);
}
// Functions we do not care.
std::unique_ptr<IHalPropValue> 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<GetValueCallbackFunc> callback) override {}
void setValue([[maybe_unused]] const IHalPropValue& requestValue,
[[maybe_unused]] std::shared_ptr<SetValueCallbackFunc> callback) override {}
VhalClientResult<void> setValueSync([[maybe_unused]] const IHalPropValue& requestValue) {
return {};
}
VhalClientResult<void> addOnBinderDiedCallback(
[[maybe_unused]] std::shared_ptr<OnBinderDiedCallbackFunc> callback) override {
return {};
}
VhalClientResult<void> removeOnBinderDiedCallback(
[[maybe_unused]] std::shared_ptr<OnBinderDiedCallbackFunc> callback) override {
return {};
}
VhalClientResult<std::vector<std::unique_ptr<IHalPropConfig>>> getAllPropConfigs() override {
return std::vector<std::unique_ptr<IHalPropConfig>>();
}
VhalClientResult<std::vector<std::unique_ptr<IHalPropConfig>>> getPropConfigs(
[[maybe_unused]] std::vector<int32_t> propIds) override {
return std::vector<std::unique_ptr<IHalPropConfig>>();
}
std::unique_ptr<ISubscriptionClient> getSubscriptionClient(
[[maybe_unused]] std::shared_ptr<ISubscriptionCallback> 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<MockGrpcClientStub> mGrpcWakeupClientStub;
std::shared_ptr<RemoteAccessService> mService;
MockClientReader<GetRemoteTasksResponse>* 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