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,
         }
     }