Merge "[API] Run vsock RPC server with vm_payload API for benchmarks"
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 58a2c85..e42f159 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -63,6 +63,7 @@
 use vsock::VsockStream;
 
 const WAIT_TIMEOUT: Duration = Duration::from_secs(10);
+const SENDING_VM_STATUS_CYCLE_PERIOD: Duration = Duration::from_secs(60);
 const MAIN_APK_PATH: &str = "/dev/block/by-name/microdroid-apk";
 const MAIN_APK_IDSIG_PATH: &str = "/dev/block/by-name/microdroid-apk-idsig";
 const MAIN_APK_DEVICE_NAME: &str = "microdroid-apk";
@@ -95,39 +96,39 @@
     InvalidConfig(String),
 }
 
-fn send_vm_status() -> Result<()> {
+fn send_vm_status(service: &Strong<dyn IVirtualMachineService>) -> Result<()> {
+    // Collect VM CPU time information and creating VmCpuStatus atom for metrics.
+    let cpu_time = get_cpu_time()?;
+    let vm_cpu_status = VirtualMachineCpuStatus {
+        cpu_time_user: cpu_time.user,
+        cpu_time_nice: cpu_time.nice,
+        cpu_time_sys: cpu_time.sys,
+        cpu_time_idle: cpu_time.idle,
+    };
+    service.notifyCpuStatus(&vm_cpu_status).expect("Can't send information about VM CPU status");
+
+    // Collect VM memory information and creating VmMemStatus atom for metrics.
+    let mem_info = get_mem_info()?;
+    let vm_mem_status = VirtualMachineMemStatus {
+        mem_total: mem_info.total,
+        mem_free: mem_info.free,
+        mem_available: mem_info.available,
+        mem_buffer: mem_info.buffer,
+        mem_cached: mem_info.cached,
+    };
+    service.notifyMemStatus(&vm_mem_status).expect("Can't send information about VM memory status");
+
+    Ok(())
+}
+
+fn send_vm_status_periodically() -> Result<()> {
     let service = get_vms_rpc_binder()
         .context("cannot connect to VirtualMachineService")
         .map_err(|e| MicrodroidError::FailedToConnectToVirtualizationService(e.to_string()))?;
 
-    let one_second = Duration::from_millis(1000);
     loop {
-        // Collect VM CPU time information and creating VmCpuStatus atom for metrics.
-        let cpu_time = get_cpu_time()?;
-        let vm_cpu_status = VirtualMachineCpuStatus {
-            cpu_time_user: cpu_time.user,
-            cpu_time_nice: cpu_time.nice,
-            cpu_time_sys: cpu_time.sys,
-            cpu_time_idle: cpu_time.idle,
-        };
-        service
-            .notifyCpuStatus(&vm_cpu_status)
-            .expect("Can't send information about VM CPU status");
-
-        // Collect VM memory information and creating VmMemStatus atom for metrics.
-        let mem_info = get_mem_info()?;
-        let vm_mem_status = VirtualMachineMemStatus {
-            mem_total: mem_info.total,
-            mem_free: mem_info.free,
-            mem_available: mem_info.available,
-            mem_buffer: mem_info.buffer,
-            mem_cached: mem_info.cached,
-        };
-        service
-            .notifyMemStatus(&vm_mem_status)
-            .expect("Can't send information about VM memory status");
-
-        thread::sleep(one_second);
+        send_vm_status(&service)?;
+        thread::sleep(SENDING_VM_STATUS_CYCLE_PERIOD);
     }
 }
 
@@ -224,7 +225,7 @@
         .map_err(|e| MicrodroidError::FailedToConnectToVirtualizationService(e.to_string()))?;
 
     thread::spawn(move || {
-        if let Err(e) = send_vm_status() {
+        if let Err(e) = send_vm_status_periodically() {
             error!("failed to get virtual machine status: {:?}", e);
         }
     });
@@ -448,6 +449,7 @@
     ProcessState::start_thread_pool();
 
     system_properties::write("dev.bootcomplete", "1").context("set dev.bootcomplete")?;
+    send_vm_status(service)?;
 
     exec_task(task, service).context("Failed to run payload")
 }
@@ -780,6 +782,7 @@
     service.notifyPayloadStarted()?;
 
     let exit_status = command.spawn()?.wait()?;
+    send_vm_status(service)?;
     exit_status.code().ok_or_else(|| anyhow!("Failed to get exit_code from the paylaod."))
 }
 
diff --git a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
index c9df624..33788ed 100644
--- a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
+++ b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
@@ -485,7 +485,7 @@
     }
 
     @Test
-    public void testTelemetryPushedAtoms() throws Exception {
+    public void testTelemetryPushedAtomsOfEventMetrics() throws Exception {
         // Reset statsd config and report before the test
         ConfigUtils.removeConfig(getDevice());
         ReportUtils.clearReports(getDevice());
@@ -566,6 +566,49 @@
     }
 
     @Test
+    public void testTelemetryPushedAtomsOfValueMetrics() throws Exception {
+        // Reset statsd config and report before the test
+        ConfigUtils.removeConfig(getDevice());
+        ReportUtils.clearReports(getDevice());
+
+        // Setup statsd config
+        int[] atomIds = {
+            AtomsProto.Atom.VM_CPU_STATUS_REPORTED_FIELD_NUMBER,
+            AtomsProto.Atom.VM_MEM_STATUS_REPORTED_FIELD_NUMBER,
+        };
+        ConfigUtils.uploadConfigForPushedAtoms(getDevice(), PACKAGE_NAME, atomIds);
+
+        // Create VM with microdroid
+        final String configPath = "assets/vm_config_apex.json"; // path inside the APK
+        final String cid =
+                startMicrodroid(
+                        getDevice(),
+                        getBuild(),
+                        APK_NAME,
+                        PACKAGE_NAME,
+                        configPath,
+                        /* debug */ true,
+                        minMemorySize(),
+                        Optional.of(NUM_VCPUS));
+
+        // Boot VM with microdroid
+        adbConnectToMicrodroid(getDevice(), cid);
+        waitForBootComplete();
+
+        // Check VmCpuStatusReported and VmMemStatusReported atoms and clear the statsd report
+        List<StatsLog.EventMetricData> data;
+        data = ReportUtils.getEventMetricDataList(getDevice());
+        assertThat(data.size() >= 2).isTrue();
+        assertThat(data.get(0).getAtom().getPushedCase().getNumber())
+                .isEqualTo(AtomsProto.Atom.VM_CPU_STATUS_REPORTED_FIELD_NUMBER);
+        assertThat(data.get(1).getAtom().getPushedCase().getNumber())
+                .isEqualTo(AtomsProto.Atom.VM_MEM_STATUS_REPORTED_FIELD_NUMBER);
+
+        // Shutdown VM with microdroid
+        shutdownMicrodroid(getDevice(), cid);
+    }
+
+    @Test
     @CddTest(requirements = {"9.17/C-1-1", "9.17/C-1-2", "9.17/C/1-3"})
     public void testMicrodroidBoots() throws Exception {
         final String configPath = "assets/vm_config.json"; // path inside the APK