98 lines
3.4 KiB
Rust
98 lines
3.4 KiB
Rust
/*
|
|
* Copyright (C) 2020 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.
|
|
*/
|
|
|
|
//! Rust Binder NDK interop tests
|
|
|
|
use ::IBinderRustNdkInteropTest::aidl::IBinderRustNdkInteropTest::{
|
|
BnBinderRustNdkInteropTest, IBinderRustNdkInteropTest,
|
|
};
|
|
use ::IBinderRustNdkInteropTest::aidl::IBinderRustNdkInteropTestOther::IBinderRustNdkInteropTestOther;
|
|
use ::IBinderRustNdkInteropTest::binder::{self, BinderFeatures, Interface, StatusCode};
|
|
use std::ffi::CStr;
|
|
use std::os::raw::{c_char, c_int};
|
|
|
|
/// Look up the provided AIDL service and call its echo method.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// service_name must be a valid, non-null C-style string (null-terminated).
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn rust_call_ndk(service_name: *const c_char) -> c_int {
|
|
let service_name = CStr::from_ptr(service_name).to_str().unwrap();
|
|
|
|
// The Rust class descriptor pointer will not match the NDK one, but the
|
|
// descriptor strings match so this needs to still associate.
|
|
let service: binder::Strong<dyn 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(),
|
|
}
|
|
|
|
// Try using the binder service through the wrong interface type
|
|
let wrong_service: Result<binder::Strong<dyn IBinderRustNdkInteropTestOther>, StatusCode> =
|
|
binder::get_interface(service_name);
|
|
match wrong_service {
|
|
Err(e) if e == 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 IBinderRustNdkInteropTest for Service {
|
|
fn echo(&self, s: &str) -> binder::Result<String> {
|
|
Ok(s.to_string())
|
|
}
|
|
}
|
|
|
|
/// Start the interop Echo test service with the given service name.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// service_name must be a valid, non-null C-style string (null-terminated).
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn rust_start_service(service_name: *const c_char) -> c_int {
|
|
let service_name = CStr::from_ptr(service_name).to_str().unwrap();
|
|
let service = 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,
|
|
}
|
|
}
|