Use random port for grpc service

To prevent port conflicts, randomly assign port number to grpc service
and then share it with the guest via virtiofs

Test: run terminal, and check if grpc works well
Bug: 372666638
Change-Id: I90bb430047afd1ba3569d2baa550586a37b26ac7
diff --git a/build/debian/fai_config/files/etc/systemd/system/forwarder_guest_launcher.service/AVF b/build/debian/fai_config/files/etc/systemd/system/forwarder_guest_launcher.service/AVF
index 251f88c..4c1b2f5 100644
--- a/build/debian/fai_config/files/etc/systemd/system/forwarder_guest_launcher.service/AVF
+++ b/build/debian/fai_config/files/etc/systemd/system/forwarder_guest_launcher.service/AVF
@@ -2,8 +2,9 @@
 Description=Port forwarding service in guest VM
 After=syslog.target
 After=network.target
+After=virtiofs_internal.service
 [Service]
-ExecStart=/usr/local/bin/forwarder_guest_launcher --host 192.168.0.1
+ExecStart=/usr/local/bin/forwarder_guest_launcher --host 192.168.0.1 --grpc_port $(cat /mnt/internal/debian_service_port)
 Type=simple
 Restart=on-failure
 RestartSec=1
diff --git a/build/debian/fai_config/files/etc/systemd/system/ip_addr_reporter.service/AVF b/build/debian/fai_config/files/etc/systemd/system/ip_addr_reporter.service/AVF
index 7d163fb..81347a7 100644
--- a/build/debian/fai_config/files/etc/systemd/system/ip_addr_reporter.service/AVF
+++ b/build/debian/fai_config/files/etc/systemd/system/ip_addr_reporter.service/AVF
@@ -3,8 +3,9 @@
 After=syslog.target
 After=network.target
 Requires=ttyd.service
+After=virtiofs_internal.service
 [Service]
-ExecStart=/usr/local/bin/ip_addr_reporter
+ExecStart=/usr/local/bin/ip_addr_reporter --grpc_port $(cat /mnt/internal/debian_service_port)
 Type=simple
 Restart=on-failure
 User=root
diff --git a/guest/forwarder_guest_launcher/src/main.rs b/guest/forwarder_guest_launcher/src/main.rs
index 59ee8c6..d753d19 100644
--- a/guest/forwarder_guest_launcher/src/main.rs
+++ b/guest/forwarder_guest_launcher/src/main.rs
@@ -33,13 +33,17 @@
     #[arg(long)]
     #[arg(alias = "host")]
     host_addr: String,
+    /// grpc port number
+    #[arg(long)]
+    #[arg(alias = "grpc_port")]
+    grpc_port: String,
 }
 
 #[tokio::main]
 async fn main() -> Result<(), Box<dyn std::error::Error>> {
     println!("Starting forwarder_guest_launcher");
     let args = Args::parse();
-    let addr = format!("https://{}:12000", args.host_addr);
+    let addr = format!("https://{}:{}", args.host_addr, args.grpc_port);
 
     let channel = Endpoint::from_shared(addr)?.connect().await?;
     let mut client = DebianServiceClient::new(channel);
diff --git a/guest/ip_addr_reporter/Cargo.toml b/guest/ip_addr_reporter/Cargo.toml
index e255eaf..900f546 100644
--- a/guest/ip_addr_reporter/Cargo.toml
+++ b/guest/ip_addr_reporter/Cargo.toml
@@ -4,6 +4,7 @@
 edition = "2021"
 
 [dependencies]
+clap = { version = "4.5.20", features = ["derive"] }
 netdev = "0.31.0"
 prost = "0.13.3"
 tokio = { version = "1.40.0", features = ["rt-multi-thread"] }
diff --git a/guest/ip_addr_reporter/src/main.rs b/guest/ip_addr_reporter/src/main.rs
index 5784a83..2c782d3 100644
--- a/guest/ip_addr_reporter/src/main.rs
+++ b/guest/ip_addr_reporter/src/main.rs
@@ -1,17 +1,27 @@
 use api::debian_service_client::DebianServiceClient;
 use api::IpAddr;
 
+use clap::Parser;
 pub mod api {
     tonic::include_proto!("com.android.virtualization.vmlauncher.proto");
 }
 
+#[derive(Parser)]
+/// Flags for running command
+pub struct Args {
+    /// grpc port number
+    #[arg(long)]
+    #[arg(alias = "grpc_port")]
+    grpc_port: String,
+}
+
 #[tokio::main]
 async fn main() -> Result<(), String> {
+    let args = Args::parse();
     let gateway_ip_addr = netdev::get_default_gateway()?.ipv4[0];
     let ip_addr = netdev::get_default_interface()?.ipv4[0].addr();
-    const PORT: i32 = 12000;
 
-    let server_addr = format!("http://{}:{}", gateway_ip_addr.to_string(), PORT);
+    let server_addr = format!("http://{}:{}", gateway_ip_addr.to_string(), args.grpc_port);
 
     println!("local ip addr: {}", ip_addr.to_string());
     println!("coonect to grpc server {}", server_addr);
diff --git a/libs/vm_launcher_lib/java/com/android/virtualization/vmlauncher/VmLauncherService.java b/libs/vm_launcher_lib/java/com/android/virtualization/vmlauncher/VmLauncherService.java
index e5d68cc..f672b7b 100644
--- a/libs/vm_launcher_lib/java/com/android/virtualization/vmlauncher/VmLauncherService.java
+++ b/libs/vm_launcher_lib/java/com/android/virtualization/vmlauncher/VmLauncherService.java
@@ -37,6 +37,8 @@
 import io.grpc.Status;
 import io.grpc.okhttp.OkHttpServerBuilder;
 
+import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.nio.file.Path;
@@ -171,11 +173,9 @@
                 };
         new Thread(
                         () -> {
-                            // TODO(b/372666638): gRPC for java doesn't support vsock for now.
-                            // In addition, let's consider using a dynamic port and SSL(and client
-                            // certificate)
-                            int port = 12000;
                             try {
+                                // TODO(b/372666638): gRPC for java doesn't support vsock for now.
+                                int port = 0;
                                 mServer =
                                         OkHttpServerBuilder.forPort(
                                                         port, InsecureServerCredentials.create())
@@ -183,6 +183,17 @@
                                                 .addService(new DebianServiceImpl(this))
                                                 .build()
                                                 .start();
+
+                                // TODO(b/373533555): we can use mDNS for that.
+                                String debianServicePortFileName = "debian_service_port";
+                                File debianServicePortFile =
+                                        new File(getFilesDir(), debianServicePortFileName);
+                                try (FileOutputStream writer =
+                                        new FileOutputStream(debianServicePortFile)) {
+                                    writer.write(String.valueOf(mServer.getPort()).getBytes());
+                                } catch (IOException e) {
+                                    Log.d(TAG, "cannot write grpc port number", e);
+                                }
                             } catch (IOException e) {
                                 Log.d(TAG, "grpc server error", e);
                             }