Send atoms via VirtualizationServiceInternal

In preparation for spliting VS into two services (global and
UID-specific), forward all statsd atoms via
VirtualizationServiceInternal. This is necessary because statsd
will not accept atoms from the client-specific VS instance, as it only
accepts atoms from known UIDs.

Bug: 245727626
Test: atest MicrodroidHostTestCases
Change-Id: I779bbc77a83665a88c9e12d3ad25824e7857514b
diff --git a/virtualizationservice/src/atom.rs b/virtualizationservice/src/atom.rs
index a880d60..698dbca 100644
--- a/virtualizationservice/src/atom.rs
+++ b/virtualizationservice/src/atom.rs
@@ -14,15 +14,20 @@
 
 //! Functions for creating and collecting atoms.
 
-use crate::aidl::clone_file;
+use crate::aidl::{clone_file, GLOBAL_SERVICE};
 use crate::crosvm::VmMetric;
+use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::DeathReason::DeathReason;
 use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
-    DeathReason::DeathReason,
     IVirtualMachine::IVirtualMachine,
     VirtualMachineAppConfig::{Payload::Payload, VirtualMachineAppConfig},
     VirtualMachineConfig::VirtualMachineConfig,
 };
 use android_system_virtualizationservice::binder::{Status, Strong};
+use android_system_virtualizationservice_internal::aidl::android::system::virtualizationservice_internal::{
+    AtomVmBooted::AtomVmBooted,
+    AtomVmCreationRequested::AtomVmCreationRequested,
+    AtomVmExited::AtomVmExited,
+};
 use anyhow::{anyhow, Result};
 use binder::{ParcelFileDescriptor, ThreadState};
 use log::{trace, warn};
@@ -106,34 +111,58 @@
         ),
     };
 
-    let uid = ThreadState::get_calling_uid() as i32;
-    thread::spawn(move || {
-        let vm_creation_requested = vm_creation_requested::VmCreationRequested {
-            uid,
-            vm_identifier: &vm_identifier,
-            hypervisor: vm_creation_requested::Hypervisor::Pkvm,
-            is_protected,
-            creation_succeeded,
-            binder_exception_code,
-            config_type,
-            num_cpus,
-            cpu_affinity: "", // deprecated
-            memory_mib,
-            apexes: &apexes,
-            // TODO(seungjaeyoo) Fill information about task_profile
-            // TODO(seungjaeyoo) Fill information about disk_image for raw config
-        };
+    let atom = AtomVmCreationRequested {
+        uid: ThreadState::get_calling_uid() as i32,
+        vmIdentifier: vm_identifier,
+        isProtected: is_protected,
+        creationSucceeded: creation_succeeded,
+        binderExceptionCode: binder_exception_code,
+        configType: config_type as i32,
+        numCpus: num_cpus,
+        memoryMib: memory_mib,
+        apexes,
+    };
 
-        wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
-        match vm_creation_requested.stats_write() {
-            Err(e) => {
-                warn!("statslog_rust failed with error: {}", e);
-            }
-            Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
-        }
+    thread::spawn(move || {
+        GLOBAL_SERVICE.atomVmCreationRequested(&atom).unwrap_or_else(|e| {
+            warn!("Failed to write VmCreationRequested atom: {e}");
+        });
     });
 }
 
+pub fn forward_vm_creation_atom(atom: &AtomVmCreationRequested) {
+    let config_type = match atom.configType {
+        x if x == vm_creation_requested::ConfigType::VirtualMachineAppConfig as i32 => {
+            vm_creation_requested::ConfigType::VirtualMachineAppConfig
+        }
+        x if x == vm_creation_requested::ConfigType::VirtualMachineRawConfig as i32 => {
+            vm_creation_requested::ConfigType::VirtualMachineRawConfig
+        }
+        _ => vm_creation_requested::ConfigType::UnknownConfig,
+    };
+    let vm_creation_requested = vm_creation_requested::VmCreationRequested {
+        uid: atom.uid,
+        vm_identifier: &atom.vmIdentifier,
+        hypervisor: vm_creation_requested::Hypervisor::Pkvm,
+        is_protected: atom.isProtected,
+        creation_succeeded: atom.creationSucceeded,
+        binder_exception_code: atom.binderExceptionCode,
+        config_type,
+        num_cpus: atom.numCpus,
+        cpu_affinity: "", // deprecated
+        memory_mib: atom.memoryMib,
+        apexes: &atom.apexes,
+        // TODO(seungjaeyoo) Fill information about task_profile
+        // TODO(seungjaeyoo) Fill information about disk_image for raw config
+    };
+
+    wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
+    match vm_creation_requested.stats_write() {
+        Err(e) => warn!("statslog_rust failed with error: {}", e),
+        Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
+    }
+}
+
 /// Write the stats of VM boot to statsd
 /// The function creates a separate thread which waits fro statsd to start to push atom
 pub fn write_vm_booted_stats(
@@ -143,22 +172,34 @@
 ) {
     let vm_identifier = vm_identifier.to_owned();
     let duration = get_duration(vm_start_timestamp);
+
+    let atom = AtomVmBooted {
+        uid,
+        vmIdentifier: vm_identifier,
+        elapsedTimeMillis: duration.as_millis() as i64,
+    };
+
     thread::spawn(move || {
-        let vm_booted = vm_booted::VmBooted {
-            uid,
-            vm_identifier: &vm_identifier,
-            elapsed_time_millis: duration.as_millis() as i64,
-        };
-        wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
-        match vm_booted.stats_write() {
-            Err(e) => {
-                warn!("statslog_rust failed with error: {}", e);
-            }
-            Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
-        }
+        GLOBAL_SERVICE.atomVmBooted(&atom).unwrap_or_else(|e| {
+            warn!("Failed to write VmCreationRequested atom: {e}");
+        });
     });
 }
 
+pub fn forward_vm_booted_atom(atom: &AtomVmBooted) {
+    let vm_booted = vm_booted::VmBooted {
+        uid: atom.uid,
+        vm_identifier: &atom.vmIdentifier,
+        elapsed_time_millis: atom.elapsedTimeMillis,
+    };
+
+    wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
+    match vm_booted.stats_write() {
+        Err(e) => warn!("statslog_rust failed with error: {}", e),
+        Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
+    }
+}
+
 /// Write the stats of VM exit to statsd
 /// The function creates a separate thread which waits fro statsd to start to push atom
 pub fn write_vm_exited_stats(
@@ -173,64 +214,82 @@
     let guest_time_millis = vm_metric.cpu_guest_time.unwrap_or_default();
     let rss = vm_metric.rss.unwrap_or_default();
 
+    let atom = AtomVmExited {
+        uid,
+        vmIdentifier: vm_identifier,
+        elapsedTimeMillis: elapsed_time_millis,
+        deathReason: reason,
+        guestTimeMillis: guest_time_millis,
+        rssVmKb: rss.vm,
+        rssCrosvmKb: rss.crosvm,
+        exitSignal: exit_signal.unwrap_or_default(),
+    };
+
     thread::spawn(move || {
-        let vm_exited = vm_exited::VmExited {
-            uid,
-            vm_identifier: &vm_identifier,
-            elapsed_time_millis,
-            death_reason: match reason {
-                DeathReason::INFRASTRUCTURE_ERROR => vm_exited::DeathReason::InfrastructureError,
-                DeathReason::KILLED => vm_exited::DeathReason::Killed,
-                DeathReason::UNKNOWN => vm_exited::DeathReason::Unknown,
-                DeathReason::SHUTDOWN => vm_exited::DeathReason::Shutdown,
-                DeathReason::START_FAILED => vm_exited::DeathReason::Error,
-                DeathReason::REBOOT => vm_exited::DeathReason::Reboot,
-                DeathReason::CRASH => vm_exited::DeathReason::Crash,
-                DeathReason::PVM_FIRMWARE_PUBLIC_KEY_MISMATCH => {
-                    vm_exited::DeathReason::PvmFirmwarePublicKeyMismatch
-                }
-                DeathReason::PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED => {
-                    vm_exited::DeathReason::PvmFirmwareInstanceImageChanged
-                }
-                DeathReason::BOOTLOADER_PUBLIC_KEY_MISMATCH => {
-                    vm_exited::DeathReason::BootloaderPublicKeyMismatch
-                }
-                DeathReason::BOOTLOADER_INSTANCE_IMAGE_CHANGED => {
-                    vm_exited::DeathReason::BootloaderInstanceImageChanged
-                }
-                DeathReason::MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE => {
-                    vm_exited::DeathReason::MicrodroidFailedToConnectToVirtualizationService
-                }
-                DeathReason::MICRODROID_PAYLOAD_HAS_CHANGED => {
-                    vm_exited::DeathReason::MicrodroidPayloadHasChanged
-                }
-                DeathReason::MICRODROID_PAYLOAD_VERIFICATION_FAILED => {
-                    vm_exited::DeathReason::MicrodroidPayloadVerificationFailed
-                }
-                DeathReason::MICRODROID_INVALID_PAYLOAD_CONFIG => {
-                    vm_exited::DeathReason::MicrodroidInvalidPayloadConfig
-                }
-                DeathReason::MICRODROID_UNKNOWN_RUNTIME_ERROR => {
-                    vm_exited::DeathReason::MicrodroidUnknownRuntimeError
-                }
-                DeathReason::HANGUP => vm_exited::DeathReason::Hangup,
-                _ => vm_exited::DeathReason::Unknown,
-            },
-            guest_time_millis,
-            rss_vm_kb: rss.vm,
-            rss_crosvm_kb: rss.crosvm,
-            exit_signal: exit_signal.unwrap_or_default(),
-        };
-        wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
-        match vm_exited.stats_write() {
-            Err(e) => {
-                warn!("statslog_rust failed with error: {}", e);
-            }
-            Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
-        }
+        GLOBAL_SERVICE.atomVmExited(&atom).unwrap_or_else(|e| {
+            warn!("Failed to write VmExited atom: {e}");
+        });
     });
 }
 
+pub fn forward_vm_exited_atom(atom: &AtomVmExited) {
+    let death_reason = match atom.deathReason {
+        DeathReason::INFRASTRUCTURE_ERROR => vm_exited::DeathReason::InfrastructureError,
+        DeathReason::KILLED => vm_exited::DeathReason::Killed,
+        DeathReason::UNKNOWN => vm_exited::DeathReason::Unknown,
+        DeathReason::SHUTDOWN => vm_exited::DeathReason::Shutdown,
+        DeathReason::START_FAILED => vm_exited::DeathReason::Error,
+        DeathReason::REBOOT => vm_exited::DeathReason::Reboot,
+        DeathReason::CRASH => vm_exited::DeathReason::Crash,
+        DeathReason::PVM_FIRMWARE_PUBLIC_KEY_MISMATCH => {
+            vm_exited::DeathReason::PvmFirmwarePublicKeyMismatch
+        }
+        DeathReason::PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED => {
+            vm_exited::DeathReason::PvmFirmwareInstanceImageChanged
+        }
+        DeathReason::BOOTLOADER_PUBLIC_KEY_MISMATCH => {
+            vm_exited::DeathReason::BootloaderPublicKeyMismatch
+        }
+        DeathReason::BOOTLOADER_INSTANCE_IMAGE_CHANGED => {
+            vm_exited::DeathReason::BootloaderInstanceImageChanged
+        }
+        DeathReason::MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE => {
+            vm_exited::DeathReason::MicrodroidFailedToConnectToVirtualizationService
+        }
+        DeathReason::MICRODROID_PAYLOAD_HAS_CHANGED => {
+            vm_exited::DeathReason::MicrodroidPayloadHasChanged
+        }
+        DeathReason::MICRODROID_PAYLOAD_VERIFICATION_FAILED => {
+            vm_exited::DeathReason::MicrodroidPayloadVerificationFailed
+        }
+        DeathReason::MICRODROID_INVALID_PAYLOAD_CONFIG => {
+            vm_exited::DeathReason::MicrodroidInvalidPayloadConfig
+        }
+        DeathReason::MICRODROID_UNKNOWN_RUNTIME_ERROR => {
+            vm_exited::DeathReason::MicrodroidUnknownRuntimeError
+        }
+        DeathReason::HANGUP => vm_exited::DeathReason::Hangup,
+        _ => vm_exited::DeathReason::Unknown,
+    };
+
+    let vm_exited = vm_exited::VmExited {
+        uid: atom.uid,
+        vm_identifier: &atom.vmIdentifier,
+        elapsed_time_millis: atom.elapsedTimeMillis,
+        death_reason,
+        guest_time_millis: atom.guestTimeMillis,
+        rss_vm_kb: atom.rssVmKb,
+        rss_crosvm_kb: atom.rssCrosvmKb,
+        exit_signal: atom.exitSignal,
+    };
+
+    wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
+    match vm_exited.stats_write() {
+        Err(e) => warn!("statslog_rust failed with error: {}", e),
+        Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
+    }
+}
+
 fn wait_for_statsd() -> Result<()> {
     let mut prop = system_properties::PropertyWatcher::new("init.svc.statsd")?;
     loop {