[API] Add new service to notify host from microdroid manager

This CL adds a new service to notify the host from
microdroid manager instead of the payload process.

Bug: 243512047
Test: MicrodroidTests microdroid_manager_test
Change-Id: Ic634944f6dd5266c084f495787bf4568a4d18ed3
diff --git a/microdroid/vm_payload/Android.bp b/microdroid/vm_payload/Android.bp
index 0424fc1..4f893d6 100644
--- a/microdroid/vm_payload/Android.bp
+++ b/microdroid/vm_payload/Android.bp
@@ -9,11 +9,10 @@
     include_dirs: ["include"],
     prefer_rlib: true,
     rustlibs: [
-        "android.system.virtualmachineservice-rust",
+        "android.system.virtualization.payload-rust",
         "libandroid_logger",
         "libanyhow",
         "libbinder_rs",
         "liblog_rust",
-        "librpcbinder_rs",
     ],
 }
diff --git a/microdroid/vm_payload/src/vm_service.rs b/microdroid/vm_payload/src/vm_service.rs
index e5a6b9a..a8f980a 100644
--- a/microdroid/vm_payload/src/vm_service.rs
+++ b/microdroid/vm_payload/src/vm_service.rs
@@ -12,17 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-//! This module handles the interaction with virtual machine service.
+//! This module handles the interaction with virtual machine payload service.
 
-use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::{
-    VM_BINDER_SERVICE_PORT, IVirtualMachineService};
+use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::IVmPayloadService;
 use anyhow::{Context, Result};
-use binder::Strong;
+use binder::{wait_for_interface, Strong};
 use log::{error, info, Level};
-use rpcbinder::get_vsock_rpc_interface;
 
 /// The CID representing the host VM
-const VMADDR_CID_HOST: u32 = 2;
+const VM_PAYLOAD_SERVICE_NAME: &str = "virtual_machine_payload_service";
 
 /// Notifies the host that the payload is ready.
 /// Returns true if the notification succeeds else false.
@@ -43,10 +41,10 @@
 /// Notifies the host that the payload is ready.
 /// Returns a `Result` containing error information if failed.
 fn try_notify_payload_ready() -> Result<()> {
-    get_vm_service()?.notifyPayloadReady().context("Cannot notify payload ready")
+    get_vm_payload_service()?.notifyPayloadReady().context("Cannot notify payload ready")
 }
 
-fn get_vm_service() -> Result<Strong<dyn IVirtualMachineService>> {
-    get_vsock_rpc_interface(VMADDR_CID_HOST, VM_BINDER_SERVICE_PORT as u32)
-        .context("Connecting to IVirtualMachineService")
+fn get_vm_payload_service() -> Result<Strong<dyn IVmPayloadService>> {
+    wait_for_interface(VM_PAYLOAD_SERVICE_NAME)
+        .context(format!("Failed to connect to service: {}", VM_PAYLOAD_SERVICE_NAME))
 }
diff --git a/microdroid_manager/Android.bp b/microdroid_manager/Android.bp
index 67130b4..b281d5c 100644
--- a/microdroid_manager/Android.bp
+++ b/microdroid_manager/Android.bp
@@ -14,6 +14,7 @@
         "android.system.virtualizationcommon-rust",
         "android.system.virtualizationservice-rust",
         "android.system.virtualmachineservice-rust",
+        "android.system.virtualization.payload-rust",
         "libanyhow",
         "libapexutil_rust",
         "libapkverify",
diff --git a/microdroid_manager/aidl/Android.bp b/microdroid_manager/aidl/Android.bp
new file mode 100644
index 0000000..98ce6f5
--- /dev/null
+++ b/microdroid_manager/aidl/Android.bp
@@ -0,0 +1,17 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aidl_interface {
+    name: "android.system.virtualization.payload",
+    srcs: ["android/system/virtualization/payload/*.aidl"],
+    unstable: true,
+    backend: {
+        rust: {
+            enabled: true,
+            apex_available: [
+                "com.android.virt",
+            ],
+        },
+    },
+}
diff --git a/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl b/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
new file mode 100644
index 0000000..4ae686b
--- /dev/null
+++ b/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.virtualization.payload;
+
+/**
+ * This interface regroups the tasks that payloads delegate to
+ * Microdroid Manager for execution.
+ */
+interface IVmPayloadService {
+    /** Notifies that the payload is ready to serve. */
+    void notifyPayloadReady();
+}
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index b4b2c8b..1349ede 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -17,8 +17,10 @@
 mod instance;
 mod ioutil;
 mod payload;
+mod vm_payload_service;
 
 use crate::instance::{ApexData, ApkData, InstanceDisk, MicrodroidData, RootHash};
+use crate::vm_payload_service::register_vm_payload_service;
 use android_hardware_security_dice::aidl::android::hardware::security::dice::{
     Config::Config, InputValues::InputValues, Mode::Mode,
 };
@@ -29,7 +31,7 @@
 };
 use anyhow::{anyhow, bail, ensure, Context, Error, Result};
 use apkverify::{get_public_key_der, verify, V4Signature};
-use binder::{wait_for_interface, Strong};
+use binder::{ProcessState, wait_for_interface, Strong};
 use diced_utils::cbor::{encode_header, encode_number};
 use glob::glob;
 use itertools::sorted;
@@ -386,6 +388,8 @@
     }
 
     system_properties::write("dev.bootcomplete", "1").context("set dev.bootcomplete")?;
+    register_vm_payload_service(service.clone())?;
+    ProcessState::start_thread_pool();
     exec_task(task, service)
 }
 
diff --git a/microdroid_manager/src/vm_payload_service.rs b/microdroid_manager/src/vm_payload_service.rs
new file mode 100644
index 0000000..6eb3240
--- /dev/null
+++ b/microdroid_manager/src/vm_payload_service.rs
@@ -0,0 +1,56 @@
+// Copyright 2022, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Implementation of the AIDL interface `IVmPayloadService`.
+
+use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::{BnVmPayloadService, IVmPayloadService};
+use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::IVirtualMachineService;
+use anyhow::{Context, Result};
+use binder::{Interface, BinderFeatures, Strong, add_service};
+
+const VM_PAYLOAD_SERVICE_NAME: &str = "virtual_machine_payload_service";
+
+/// Implementation of `IVmPayloadService`.
+struct VmPayloadService {
+    virtual_machine_service: Strong<dyn IVirtualMachineService>,
+}
+
+impl IVmPayloadService for VmPayloadService {
+    fn notifyPayloadReady(&self) -> binder::Result<()> {
+        self.virtual_machine_service.notifyPayloadReady()
+    }
+}
+
+impl Interface for VmPayloadService {}
+
+impl VmPayloadService {
+    /// Creates a new `VmPayloadService` instance from the `IVirtualMachineService` reference.
+    fn new(vm_service: Strong<dyn IVirtualMachineService>) -> Self {
+        Self { virtual_machine_service: vm_service }
+    }
+}
+
+/// Registers the `IVmPayloadService` service.
+pub(crate) fn register_vm_payload_service(
+    vm_service: Strong<dyn IVirtualMachineService>,
+) -> Result<()> {
+    let vm_payload_binder = BnVmPayloadService::new_binder(
+        VmPayloadService::new(vm_service),
+        BinderFeatures::default(),
+    );
+    add_service(VM_PAYLOAD_SERVICE_NAME, vm_payload_binder.as_binder())
+        .with_context(|| format!("Failed to register service {}", VM_PAYLOAD_SERVICE_NAME))?;
+    log::info!("{} is running", VM_PAYLOAD_SERVICE_NAME);
+    Ok(())
+}