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

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

Implement supported values API in GRPC VHAL client/server.

Define new protobuf interface for GRPC VHAL. Implement the GRPC
VHAL client/server.

Test: Manual test on cf.
atest GRPCVehicleHardwareUnitTest GRPCVehicleProxyServerUnitTest
Flag: EXEMPT HAL
Bug: 393154530

Change-Id: I9252d6f42a5f43f1829f431887126142d69102f9
parent 3c0407a2
Loading
Loading
Loading
Loading
+90 −12
Original line number Diff line number Diff line
@@ -29,19 +29,45 @@

namespace android::hardware::automotive::vehicle::virtualization {

using ::grpc::ChannelCredentials;
using ::grpc::ClientContext;
using ::grpc::CreateChannel;
using ::grpc::InsecureChannelCredentials;
using ::grpc::Status;

namespace {

constexpr size_t MAX_RETRY_COUNT = 5;

std::shared_ptr<::grpc::ChannelCredentials> getChannelCredentials() {
    return ::grpc::InsecureChannelCredentials();
std::shared_ptr<ChannelCredentials> getChannelCredentials() {
    return InsecureChannelCredentials();
}

template <class ProtoRequestType>
void fillPropIdAreaIdsToProtoRequest(const std::vector<PropIdAreaId>& propIdAreaIds,
                                     ProtoRequestType* protoRequest) {
    for (const auto& propIdAreaId : propIdAreaIds) {
        proto_msg_converter::aidlToProto(propIdAreaId, protoRequest->add_prop_id_area_id());
    }
}

template <class AidlResultType, class ProtoResultType>
std::vector<AidlResultType> convertSupportedValueProtoResultToAidlResults(
        const std::vector<PropIdAreaId>& propIdAreaIds, const ProtoResultType& protoResult) {
    std::vector<AidlResultType> aidlResults;
    for (const auto& protoResultPerRequest : protoResult.result()) {
        AidlResultType aidlResult = {};
        proto_msg_converter::protoToAidl(protoResultPerRequest, &aidlResult);
        aidlResults.push_back(std::move(aidlResult));
    }
    return aidlResults;
}

}  // namespace

GRPCVehicleHardware::GRPCVehicleHardware(std::string service_addr)
    : mServiceAddr(std::move(service_addr)),
      mGrpcChannel(::grpc::CreateChannel(mServiceAddr, getChannelCredentials())),
      mGrpcChannel(CreateChannel(mServiceAddr, getChannelCredentials())),
      mGrpcStub(proto::VehicleServer::NewStub(mGrpcChannel)),
      mValuePollingThread([this] { ValuePollingLoop(); }) {}

@@ -67,7 +93,7 @@ GRPCVehicleHardware::~GRPCVehicleHardware() {

std::vector<aidlvhal::VehiclePropConfig> GRPCVehicleHardware::getAllPropertyConfigs() const {
    std::vector<aidlvhal::VehiclePropConfig> configs;
    ::grpc::ClientContext context;
    ClientContext context;
    auto config_stream = mGrpcStub->GetAllPropertyConfig(&context, ::google::protobuf::Empty());
    proto::VehiclePropConfig protoConfig;
    while (config_stream->Read(&protoConfig)) {
@@ -97,7 +123,7 @@ std::optional<aidlvhal::VehiclePropConfig> GRPCVehicleHardware::getPropertyConfi
aidlvhal::StatusCode GRPCVehicleHardware::setValues(
        std::shared_ptr<const SetValuesCallback> callback,
        const std::vector<aidlvhal::SetValueRequest>& requests) {
    ::grpc::ClientContext context;
    ClientContext context;
    proto::VehiclePropValueRequests protoRequests;
    proto::SetValueResults protoResults;
    for (const auto& request : requests) {
@@ -160,7 +186,7 @@ aidlvhal::StatusCode GRPCVehicleHardware::getValuesWithRetry(
    }

    // TODO(chenhaosjtuacm): Make it Async.
    ::grpc::ClientContext context;
    ClientContext context;
    proto::GetValueResults protoResults;
    auto grpc_status = mGrpcStub->GetValues(&context, protoRequests, &protoResults);
    if (!grpc_status.ok()) {
@@ -262,7 +288,7 @@ void GRPCVehicleHardware::registerOnPropertySetErrorEvent(
}

DumpResult GRPCVehicleHardware::dump(const std::vector<std::string>& options) {
    ::grpc::ClientContext context;
    ClientContext context;
    proto::DumpOptions protoDumpOptions;
    proto::DumpResult protoDumpResult;
    for (const auto& option : options) {
@@ -281,7 +307,7 @@ DumpResult GRPCVehicleHardware::dump(const std::vector<std::string>& options) {
}

aidlvhal::StatusCode GRPCVehicleHardware::checkHealth() {
    ::grpc::ClientContext context;
    ClientContext context;
    proto::VehicleHalCallStatus protoStatus;
    auto grpc_status = mGrpcStub->CheckHealth(&context, ::google::protobuf::Empty(), &protoStatus);
    if (!grpc_status.ok()) {
@@ -293,7 +319,7 @@ aidlvhal::StatusCode GRPCVehicleHardware::checkHealth() {

aidlvhal::StatusCode GRPCVehicleHardware::subscribe(aidlvhal::SubscribeOptions options) {
    proto::SubscribeRequest request;
    ::grpc::ClientContext context;
    ClientContext context;
    proto::VehicleHalCallStatus protoStatus;
    proto_msg_converter::aidlToProto(options, request.mutable_options());
    auto grpc_status = mGrpcStub->Subscribe(&context, request, &protoStatus);
@@ -311,7 +337,7 @@ aidlvhal::StatusCode GRPCVehicleHardware::subscribe(aidlvhal::SubscribeOptions o

aidlvhal::StatusCode GRPCVehicleHardware::unsubscribe(int32_t propId, int32_t areaId) {
    proto::UnsubscribeRequest request;
    ::grpc::ClientContext context;
    ClientContext context;
    proto::VehicleHalCallStatus protoStatus;
    request.set_prop_id(propId);
    request.set_area_id(areaId);
@@ -330,7 +356,7 @@ aidlvhal::StatusCode GRPCVehicleHardware::unsubscribe(int32_t propId, int32_t ar

aidlvhal::StatusCode GRPCVehicleHardware::updateSampleRate(int32_t propId, int32_t areaId,
                                                           float sampleRate) {
    ::grpc::ClientContext context;
    ClientContext context;
    proto::UpdateSampleRateRequest request;
    proto::VehicleHalCallStatus protoStatus;
    request.set_prop(propId);
@@ -357,7 +383,7 @@ void GRPCVehicleHardware::ValuePollingLoop() {
}

void GRPCVehicleHardware::pollValue() {
    ::grpc::ClientContext context;
    ClientContext context;

    bool rpc_stopped{false};
    std::thread shuttingdown_watcher([this, &rpc_stopped, &context]() {
@@ -408,4 +434,56 @@ void GRPCVehicleHardware::pollValue() {
    LOG(ERROR) << __func__ << ": GRPC Value Streaming Failed: " << grpc_status.error_message();
}

std::vector<aidlvhal::MinMaxSupportedValueResult> GRPCVehicleHardware::getMinMaxSupportedValues(
        const std::vector<PropIdAreaId>& propIdAreaIds) {
    ClientContext context;
    proto::GetMinMaxSupportedValuesRequest protoRequest = {};
    proto::GetMinMaxSupportedValuesResult protoResult = {};
    fillPropIdAreaIdsToProtoRequest(propIdAreaIds, &protoRequest);

    auto grpc_status = mGrpcStub->GetMinMaxSupportedValues(&context, protoRequest, &protoResult);
    std::vector<aidlvhal::MinMaxSupportedValueResult> aidlResults;
    if (!grpc_status.ok()) {
        LOG(ERROR) << __func__
                   << ": GRPC GetMinMaxSupportedValues Failed: " << grpc_status.error_message();
        for (const auto& propIdAreaId : propIdAreaIds) {
            aidlResults.push_back({
                    .status = aidlvhal::StatusCode::INTERNAL_ERROR,
            });
        }
        return aidlResults;
    }
    aidlResults =
            convertSupportedValueProtoResultToAidlResults<aidlvhal::MinMaxSupportedValueResult,
                                                          proto::GetMinMaxSupportedValuesResult>(
                    propIdAreaIds, protoResult);
    return aidlResults;
}

std::vector<aidlvhal::SupportedValuesListResult> GRPCVehicleHardware::getSupportedValuesLists(
        const std::vector<PropIdAreaId>& propIdAreaIds) {
    ClientContext context;
    proto::GetSupportedValuesListsRequest protoRequest = {};
    proto::GetSupportedValuesListsResult protoResult = {};
    fillPropIdAreaIdsToProtoRequest(propIdAreaIds, &protoRequest);

    auto grpc_status = mGrpcStub->GetSupportedValuesLists(&context, protoRequest, &protoResult);
    std::vector<aidlvhal::SupportedValuesListResult> aidlResults;
    if (!grpc_status.ok()) {
        LOG(ERROR) << __func__
                   << ": GRPC GetSupportedValuesLists Failed: " << grpc_status.error_message();
        for (const auto& propIdAreaId : propIdAreaIds) {
            aidlResults.push_back({
                    .status = aidlvhal::StatusCode::INTERNAL_ERROR,
            });
        }
        return aidlResults;
    }
    aidlResults =
            convertSupportedValueProtoResultToAidlResults<aidlvhal::SupportedValuesListResult,
                                                          proto::GetSupportedValuesListsResult>(
                    propIdAreaIds, protoResult);
    return aidlResults;
}

}  // namespace android::hardware::automotive::vehicle::virtualization
+6 −0
Original line number Diff line number Diff line
@@ -90,6 +90,12 @@ class GRPCVehicleHardware : public IVehicleHardware {

    aidlvhal::StatusCode unsubscribe(int32_t propId, int32_t areaId) override;

    std::vector<aidlvhal::MinMaxSupportedValueResult> getMinMaxSupportedValues(
            const std::vector<PropIdAreaId>& propIdAreaIds) override;

    std::vector<aidlvhal::SupportedValuesListResult> getSupportedValuesLists(
            const std::vector<PropIdAreaId>& propIdAreaIds) override;

    bool waitForConnected(std::chrono::milliseconds waitTime);

  protected:
+44 −4
Original line number Diff line number Diff line
@@ -31,13 +31,33 @@

namespace android::hardware::automotive::vehicle::virtualization {

std::atomic<uint64_t> GrpcVehicleProxyServer::ConnectionDescriptor::connection_id_counter_{0};

static std::shared_ptr<::grpc::ServerCredentials> getServerCredentials() {
    // TODO(chenhaosjtuacm): get secured credentials here
namespace {
std::shared_ptr<::grpc::ServerCredentials> getServerCredentials() {
    return ::grpc::InsecureServerCredentials();
}

template <class ProtoRequestType>
std::vector<PropIdAreaId> getPropIdAreaIdsFromProtoRequest(const ProtoRequestType* request) {
    std::vector<PropIdAreaId> propIdAreaIds;
    for (const proto::PropIdAreaId& protoPropIdAreaId : request->prop_id_area_id()) {
        PropIdAreaId aidlPropIdAreaId = {};
        proto_msg_converter::protoToAidl(protoPropIdAreaId, &aidlPropIdAreaId);
        propIdAreaIds.push_back(aidlPropIdAreaId);
    }
    return propIdAreaIds;
}

template <class AidlResultType, class ProtoResultType>
void aidlResultsToProtoResults(const AidlResultType& aidlResults, ProtoResultType* result) {
    for (const auto& aidlResult : aidlResults) {
        auto* protoResult = result->add_result();
        proto_msg_converter::aidlToProto(aidlResult, protoResult);
    }
}
}  // namespace

std::atomic<uint64_t> GrpcVehicleProxyServer::ConnectionDescriptor::connection_id_counter_{0};

GrpcVehicleProxyServer::GrpcVehicleProxyServer(std::string serverAddr,
                                               std::unique_ptr<IVehicleHardware>&& hardware)
    : GrpcVehicleProxyServer(std::vector<std::string>({serverAddr}), std::move(hardware)) {};
@@ -243,6 +263,26 @@ GrpcVehicleProxyServer::GrpcVehicleProxyServer(std::vector<std::string> serverAd
    return ::grpc::Status(::grpc::StatusCode::ABORTED, "Connection lost.");
}

::grpc::Status GrpcVehicleProxyServer::GetMinMaxSupportedValues(
        ::grpc::ServerContext* context, const proto::GetMinMaxSupportedValuesRequest* request,
        proto::GetMinMaxSupportedValuesResult* result) {
    std::vector<PropIdAreaId> propIdAreaIds = getPropIdAreaIdsFromProtoRequest(request);
    std::vector<aidlvhal::MinMaxSupportedValueResult> minMaxSupportedValueResults =
            mHardware->getMinMaxSupportedValues(propIdAreaIds);
    aidlResultsToProtoResults(minMaxSupportedValueResults, result);
    return ::grpc::Status::OK;
}

::grpc::Status GrpcVehicleProxyServer::GetSupportedValuesLists(
        ::grpc::ServerContext* context, const proto::GetSupportedValuesListsRequest* request,
        proto::GetSupportedValuesListsResult* result) {
    std::vector<PropIdAreaId> propIdAreaIds = getPropIdAreaIdsFromProtoRequest(request);
    std::vector<aidlvhal::SupportedValuesListResult> supportedValuesListResults =
            mHardware->getSupportedValuesLists(propIdAreaIds);
    aidlResultsToProtoResults(supportedValuesListResults, result);
    return ::grpc::Status::OK;
}

void GrpcVehicleProxyServer::OnVehiclePropChange(
        const std::vector<aidlvhal::VehiclePropValue>& values) {
    std::unordered_set<uint64_t> brokenConn;
+8 −0
Original line number Diff line number Diff line
@@ -77,6 +77,14 @@ class GrpcVehicleProxyServer : public proto::VehicleServer::Service {
            ::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
            ::grpc::ServerWriter<proto::VehiclePropValues>* stream) override;

    ::grpc::Status GetMinMaxSupportedValues(
            ::grpc::ServerContext* context, const proto::GetMinMaxSupportedValuesRequest* requests,
            proto::GetMinMaxSupportedValuesResult* results) override;

    ::grpc::Status GetSupportedValuesLists(::grpc::ServerContext* context,
                                           const proto::GetSupportedValuesListsRequest* requests,
                                           proto::GetSupportedValuesListsResult* results) override;

    GrpcVehicleProxyServer& Start();

    GrpcVehicleProxyServer& Shutdown();
+8 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ 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/GetMinMaxSupportedValuesTypes.proto";
import "android/hardware/automotive/vehicle/GetSupportedValuesListsTypes.proto";
import "android/hardware/automotive/vehicle/SubscribeRequest.proto";
import "android/hardware/automotive/vehicle/StatusCode.proto";
import "android/hardware/automotive/vehicle/UnsubscribeRequest.proto";
@@ -46,4 +48,10 @@ service VehicleServer {
    rpc Subscribe(SubscribeRequest) returns (VehicleHalCallStatus) {}

    rpc Unsubscribe(UnsubscribeRequest) returns (VehicleHalCallStatus) {}

    rpc GetMinMaxSupportedValues(GetMinMaxSupportedValuesRequest)
            returns (GetMinMaxSupportedValuesResult) {}

    rpc GetSupportedValuesLists(GetSupportedValuesListsRequest)
            returns (GetSupportedValuesListsResult) {}
}
Loading