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
diff --git a/automotive/remoteaccess/hal/default/Android.bp b/automotive/remoteaccess/hal/default/Android.bp
index be6a425..cf173d5 100644
--- a/automotive/remoteaccess/hal/default/Android.bp
+++ b/automotive/remoteaccess/hal/default/Android.bp
@@ -52,11 +52,6 @@
     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 @@
     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 {
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp
index 28c5cd5..a50f3bb 100644
--- a/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp
@@ -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);
 
-#ifdef GRPC_SERVICE_ADDRESS
-    LOG(INFO) << "Registering RemoteAccessService as service, server: " << GRPC_SERVICE_ADDRESS
-              << "...";
-    grpc::ChannelArguments grpcargs = {};
+    std::unique_ptr<android::hardware::automotive::remoteaccess::WakeupClient::Stub> grpcStub;
 
-#ifdef GRPC_SERVICE_IFNAME
-    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},
-                                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);
+    if (grpcServiceAddress != "") {
+        LOG(INFO) << "Registering RemoteAccessService as service, server: " << grpcServiceAddress
+                  << "...";
+        grpc::ChannelArguments grpcargs = {};
 
-    grpcStub = clientStub.get();
-
-#else
-    LOG(INFO) << "GRPC_SERVICE_ADDRESS is not defined, work in fake mode";
-#endif  // #ifdef GRPC_SERVICE_ADDRESS
+        if (grpcServiceIfname != "") {
+            grpcargs.SetSocketMutator(
+                    android::hardware::automotive::remoteaccess::MakeBindToDeviceSocketMutator(
+                            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: " << 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) {
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
index 80e4087..5fc07c9 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
@@ -29,9 +29,6 @@
     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",
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
index 8d6c883..644d1cd 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -189,6 +189,10 @@
     // 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);
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index c4e7086..072aafc 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -114,6 +114,9 @@
 // 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_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 @@
 }
 
 void FakeVehicleHardware::init() {
+    maybeGetGrpcServiceInfo(&mPowerControllerServiceAddress);
+
     for (auto& [_, configDeclaration] : loadConfigDeclarations()) {
         VehiclePropConfig cfg = configDeclaration.config;
         VehiclePropertyStore::TokenFunction tokenFunction = nullptr;
@@ -774,12 +790,12 @@
     int32_t propId = value.prop;
     ValueResultType result;
 
-#ifdef POWER_GRPC_SERVICE_ADDRESS
-    if (mPowerPropIds.find(propId) != mPowerPropIds.end()) {
-        *isSpecialValue = true;
-        return getPowerPropFromExternalService(propId);
+    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::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 @@
             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(