Move VM callback to vmclient
Instead of having clients directly register a callback with VS,
implement a Rust level callback interface in vmclient. This saves an
extra binder call on each notification, a bunch of boilerplate code,
and allows us to provide a slightly better interface (e.g. we can use
the Rust DeathReason enum, as elsewhere in vmclient, for instantly
better logging).
I also replaced all our usages of <some_interface>::binder::{...} with
direct access to binder::{...}. That makes it clearer what depends on
the interface itself and what is just generic binder code. I realise
this should be a separate change, but I only realised that after doing
bits of both.
Test: composd_cmd test-compile, observe logs (on both success & failure)
Test: atest -b (to make sure all our tests build)
Test: Presubmits
Change-Id: Iceda8d7b8f8008f9d7a2c51106c2794f09bb378e
diff --git a/vm/Android.bp b/vm/Android.bp
index 2b83ca7..f9eac4d 100644
--- a/vm/Android.bp
+++ b/vm/Android.bp
@@ -11,6 +11,7 @@
rustlibs: [
"android.system.virtualizationservice-rust",
"libanyhow",
+ "libbinder_rs",
"libenv_logger",
"liblibc",
"liblog_rust",
diff --git a/vm/src/create_idsig.rs b/vm/src/create_idsig.rs
index fe7cd82..9a66228 100644
--- a/vm/src/create_idsig.rs
+++ b/vm/src/create_idsig.rs
@@ -15,7 +15,7 @@
//! Command to create or update an idsig for APK
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::IVirtualizationService::IVirtualizationService;
-use android_system_virtualizationservice::binder::ParcelFileDescriptor;
+use binder::ParcelFileDescriptor;
use anyhow::{Context, Error};
use std::fs::{File, OpenOptions};
use std::path::Path;
diff --git a/vm/src/create_partition.rs b/vm/src/create_partition.rs
index 049c201..affa28e 100644
--- a/vm/src/create_partition.rs
+++ b/vm/src/create_partition.rs
@@ -16,7 +16,7 @@
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::IVirtualizationService::IVirtualizationService;
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::PartitionType::PartitionType;
-use android_system_virtualizationservice::binder::ParcelFileDescriptor;
+use binder::ParcelFileDescriptor;
use anyhow::{Context, Error};
use std::convert::TryInto;
use std::fs::OpenOptions;
diff --git a/vm/src/main.rs b/vm/src/main.rs
index 60786ac..c421b04 100644
--- a/vm/src/main.rs
+++ b/vm/src/main.rs
@@ -22,8 +22,8 @@
IVirtualizationService::IVirtualizationService, PartitionType::PartitionType,
VirtualMachineAppConfig::DebugLevel::DebugLevel,
};
-use android_system_virtualizationservice::binder::ProcessState;
use anyhow::{Context, Error};
+use binder::ProcessState;
use create_idsig::command_create_idsig;
use create_partition::command_create_partition;
use run::{command_run, command_run_app};
diff --git a/vm/src/run.rs b/vm/src/run.rs
index 44eb27a..9bd7863 100644
--- a/vm/src/run.rs
+++ b/vm/src/run.rs
@@ -16,19 +16,13 @@
use crate::create_partition::command_create_partition;
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
- DeathReason::DeathReason,
- IVirtualMachineCallback::{BnVirtualMachineCallback, IVirtualMachineCallback},
- IVirtualizationService::IVirtualizationService,
- PartitionType::PartitionType,
+ IVirtualizationService::IVirtualizationService, PartitionType::PartitionType,
VirtualMachineAppConfig::DebugLevel::DebugLevel,
- VirtualMachineAppConfig::VirtualMachineAppConfig,
- VirtualMachineConfig::VirtualMachineConfig,
+ VirtualMachineAppConfig::VirtualMachineAppConfig, VirtualMachineConfig::VirtualMachineConfig,
VirtualMachineState::VirtualMachineState,
};
-use android_system_virtualizationservice::binder::{
- BinderFeatures, Interface, ParcelFileDescriptor, Result as BinderResult,
-};
use anyhow::{bail, Context, Error};
+use binder::ParcelFileDescriptor;
use microdroid_payload_config::VmPayloadConfig;
use std::fs::File;
use std::io::{self, BufRead, BufReader};
@@ -197,10 +191,9 @@
Some(duplicate_stdout()?)
};
- let vm = VmInstance::create(service, config, console, log).context("Failed to create VM")?;
- let callback =
- BnVirtualMachineCallback::new_binder(VirtualMachineCallback {}, BinderFeatures::default());
- vm.vm.registerCallback(&callback)?;
+ let callback = Box::new(Callback {});
+ let vm = VmInstance::create(service, config, console, log, Some(callback))
+ .context("Failed to create VM")?;
vm.start().context("Failed to start VM")?;
println!(
@@ -246,20 +239,13 @@
Ok(config.extra_apks.into_iter().map(|x| x.path).collect())
}
-#[derive(Debug)]
-struct VirtualMachineCallback {}
+struct Callback {}
-impl Interface for VirtualMachineCallback {}
-
-impl IVirtualMachineCallback for VirtualMachineCallback {
- fn onPayloadStarted(
- &self,
- _cid: i32,
- stream: Option<&ParcelFileDescriptor>,
- ) -> BinderResult<()> {
+impl vmclient::VmCallback for Callback {
+ fn on_payload_started(&self, _cid: i32, stream: Option<&File>) {
// Show the output of the payload
if let Some(stream) = stream {
- let mut reader = BufReader::new(stream.as_ref());
+ let mut reader = BufReader::new(stream);
loop {
let mut s = String::new();
match reader.read_line(&mut s) {
@@ -269,31 +255,18 @@
};
}
}
- Ok(())
}
- fn onPayloadReady(&self, _cid: i32) -> BinderResult<()> {
+ fn on_payload_ready(&self, _cid: i32) {
eprintln!("payload is ready");
- Ok(())
}
- fn onPayloadFinished(&self, _cid: i32, exit_code: i32) -> BinderResult<()> {
+ fn on_payload_finished(&self, _cid: i32, exit_code: i32) {
eprintln!("payload finished with exit code {}", exit_code);
- Ok(())
}
- fn onError(&self, _cid: i32, error_code: i32, message: &str) -> BinderResult<()> {
+ fn on_error(&self, _cid: i32, error_code: i32, message: &str) {
eprintln!("VM encountered an error: code={}, message={}", error_code, message);
- Ok(())
- }
-
- fn onRamdump(&self, _cid: i32, _stream: &ParcelFileDescriptor) -> BinderResult<()> {
- // Do nothing. We get ramdump from the vmclient library.
- Ok(())
- }
-
- fn onDied(&self, _cid: i32, _reason: DeathReason) -> BinderResult<()> {
- Ok(())
}
}