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

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

Use runtime config file instead of compile flag.

Use runtime config file instead of compile flag to control an
optional external grpc server address. This allows us to test
connecting with an external simluated power unit without recompiling
the image.

Test: Manual test with push the config file at
/vendor/etc/automotive/powercontroller/serverconfig
Bug: 325675883

Change-Id: I04193e7603a670c8398c6d6dc0466a0071f7c33d
parent 4cc6345c
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -52,11 +52,6 @@ cc_binary {
    defaults: ["remote-access-hal-defaults"],
    vintf_fragments: ["remoteaccess-default-service.xml"],
    init_rc: ["remoteaccess-default-service.rc"],
    cflags: [
        // Uncomment this if running on emulator and connecting to a local grpc server
        // running on host 127.0.0.1:50051 (TestWakeupClientServerHost)
        // "-DGRPC_SERVICE_ADDRESS=\"10.0.2.2:50051\"",
    ],
}

cc_binary {
@@ -64,10 +59,6 @@ cc_binary {
    defaults: ["remote-access-hal-defaults"],
    vintf_fragments: ["remoteaccess-default-service.xml"],
    init_rc: ["remoteaccess-tcu-test-service.rc"],
    cflags: [
        "-DGRPC_SERVICE_ADDRESS=\"10.10.10.1:50051\"",
        "-DGRPC_SERVICE_IFNAME=\"eth1\"",
    ],
}

cc_library {
+55 −26
Original line number Diff line number Diff line
@@ -27,37 +27,66 @@
#include <libnetdevice/libnetdevice.h>
#include <stdlib.h>

namespace {

constexpr char GRPC_SERVICE_CONFIG_FILE[] = "/vendor/etc/automotive/powercontroller/serverconfig";
constexpr char SERVICE_NAME[] = "android.hardware.automotive.remoteaccess.IRemoteAccess/default";

void maybeGetGrpcServiceInfo(std::string* address, std::string* ifname) {
    std::ifstream ifs(GRPC_SERVICE_CONFIG_FILE);
    if (!ifs) {
        LOG(INFO) << "Cannot open grpc service config file at: " << GRPC_SERVICE_CONFIG_FILE
                  << ", assume no service is available";
        return;
    }
    int count = 0;
    while (ifs.good()) {
        std::string line;
        ifs >> line;
        // First line is address, second line, if present is ifname.
        if (count == 0) {
            *address = line;
        } else {
            *ifname = line;
            break;
        }
        count++;
    }
    ifs.close();
}

}  // namespace

int main(int /* argc */, char* /* argv */[]) {
    android::hardware::automotive::remoteaccess::WakeupClient::StubInterface* grpcStub = nullptr;
    std::string grpcServiceAddress = "";
    std::string grpcServiceIfname = "";
    maybeGetGrpcServiceInfo(&grpcServiceAddress, &grpcServiceIfname);

    std::unique_ptr<android::hardware::automotive::remoteaccess::WakeupClient::Stub> grpcStub;

#ifdef GRPC_SERVICE_ADDRESS
    LOG(INFO) << "Registering RemoteAccessService as service, server: " << GRPC_SERVICE_ADDRESS
    if (grpcServiceAddress != "") {
        LOG(INFO) << "Registering RemoteAccessService as service, server: " << grpcServiceAddress
                  << "...";
        grpc::ChannelArguments grpcargs = {};

#ifdef GRPC_SERVICE_IFNAME
        if (grpcServiceIfname != "") {
            grpcargs.SetSocketMutator(
                    android::hardware::automotive::remoteaccess::MakeBindToDeviceSocketMutator(
                    GRPC_SERVICE_IFNAME));
    LOG(DEBUG) << "GRPC_SERVICE_IFNAME specified as: " << GRPC_SERVICE_IFNAME;
    LOG(INFO) << "Waiting for interface: " << GRPC_SERVICE_IFNAME;
    android::netdevice::waitFor({GRPC_SERVICE_IFNAME},
                            grpcServiceIfname));
            LOG(DEBUG) << "grpcServiceIfname specified as: " << grpcServiceIfname;
            LOG(INFO) << "Waiting for interface: " << grpcServiceIfname;
            android::netdevice::waitFor({grpcServiceIfname},
                                        android::netdevice::WaitCondition::PRESENT_AND_UP);
    LOG(INFO) << "Waiting for interface: " << GRPC_SERVICE_IFNAME << " done";
#endif  // #ifdef GRPC_SERVICE_IFNAME
    auto channel = grpc::CreateChannel(GRPC_SERVICE_ADDRESS, grpc::InsecureChannelCredentials());
    auto clientStub = android::hardware::automotive::remoteaccess::WakeupClient::NewStub(channel);

    grpcStub = clientStub.get();

#else
    LOG(INFO) << "GRPC_SERVICE_ADDRESS is not defined, work in fake mode";
#endif  // #ifdef GRPC_SERVICE_ADDRESS
            LOG(INFO) << "Waiting for interface: " << grpcServiceIfname << " done";
        }
        auto channel = grpc::CreateChannel(grpcServiceAddress, grpc::InsecureChannelCredentials());
        grpcStub = android::hardware::automotive::remoteaccess::WakeupClient::NewStub(channel);
    } else {
        LOG(INFO) << "grpcServiceAddress is not defined, work in fake mode";
    }

    auto service = ndk::SharedRefBase::make<
            android::hardware::automotive::remoteaccess::RemoteAccessService>(grpcStub);
            android::hardware::automotive::remoteaccess::RemoteAccessService>(grpcStub.get());

    binder_exception_t err = AServiceManager_addService(service->asBinder().get(), SERVICE_NAME);
    if (err != EX_NONE) {
+0 −3
Original line number Diff line number Diff line
@@ -29,9 +29,6 @@ cc_library {
    export_include_dirs: ["include"],
    cflags: [
        "-DENABLE_VEHICLE_HAL_TEST_PROPERTIES",
        // Uncomment this if running on emulator and connecting to a local grpc server
        // running on host 127.0.0.1:50051 (TestWakeupClientServerHost)
        // "-DPOWER_GRPC_SERVICE_ADDRESS=\"10.0.2.2:50051\"",
    ],
    defaults: [
        "VehicleHalDefaults",
+4 −0
Original line number Diff line number Diff line
@@ -189,6 +189,10 @@ class FakeVehicleHardware : public IVehicleHardware {
    // Only used during initialization.
    JsonConfigLoader mLoader;

    // Only used during initialization. If not empty, points to an external grpc server that
    // provides power controlling related properties.
    std::string mPowerControllerServiceAddress = "";

    void init();
    // Stores the initial value to property store.
    void storePropInitialValue(const ConfigDeclaration& config);
+23 −12
Original line number Diff line number Diff line
@@ -114,6 +114,9 @@ constexpr char DEFAULT_CONFIG_DIR[] = "/vendor/etc/automotive/vhalconfig/";
// The directory for property configuration file that overrides the default configuration file.
// For config file format, see impl/default_config/config/README.md.
constexpr char OVERRIDE_CONFIG_DIR[] = "/vendor/etc/automotive/vhaloverride/";
// The optional config file for power controller grpc service that provides vehicleInUse and
// ApPowerBootupReason property.
constexpr char GRPC_SERVICE_CONFIG_FILE[] = "/vendor/etc/automotive/powercontroller/serverconfig";
// If OVERRIDE_PROPERTY is set, we will use the configuration files from OVERRIDE_CONFIG_DIR to
// overwrite the default configs.
constexpr char OVERRIDE_PROPERTY[] = "persist.vendor.vhal_init_value_override";
@@ -267,6 +270,17 @@ const std::unordered_map<int32_t, std::vector<int32_t>> mAdasEnabledPropToAdasPr
const std::unordered_set<int32_t> mPowerPropIds = {toInt(VehicleProperty::VEHICLE_IN_USE),
                                                   toInt(VehicleProperty::AP_POWER_BOOTUP_REASON)};

void maybeGetGrpcServiceInfo(std::string* address) {
    std::ifstream ifs(GRPC_SERVICE_CONFIG_FILE);
    if (!ifs) {
        ALOGI("Cannot open grpc service config file at: %s, assume no service is available",
              GRPC_SERVICE_CONFIG_FILE);
        return;
    }
    ifs >> *address;
    ifs.close();
}

}  // namespace

void FakeVehicleHardware::storePropInitialValue(const ConfigDeclaration& config) {
@@ -357,6 +371,8 @@ std::unordered_map<int32_t, ConfigDeclaration> FakeVehicleHardware::loadConfigDe
}

void FakeVehicleHardware::init() {
    maybeGetGrpcServiceInfo(&mPowerControllerServiceAddress);

    for (auto& [_, configDeclaration] : loadConfigDeclarations()) {
        VehiclePropConfig cfg = configDeclaration.config;
        VehiclePropertyStore::TokenFunction tokenFunction = nullptr;
@@ -774,12 +790,12 @@ FakeVehicleHardware::ValueResultType FakeVehicleHardware::maybeGetSpecialValue(
    int32_t propId = value.prop;
    ValueResultType result;

#ifdef POWER_GRPC_SERVICE_ADDRESS
    if (mPowerControllerServiceAddress != "") {
        if (mPowerPropIds.find(propId) != mPowerPropIds.end()) {
            *isSpecialValue = true;
            return getPowerPropFromExternalService(propId);
        }
#endif
    }

    if (propId >= STARTING_VENDOR_CODE_PROPERTIES_FOR_TEST &&
        propId < ENDING_VENDOR_CODE_PROPERTIES_FOR_TEST) {
@@ -863,10 +879,9 @@ FakeVehicleHardware::ValueResultType FakeVehicleHardware::maybeGetSpecialValue(
}

FakeVehicleHardware::ValueResultType FakeVehicleHardware::getPowerPropFromExternalService(
        [[maybe_unused]] int32_t propId) const {
#ifdef POWER_GRPC_SERVICE_ADDRESS
        int32_t propId) const {
    auto channel =
            grpc::CreateChannel(POWER_GRPC_SERVICE_ADDRESS, grpc::InsecureChannelCredentials());
            grpc::CreateChannel(mPowerControllerServiceAddress, grpc::InsecureChannelCredentials());
    auto clientStub = PowerController::NewStub(channel);
    switch (propId) {
        case toInt(VehicleProperty::VEHICLE_IN_USE):
@@ -877,10 +892,6 @@ FakeVehicleHardware::ValueResultType FakeVehicleHardware::getPowerPropFromExtern
            return StatusError(StatusCode::INTERNAL_ERROR)
                   << "Unsupported power property ID: " << propId;
    }
#else
    // Must not reach here.
    return StatusError(StatusCode::INTERNAL_ERROR);
#endif
}

FakeVehicleHardware::ValueResultType FakeVehicleHardware::getVehicleInUse(