Refactor libavf to follow NDK guidelines

* Add __INTRODUCED_IN
* Add nullability annotations
* Clarify documentations (such as mentioning UTF-8, rephrasing, etc.)
* Rename enum and its value

Bug: b/369588412
Test: boot cuttlefish
Change-Id: I2ff69092590b2b6962f131eb866843d688a9cdb1
diff --git a/libs/libavf/src/lib.rs b/libs/libavf/src/lib.rs
index 0a8f891..1d7861f 100644
--- a/libs/libavf/src/lib.rs
+++ b/libs/libavf/src/lib.rs
@@ -19,6 +19,7 @@
 use std::os::fd::FromRawFd;
 use std::os::raw::{c_char, c_int};
 use std::ptr;
+use std::time::Duration;
 
 use android_system_virtualizationservice::{
     aidl::android::system::virtualizationservice::{
@@ -28,7 +29,8 @@
     },
     binder::{ParcelFileDescriptor, Strong},
 };
-use avf_bindgen::StopReason;
+use avf_bindgen::AVirtualMachineStopReason;
+use libc::timespec;
 use vmclient::{DeathReason, VirtualizationService, VmInstance};
 
 /// Create a new virtual machine config object with no properties.
@@ -70,8 +72,14 @@
     // AVirtualMachineRawConfig_create. It's the only reference to the object.
     let config = unsafe { &mut *config };
     // SAFETY: `name` is assumed to be a pointer to a valid C string.
-    config.name = unsafe { CStr::from_ptr(name) }.to_string_lossy().into_owned();
-    0
+    let name = unsafe { CStr::from_ptr(name) };
+    match name.to_str() {
+        Ok(name) => {
+            config.name = name.to_owned();
+            0
+        }
+        Err(_) => -libc::EINVAL,
+    }
 }
 
 /// Set an instance ID of a virtual machine.
@@ -83,7 +91,12 @@
 pub unsafe extern "C" fn AVirtualMachineRawConfig_setInstanceId(
     config: *mut VirtualMachineRawConfig,
     instance_id: *const u8,
+    instance_id_size: usize,
 ) -> c_int {
+    if instance_id_size != 64 {
+        return -libc::EINVAL;
+    }
+
     // SAFETY: `config` is assumed to be a valid, non-null pointer returned by
     // AVirtualMachineRawConfig_create. It's the only reference to the object.
     let config = unsafe { &mut *config };
@@ -91,7 +104,7 @@
     // is assumed to be a valid object returned by AVirtuaMachineConfig_create.
     // Both never overlap.
     unsafe {
-        ptr::copy_nonoverlapping(instance_id, config.instanceId.as_mut_ptr(), 64);
+        ptr::copy_nonoverlapping(instance_id, config.instanceId.as_mut_ptr(), instance_id_size);
     }
     0
 }
@@ -106,13 +119,12 @@
 pub unsafe extern "C" fn AVirtualMachineRawConfig_setKernel(
     config: *mut VirtualMachineRawConfig,
     fd: c_int,
-) -> c_int {
+) {
     let file = get_file_from_fd(fd);
     // SAFETY: `config` is assumed to be a valid, non-null pointer returned by
     // AVirtualMachineRawConfig_create. It's the only reference to the object.
     let config = unsafe { &mut *config };
     config.kernel = file.map(ParcelFileDescriptor::new);
-    0
 }
 
 /// Set an init rd of a virtual machine.
@@ -125,13 +137,12 @@
 pub unsafe extern "C" fn AVirtualMachineRawConfig_setInitRd(
     config: *mut VirtualMachineRawConfig,
     fd: c_int,
-) -> c_int {
+) {
     let file = get_file_from_fd(fd);
     // SAFETY: `config` is assumed to be a valid, non-null pointer returned by
     // AVirtualMachineRawConfig_create. It's the only reference to the object.
     let config = unsafe { &mut *config };
     config.initrd = file.map(ParcelFileDescriptor::new);
-    0
 }
 
 /// Add a disk for a virtual machine.
@@ -172,12 +183,11 @@
 pub unsafe extern "C" fn AVirtualMachineRawConfig_setMemoryMib(
     config: *mut VirtualMachineRawConfig,
     memory_mib: i32,
-) -> c_int {
+) {
     // SAFETY: `config` is assumed to be a valid, non-null pointer returned by
     // AVirtualMachineRawConfig_create. It's the only reference to the object.
     let config = unsafe { &mut *config };
     config.memoryMib = memory_mib;
-    0
 }
 
 /// Set whether a virtual machine is protected or not.
@@ -188,12 +198,11 @@
 pub unsafe extern "C" fn AVirtualMachineRawConfig_setProtectedVm(
     config: *mut VirtualMachineRawConfig,
     protected_vm: bool,
-) -> c_int {
+) {
     // SAFETY: `config` is assumed to be a valid, non-null pointer returned by
     // AVirtualMachineRawConfig_create. It's the only reference to the object.
     let config = unsafe { &mut *config };
     config.protectedVm = protected_vm;
-    0
 }
 
 /// Set whether a virtual machine uses memory ballooning or not.
@@ -204,12 +213,11 @@
 pub unsafe extern "C" fn AVirtualMachineRawConfig_setBalloon(
     config: *mut VirtualMachineRawConfig,
     balloon: bool,
-) -> c_int {
+) {
     // SAFETY: `config` is assumed to be a valid, non-null pointer returned by
     // AVirtualMachineRawConfig_create. It's the only reference to the object.
     let config = unsafe { &mut *config };
     config.noBalloon = !balloon;
-    0
 }
 
 /// NOT IMPLEMENTED.
@@ -232,8 +240,8 @@
 pub extern "C" fn AVirtualMachineRawConfig_addCustomMemoryBackingFile(
     _config: *mut VirtualMachineRawConfig,
     _fd: c_int,
-    _range_start: usize,
-    _range_end: usize,
+    _range_start: u64,
+    _range_end: u64,
 ) -> c_int {
     -libc::ENOTSUP
 }
@@ -360,31 +368,64 @@
     }
 }
 
-/// Wait until a virtual machine stops.
+fn death_reason_to_stop_reason(death_reason: DeathReason) -> AVirtualMachineStopReason {
+    match death_reason {
+        DeathReason::VirtualizationServiceDied => {
+            AVirtualMachineStopReason::AVIRTUAL_MACHINE_VIRTUALIZATION_SERVICE_DIED
+        }
+        DeathReason::InfrastructureError => {
+            AVirtualMachineStopReason::AVIRTUAL_MACHINE_INFRASTRUCTURE_ERROR
+        }
+        DeathReason::Killed => AVirtualMachineStopReason::AVIRTUAL_MACHINE_KILLED,
+        DeathReason::Unknown => AVirtualMachineStopReason::AVIRTUAL_MACHINE_UNKNOWN,
+        DeathReason::Shutdown => AVirtualMachineStopReason::AVIRTUAL_MACHINE_SHUTDOWN,
+        DeathReason::StartFailed => AVirtualMachineStopReason::AVIRTUAL_MACHINE_START_FAILED,
+        DeathReason::Reboot => AVirtualMachineStopReason::AVIRTUAL_MACHINE_REBOOT,
+        DeathReason::Crash => AVirtualMachineStopReason::AVIRTUAL_MACHINE_CRASH,
+        DeathReason::PvmFirmwarePublicKeyMismatch => {
+            AVirtualMachineStopReason::AVIRTUAL_MACHINE_PVM_FIRMWARE_PUBLIC_KEY_MISMATCH
+        }
+        DeathReason::PvmFirmwareInstanceImageChanged => {
+            AVirtualMachineStopReason::AVIRTUAL_MACHINE_PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED
+        }
+        DeathReason::Hangup => AVirtualMachineStopReason::AVIRTUAL_MACHINE_HANGUP,
+        _ => AVirtualMachineStopReason::AVIRTUAL_MACHINE_UNRECOGNISED,
+    }
+}
+
+/// Wait until a virtual machine stops or the timeout elapses.
 ///
 /// # Safety
-/// `vm` must be a pointer returned by `AVirtualMachine_createRaw`.
+/// `vm` must be a pointer returned by `AVirtualMachine_createRaw`. `timeout` must be a valid
+/// pointer to a `struct timespec` object or null. `reason` must be a valid, non-null pointer to an
+/// AVirtualMachineStopReason object.
 #[no_mangle]
-pub unsafe extern "C" fn AVirtualMachine_waitForStop(vm: *const VmInstance) -> StopReason {
+pub unsafe extern "C" fn AVirtualMachine_waitForStop(
+    vm: *const VmInstance,
+    timeout: *const timespec,
+    reason: *mut AVirtualMachineStopReason,
+) -> bool {
     // SAFETY: `vm` is assumed to be a valid, non-null pointer returned by
     // AVirtualMachine_create. It's the only reference to the object.
     let vm = unsafe { &*vm };
-    match vm.wait_for_death() {
-        DeathReason::VirtualizationServiceDied => StopReason::VIRTUALIZATION_SERVICE_DIED,
-        DeathReason::InfrastructureError => StopReason::INFRASTRUCTURE_ERROR,
-        DeathReason::Killed => StopReason::KILLED,
-        DeathReason::Unknown => StopReason::UNKNOWN,
-        DeathReason::Shutdown => StopReason::SHUTDOWN,
-        DeathReason::StartFailed => StopReason::START_FAILED,
-        DeathReason::Reboot => StopReason::REBOOT,
-        DeathReason::Crash => StopReason::CRASH,
-        DeathReason::PvmFirmwarePublicKeyMismatch => StopReason::PVM_FIRMWARE_PUBLIC_KEY_MISMATCH,
-        DeathReason::PvmFirmwareInstanceImageChanged => {
-            StopReason::PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED
+
+    let death_reason = if timeout.is_null() {
+        vm.wait_for_death()
+    } else {
+        // SAFETY: `timeout` is assumed to be a valid pointer to a `struct timespec` object if
+        // non-null.
+        let timeout = unsafe { &*timeout };
+        let timeout = Duration::new(timeout.tv_sec as u64, timeout.tv_nsec as u32);
+        match vm.wait_for_death_with_timeout(timeout) {
+            Some(death_reason) => death_reason,
+            None => return false,
         }
-        DeathReason::Hangup => StopReason::HANGUP,
-        _ => StopReason::UNRECOGNISED,
-    }
+    };
+
+    // SAFETY: `reason` is assumed to be a valid, non-null pointer to an
+    // AVirtualMachineStopReason object.
+    unsafe { *reason = death_reason_to_stop_reason(death_reason) };
+    true
 }
 
 /// Destroy a virtual machine.