use ::IBinderRustNdkInteropTest::aidl::IBinderRustNdkInteropTest as Iface;
use ::IBinderRustNdkInteropTest::aidl::IBinderRustNdkInteropTestOther::IBinderRustNdkInteropTestOther;
use ::IBinderRustNdkInteropTest::binder::{self, BinderFeatures, Interface, StatusCode};
use std::ffi::CStr;
use std::os::raw::{c_char, c_int};
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust_call_ndk(service_name: *const c_char) -> c_int {
let service_name = unsafe { CStr::from_ptr(service_name) }.to_str().unwrap();
let service: binder::Strong<dyn Iface::IBinderRustNdkInteropTest> =
match binder::get_interface(service_name) {
Err(e) => {
eprintln!("Could not find Ndk service {}: {:?}", service_name, e);
return StatusCode::NAME_NOT_FOUND as c_int;
}
Ok(service) => service,
};
match service.echo("testing") {
Ok(s) => {
if s != "testing" {
return StatusCode::BAD_VALUE as c_int;
}
}
Err(e) => return e.into(),
}
let wrong_service: Result<binder::Strong<dyn IBinderRustNdkInteropTestOther>, StatusCode> =
binder::get_interface(service_name);
match wrong_service {
Err(StatusCode::BAD_TYPE) => {}
Err(e) => {
eprintln!("Trying to use a service via the wrong interface errored with unexpected error {:?}", e);
return e as c_int;
}
Ok(_) => {
eprintln!("We should not be allowed to use a service via the wrong interface");
return StatusCode::BAD_TYPE as c_int;
}
}
StatusCode::OK as c_int
}
struct Service;
impl Interface for Service {}
impl Iface::IBinderRustNdkInteropTest for Service {
fn echo(&self, s: &str) -> binder::Result<String> {
Ok(s.to_string())
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust_start_service(service_name: *const c_char) -> c_int {
let service_name = unsafe { CStr::from_ptr(service_name) }.to_str().unwrap();
let service = Iface::BnBinderRustNdkInteropTest::new_binder(Service, BinderFeatures::default());
match binder::add_service(service_name, service.as_binder()) {
Ok(_) => StatusCode::OK as c_int,
Err(e) => e as c_int,
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rust_test_get_function_name() -> c_int {
let service = Iface::BnBinderRustNdkInteropTest::new_binder(Service, BinderFeatures::default());
let code = Iface::transactions::r#echo;
let mut binder = service.as_binder();
let class = binder.get_class().unwrap();
let name = unsafe { binder_rs_ndk_compat::get_function_name(class.into(), code) };
if name.is_null() {
eprintln!("Transaction name for code {} not found", code);
return StatusCode::BAD_VALUE as c_int;
}
let name_str = unsafe { CStr::from_ptr(name) }.to_str().unwrap();
if name_str != "echo" {
eprintln!("Expected transaction name 'echo', but got '{}'", name_str);
return StatusCode::BAD_VALUE as c_int;
}
StatusCode::OK as c_int
}