Remove libcompos_client

CompOS APEX no longer needs to provide libcompos_client API (added
recently during T development).

Some of the code is still reusable, so the remaining code is moved to
composd/src/fd_server_helper.rs.

Bug: 205750213
Test: m
Test: atest ComposHostTestCases

Change-Id: I584b700c41ffc0e08c6ac6c171cb17ab21c7d8ff
diff --git a/compos/apex/Android.bp b/compos/apex/Android.bp
index 36e3c3e..c68899a 100644
--- a/compos/apex/Android.bp
+++ b/compos/apex/Android.bp
@@ -45,16 +45,12 @@
         "compos_verify_key",
         "composd",
         "composd_cmd",
-        "pvm_exec", // to be superseded by libcompos_client
+        "pvm_exec", // deprecated
 
         // Used in VM
         "compsvc",
     ],
 
-    native_shared_libs: [
-        "libcompos_client",
-    ],
-
     apps: [
         "CompOSPayloadApp",
     ],
diff --git a/compos/composd/Android.bp b/compos/composd/Android.bp
index a76d96c..2ab12e3 100644
--- a/compos/composd/Android.bp
+++ b/compos/composd/Android.bp
@@ -18,6 +18,8 @@
         "libbinder_rs",
         "libcompos_common",
         "libcomposd_native_rust",
+        "libminijail_rust",
+        "libnix",
         "libnum_traits",
         "liblog_rust",
         "librustutils",
diff --git a/compos/composd/src/composd_main.rs b/compos/composd/src/composd_main.rs
index f9751c3..57f64a5 100644
--- a/compos/composd/src/composd_main.rs
+++ b/compos/composd/src/composd_main.rs
@@ -19,6 +19,7 @@
 //! them, and orchestrating trusted compilation.
 
 mod compilation_task;
+mod fd_server_helper;
 mod instance_manager;
 mod instance_starter;
 mod internal_service;
diff --git a/compos/composd/src/fd_server_helper.rs b/compos/composd/src/fd_server_helper.rs
new file mode 100644
index 0000000..2dab9a3
--- /dev/null
+++ b/compos/composd/src/fd_server_helper.rs
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+//! A helper library to start a fd_server.
+//!
+//! TODO(205750213): Make it easy to spawn a fd_server.
+
+use anyhow::{Context, Result};
+use log::debug;
+use minijail::Minijail;
+use nix::fcntl::OFlag;
+use nix::unistd::pipe2;
+use std::fs::File;
+use std::io::Read;
+use std::os::unix::io::{AsRawFd, FromRawFd};
+use std::path::Path;
+
+const FD_SERVER_BIN: &str = "/apex/com.android.virt/bin/fd_server";
+
+#[allow(dead_code)]
+fn spawn_fd_server(input_fds: &[i32], output_fds: &[i32], ready_file: File) -> Result<Minijail> {
+    let mut inheritable_fds = Vec::new();
+    let mut args = vec![FD_SERVER_BIN.to_string()];
+    for fd in input_fds {
+        args.push("--ro-fds".to_string());
+        args.push(fd.to_string());
+        inheritable_fds.push(*fd);
+    }
+    for fd in output_fds {
+        args.push("--rw-fds".to_string());
+        args.push(fd.to_string());
+        inheritable_fds.push(*fd);
+    }
+    let ready_fd = ready_file.as_raw_fd();
+    args.push("--ready-fd".to_string());
+    args.push(ready_fd.to_string());
+    inheritable_fds.push(ready_fd);
+
+    let jail = Minijail::new()?;
+    let _pid = jail.run(Path::new(FD_SERVER_BIN), &inheritable_fds, &args)?;
+    Ok(jail)
+}
+
+#[allow(dead_code)]
+fn create_pipe() -> Result<(File, File)> {
+    let (raw_read, raw_write) = pipe2(OFlag::O_CLOEXEC)?;
+    // SAFETY: We are the sole owners of these fds as they were just created.
+    let read_fd = unsafe { File::from_raw_fd(raw_read) };
+    let write_fd = unsafe { File::from_raw_fd(raw_write) };
+    Ok((read_fd, write_fd))
+}
+
+#[allow(dead_code)]
+fn wait_for_fd_server_ready(mut ready_fd: File) -> Result<()> {
+    let mut buffer = [0];
+    // When fd_server is ready it closes its end of the pipe. And if it exits, the pipe is also
+    // closed. Either way this read will return 0 bytes at that point, and there's no point waiting
+    // any longer.
+    let _ = ready_fd.read(&mut buffer).context("Waiting for fd_server to be ready")?;
+    debug!("fd_server is ready");
+    Ok(())
+}
diff --git a/compos/libcompos_client/Android.bp b/compos/libcompos_client/Android.bp
deleted file mode 100644
index db6294e..0000000
--- a/compos/libcompos_client/Android.bp
+++ /dev/null
@@ -1,58 +0,0 @@
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-cc_library {
-    name: "libcompos_client",
-    whole_static_libs: ["libcompos_client_ffi"],
-    min_sdk_version: "apex_inherit",
-    shared_libs: [
-        "libbinder_ndk",
-        "libbinder_rpc_unstable",
-        "libminijail",
-    ],
-    export_include_dirs: ["include"],
-    stubs: {
-        symbol_file: "libcompos_client.map.txt",
-    },
-    apex_available: [
-        "com.android.compos",
-    ],
-    visibility: [
-        "//packages/modules/Virtualization/compos:__subpackages__",
-        "//art/odrefresh:__subpackages__",
-    ],
-}
-
-// TODO(203478530): Once rust_ffi supports stubs/symbol file, remove the wrapping cc_library above.
-rust_ffi {
-    name: "libcompos_client_ffi",
-    crate_name: "compos_client_ffi",
-    srcs: ["libcompos_client.rs"],
-    include_dirs: ["include"],
-    rustlibs: [
-        "android.system.composd.internal-rust",
-        "compos_aidl_interface-rust",
-        "libandroid_logger",
-        "libanyhow",
-        "libbinder_common",
-        "libbinder_rs",
-        "libcompos_common",
-        "liblibc",
-        "liblog_rust",
-        "libminijail_rust",
-        "libnix",
-        "libscopeguard",
-    ],
-    prefer_rlib: true,
-    shared_libs: [
-        "libbinder_ndk",
-    ],
-    apex_available: [
-        "com.android.compos",
-    ],
-    visibility: [
-        "//packages/modules/Virtualization/compos:__subpackages__",
-        "//art/odrefresh:__subpackages__",
-    ],
-}
diff --git a/compos/libcompos_client/include/libcompos_client.h b/compos/libcompos_client/include/libcompos_client.h
deleted file mode 100644
index 171854d..0000000
--- a/compos/libcompos_client/include/libcompos_client.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-/**
- * Sends request encoded in a marshaled byte buffer to the Compilation OS service, which will
- * execute the compiler with context encoded in the marshaled byte buffer.
- *
- * @param cid the VM's cid to send the request to.
- * @param marshaled pointer to a marshaled byte buffer.
- * @param size size of the marshaled byte buffer pointed by `marshaled`.
- * @param ro_fds pointer to a int array of read-only file descriptor numbers.
- * @param ro_fds_num size of the array pointed by `ro_fds`.
- * @param rw_fds pointer to a int array of read-writable file descriptor numbers.
- * @param rw_fds_num size of the array pointed by `rw_fds`.
- * @return the exit code of the compiler.
- *
- * Available since API level 33.
- */
-int AComposClient_Request(int cid, const uint8_t* marshaled, size_t size, const int* ro_fds,
-                          size_t ro_fds_num, const int* rw_fds, size_t rw_fds_num)
-        __INTRODUCED_IN(33);
-
-__END_DECLS
diff --git a/compos/libcompos_client/libcompos_client.map.txt b/compos/libcompos_client/libcompos_client.map.txt
deleted file mode 100644
index 9d47c53..0000000
--- a/compos/libcompos_client/libcompos_client.map.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-LIBCOMPOS_CLIENT {
-    global:
-        AComposClient_Request; # apex
-    local:
-        *;
-};
diff --git a/compos/libcompos_client/libcompos_client.rs b/compos/libcompos_client/libcompos_client.rs
deleted file mode 100644
index 701e515..0000000
--- a/compos/libcompos_client/libcompos_client.rs
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-//! A library for a client to send requests to the CompOS service in the VM.
-
-use anyhow::{Context, Result};
-use binder_common::rpc_client::connect_rpc_binder;
-use libc::c_int;
-use log::{debug, error, warn};
-use minijail::Minijail;
-use nix::fcntl::OFlag;
-use nix::unistd::pipe2;
-use std::fs::File;
-use std::io::Read;
-use std::os::unix::io::{AsRawFd, FromRawFd};
-use std::path::Path;
-use std::slice::from_raw_parts;
-
-use android_system_composd_internal::{
-    aidl::android::system::composd::internal::ICompilationInternal::ICompilationInternal,
-    binder::wait_for_interface,
-};
-use compos_aidl_interface::aidl::com::android::compos::{
-    FdAnnotation::FdAnnotation, ICompOsService::ICompOsService,
-};
-use compos_aidl_interface::binder::Strong;
-use compos_common::{COMPOS_VSOCK_PORT, VMADDR_CID_ANY};
-
-const FD_SERVER_BIN: &str = "/apex/com.android.virt/bin/fd_server";
-
-fn get_composd() -> Result<Strong<dyn ICompilationInternal>> {
-    wait_for_interface::<dyn ICompilationInternal>("android.system.composd.internal")
-        .context("Failed to find ICompilationInternal")
-}
-
-fn spawn_fd_server(fd_annotation: &FdAnnotation, ready_file: File) -> Result<Minijail> {
-    let mut inheritable_fds = Vec::new();
-    let mut args = vec![FD_SERVER_BIN.to_string()];
-    for fd in &fd_annotation.input_fds {
-        args.push("--ro-fds".to_string());
-        args.push(fd.to_string());
-        inheritable_fds.push(*fd);
-    }
-    for fd in &fd_annotation.output_fds {
-        args.push("--rw-fds".to_string());
-        args.push(fd.to_string());
-        inheritable_fds.push(*fd);
-    }
-    let ready_fd = ready_file.as_raw_fd();
-    args.push("--ready-fd".to_string());
-    args.push(ready_fd.to_string());
-    inheritable_fds.push(ready_fd);
-
-    let jail = Minijail::new()?;
-    let _pid = jail.run(Path::new(FD_SERVER_BIN), &inheritable_fds, &args)?;
-    Ok(jail)
-}
-
-fn create_pipe() -> Result<(File, File)> {
-    let (raw_read, raw_write) = pipe2(OFlag::O_CLOEXEC)?;
-    // SAFETY: We are the sole owners of these fds as they were just created.
-    let read_fd = unsafe { File::from_raw_fd(raw_read) };
-    let write_fd = unsafe { File::from_raw_fd(raw_write) };
-    Ok((read_fd, write_fd))
-}
-
-fn wait_for_fd_server_ready(mut ready_fd: File) -> Result<()> {
-    let mut buffer = [0];
-    // When fd_server is ready it closes its end of the pipe. And if it exits, the pipe is also
-    // closed. Either way this read will return 0 bytes at that point, and there's no point waiting
-    // any longer.
-    let _ = ready_fd.read(&mut buffer).context("Waiting for fd_server to be ready")?;
-    debug!("fd_server is ready");
-    Ok(())
-}
-
-fn try_request(cid: c_int, marshaled: &[u8], fd_annotation: FdAnnotation) -> Result<c_int> {
-    // 1. Spawn a fd_server to serve remote read/write requests.
-    let (ready_read_fd, ready_write_fd) = create_pipe()?;
-    let fd_server_jail = spawn_fd_server(&fd_annotation, ready_write_fd)?;
-    let fd_server_lifetime = scopeguard::guard(fd_server_jail, |fd_server_jail| {
-        if let Err(e) = fd_server_jail.kill() {
-            if !matches!(e, minijail::Error::Killed(_)) {
-                warn!("Failed to kill fd_server: {}", e);
-            }
-        }
-    });
-
-    // 2. Send the marshaled request the remote.
-    let cid = cid as u32;
-    let result = if cid == VMADDR_CID_ANY {
-        // Sentinel value that indicates we should use composd
-        let composd = get_composd()?;
-        wait_for_fd_server_ready(ready_read_fd)?;
-        composd.compile(marshaled, &fd_annotation)
-    } else {
-        // Call directly into the VM
-        let compos_vm = connect_rpc_binder::<dyn ICompOsService>(cid, COMPOS_VSOCK_PORT)
-            .context("Cannot connect to RPC binder")?;
-        wait_for_fd_server_ready(ready_read_fd)?;
-        compos_vm.compile(marshaled, &fd_annotation)
-    };
-    let result = result.context("Binder call failed")?;
-
-    // Be explicit about the lifetime, which should last at least until the task is finished.
-    drop(fd_server_lifetime);
-
-    Ok(c_int::from(result))
-}
-
-/// A public C API. See libcompos_client.h for the canonical doc.
-///
-/// # Safety
-///
-/// The client must provide legitimate pointers with correct sizes to the backing arrays.
-#[no_mangle]
-pub unsafe extern "C" fn AComposClient_Request(
-    cid: c_int,
-    marshaled: *const u8,
-    size: usize,
-    ro_fds: *const c_int,
-    ro_fds_num: usize,
-    rw_fds: *const c_int,
-    rw_fds_num: usize,
-) -> c_int {
-    if marshaled.is_null() || ro_fds.is_null() || rw_fds.is_null() {
-        error!("Argument pointers should not be null");
-        return -1;
-    }
-
-    // The unsafe parts.
-    let ro_fd_slice = from_raw_parts(ro_fds, ro_fds_num);
-    let rw_fd_slice = from_raw_parts(rw_fds, rw_fds_num);
-    let marshaled_slice = from_raw_parts(marshaled, size);
-
-    let fd_annotation =
-        FdAnnotation { input_fds: ro_fd_slice.to_vec(), output_fds: rw_fd_slice.to_vec() };
-
-    match try_request(cid, marshaled_slice, fd_annotation) {
-        Ok(exit_code) => exit_code,
-        Err(e) => {
-            error!("AComposClient_Request failed: {:?}", e);
-            -1
-        }
-    }
-}