Add setDisplayService and waitDisplayService in IVirtualizationServiceInternal
In normal app context, it cannot add a service into service manager, so
add something similar into VirtualizationServiceInternal.
Bug: 331708504
Test: check if the display shows
Change-Id: I895e6a8affe3bc4e9de6bea226ebc40a7fcf7a0d
diff --git a/libs/android_display_backend/Android.bp b/libs/android_display_backend/Android.bp
index f818951..6ad5fab 100644
--- a/libs/android_display_backend/Android.bp
+++ b/libs/android_display_backend/Android.bp
@@ -37,11 +37,12 @@
srcs: [
"crosvm_android_display_client.cpp",
],
- stl: "libc++_static",
whole_static_libs: [
"libcrosvm_android_display_service-ndk",
+ "android.system.virtualizationservice_internal-ndk",
+ "android.system.virtualizationcommon-ndk",
+ "android.system.virtualizationservice-ndk",
"libyuv",
- "libc++_static",
],
shared_libs: [
"libbinder_ndk",
diff --git a/libs/android_display_backend/crosvm_android_display_client.cpp b/libs/android_display_backend/crosvm_android_display_client.cpp
index 91412af..6737453 100644
--- a/libs/android_display_backend/crosvm_android_display_client.cpp
+++ b/libs/android_display_backend/crosvm_android_display_client.cpp
@@ -15,6 +15,7 @@
*/
#include <aidl/android/crosvm/BnCrosvmAndroidDisplayService.h>
+#include <aidl/android/system/virtualizationservice_internal/IVirtualizationServiceInternal.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <android/native_window.h>
@@ -28,6 +29,8 @@
#include <mutex>
#include <vector>
+using aidl::android::system::virtualizationservice_internal::IVirtualizationServiceInternal;
+
#define LIBEXPORT __attribute__((visibility("default"))) extern "C"
typedef void (*android_display_log_callback_type)(const char* message);
@@ -104,9 +107,16 @@
strlen(name));
return nullptr;
}
+ ::ndk::SpAIBinder binder(
+ AServiceManager_waitForService("android.system.virtualizationservice"));
- auto status = AServiceManager_addService(service->asBinder().get(), name);
- if (status != STATUS_OK) {
+ auto virt_service = IVirtualizationServiceInternal::fromBinder(binder);
+ if (virt_service == nullptr) {
+ ErrorF(error_callback, "Failed to find android.system.virtualizationservice");
+ return nullptr;
+ }
+ auto status = virt_service->setDisplayService(service->asBinder());
+ if (!status.isOk()) {
ErrorF(error_callback, "Failed to register %s",
aidl::android::crosvm::ICrosvmAndroidDisplayService::descriptor);
return nullptr;
diff --git a/virtualizationservice/aidl/Android.bp b/virtualizationservice/aidl/Android.bp
index 112e1cc..c479691 100644
--- a/virtualizationservice/aidl/Android.bp
+++ b/virtualizationservice/aidl/Android.bp
@@ -12,7 +12,10 @@
backend: {
java: {
sdk_version: "module_current",
- apex_available: ["com.android.virt"],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.virt",
+ ],
},
cpp: {
enabled: true,
@@ -44,6 +47,9 @@
backend: {
java: {
sdk_version: "module_current",
+ apex_available: [
+ "//apex_available:platform",
+ ],
},
rust: {
enabled: true,
@@ -51,6 +57,11 @@
"com.android.virt",
],
},
+ ndk: {
+ apex_available: [
+ "com.android.virt",
+ ],
+ },
},
}
@@ -103,7 +114,10 @@
backend: {
java: {
sdk_version: "module_current",
- apex_available: ["com.android.virt"],
+ apex_available: [
+ "com.android.virt",
+ "//apex_available:platform",
+ ],
},
ndk: {
apex_available: [
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVirtualizationServiceInternal.aidl b/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVirtualizationServiceInternal.aidl
index 16975ee..65806da 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVirtualizationServiceInternal.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVirtualizationServiceInternal.aidl
@@ -116,4 +116,8 @@
* @param instanceId The ID for the VM.
*/
void claimVmInstance(in byte[64] instanceId);
+
+ // TODO(b/330257000): Remove these functions when a display service is running with binder RPC.
+ void setDisplayService(IBinder ibinder);
+ IBinder waitDisplayService();
}
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index c6150b2..9258b82 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -51,7 +51,7 @@
use std::os::unix::fs::PermissionsExt;
use std::os::unix::raw::{pid_t, uid_t};
use std::path::{Path, PathBuf};
-use std::sync::{Arc, Mutex, Weak};
+use std::sync::{Arc, Condvar, Mutex, Weak};
use tombstoned_client::{DebuggerdDumpType, TombstonedConnection};
use virtualizationcommon::Certificate::Certificate;
use virtualizationmaintenance::{
@@ -170,12 +170,15 @@
#[derive(Clone)]
pub struct VirtualizationServiceInternal {
state: Arc<Mutex<GlobalState>>,
+ display_service_set: Arc<Condvar>,
}
impl VirtualizationServiceInternal {
pub fn init() -> VirtualizationServiceInternal {
- let service =
- VirtualizationServiceInternal { state: Arc::new(Mutex::new(GlobalState::new())) };
+ let service = VirtualizationServiceInternal {
+ state: Arc::new(Mutex::new(GlobalState::new())),
+ display_service_set: Arc::new(Condvar::new()),
+ };
std::thread::spawn(|| {
if let Err(e) = handle_stream_connection_tombstoned() {
@@ -190,6 +193,30 @@
impl Interface for VirtualizationServiceInternal {}
impl IVirtualizationServiceInternal for VirtualizationServiceInternal {
+ fn setDisplayService(
+ &self,
+ ibinder: &binder::SpIBinder,
+ ) -> std::result::Result<(), binder::Status> {
+ check_manage_access()?;
+ check_use_custom_virtual_machine()?;
+ let state = &mut *self.state.lock().unwrap();
+ state.display_service = Some(ibinder.clone());
+ self.display_service_set.notify_all();
+ Ok(())
+ }
+
+ fn waitDisplayService(&self) -> std::result::Result<binder::SpIBinder, binder::Status> {
+ check_manage_access()?;
+ check_use_custom_virtual_machine()?;
+ let state = self
+ .display_service_set
+ .wait_while(self.state.lock().unwrap(), |state| state.display_service.is_none())
+ .unwrap();
+ Ok((state.display_service)
+ .as_ref()
+ .cloned()
+ .expect("Display service cannot be None in this context"))
+ }
fn removeMemlockRlimit(&self) -> binder::Result<()> {
let pid = get_calling_pid();
let lim = libc::rlimit { rlim_cur: libc::RLIM_INFINITY, rlim_max: libc::RLIM_INFINITY };
@@ -588,6 +615,8 @@
/// State relating to secrets held by (optional) Secretkeeper instance on behalf of VMs.
sk_state: Option<maintenance::State>,
+
+ display_service: Option<binder::SpIBinder>,
}
impl GlobalState {
@@ -596,6 +625,7 @@
held_contexts: HashMap::new(),
dtbo_file: Mutex::new(None),
sk_state: maintenance::State::new(),
+ display_service: None,
}
}