Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc2ed2a3 authored by Yu Shan's avatar Yu Shan
Browse files

Talk with VHAL to get device ID.

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

Change-Id: I884cb75a493550afe4b1b412e6cc95ebe61b8cd3
parent dc54b8c2
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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",
+3 −0
Original line number Diff line number Diff line
@@ -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);
+40 −4
Original line number Diff line number Diff line
@@ -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);
    }
+3 −0
Original line number Diff line number Diff line
@@ -37,6 +37,9 @@ cc_test {
        "libgtest",
        "libgmock",
    ],
    defaults: [
        "vhalclient_defaults",
    ],
    cflags: [
        "-Wno-unused-parameter",
    ],
+86 −1
Original line number Diff line number Diff line
@@ -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