//! This module implements the ITestAidlMsgQ AIDL interface /* * Copyright (C) 2024 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. */ use android_fmq_test::aidl::android::fmq::test::ITestAidlMsgQ::ITestAidlMsgQ; use android_fmq_test::binder::{self, Interface, Result as BinderResult}; /// Struct implementing the ITestAidlMsgQ AIDL interface #[derive(Default)] pub struct MsgQTestService { queue_sync: std::sync::Mutex>>, } impl Interface for MsgQTestService {} use android_hardware_common_fmq::aidl::android::hardware::common::fmq::{ MQDescriptor::MQDescriptor, SynchronizedReadWrite::SynchronizedReadWrite, UnsynchronizedWrite::UnsynchronizedWrite, }; impl ITestAidlMsgQ for MsgQTestService { /** * This method requests the service to set up a synchronous read/write * wait-free FMQ using the input descriptor with the client as reader. * * @param mqDesc This structure describes the FMQ that was set up by the * client. Server uses this descriptor to set up a FMQ object at its end. * * @return True if the setup is successful. */ fn configureFmqSyncReadWrite( &self, mq_desc: &MQDescriptor, ) -> BinderResult { *self.queue_sync.lock().unwrap() = Some(fmq::MessageQueue::from_desc(mq_desc, false)); /* TODO(b/339999649) in C++ we set the EventFlag word with bit FMQ_NOT_FULL: */ /*auto evFlagWordPtr = mFmqSynchronized->getEventFlagWord(); if (evFlagWordPtr != nullptr) { std::atomic_init(evFlagWordPtr, static_cast(EventFlagBits::FMQ_NOT_FULL)); }*/ Ok(true) } /** * This method requests the service to read from the synchronized read/write * FMQ. * * @param count Number to messages to read. * * @return True if the read operation was successful. */ fn requestReadFmqSync(&self, count: i32) -> BinderResult { let mut queue_guard = self.queue_sync.lock().unwrap(); let Some(ref mut mq) = *queue_guard else { return Err(binder::Status::new_service_specific_error_str(107, Some("no fmq set up"))); }; let rc = mq.read_many(count.try_into().unwrap()); match rc { Some(mut rc) => { for _ in 0..count { rc.read().unwrap(); } Ok(true) } None => { eprintln!("failed to read_many({count})"); Ok(false) } } } /** * This method requests the service to write into the synchronized read/write * flavor of the FMQ. * * @param count Number to messages to write. * * @return True if the write operation was successful. */ fn requestWriteFmqSync(&self, count: i32) -> BinderResult { let mut queue_guard = self.queue_sync.lock().unwrap(); let Some(ref mut mq) = *queue_guard else { return Err(binder::Status::new_service_specific_error_str(107, Some("no fmq set up"))); }; let wc = mq.write_many(count.try_into().unwrap()); match wc { Some(mut wc) => { for i in 0..count { wc.write(i).unwrap(); } drop(wc); Ok(true) } None => { eprintln!("failed to write_many({count})"); Ok(false) } } } fn getFmqUnsyncWrite( &self, _: bool, _: bool, _: &mut MQDescriptor, ) -> BinderResult { // The Rust interface to FMQ does not support `UnsynchronizedWrite`. Ok(false) } /** * This method requests the service to trigger a blocking read. * * @param count Number of messages to read. * */ fn requestBlockingRead(&self, _: i32) -> BinderResult<()> { todo!("b/339999649") } fn requestBlockingReadDefaultEventFlagBits(&self, _: i32) -> BinderResult<()> { todo!("b/339999649") } fn requestBlockingReadRepeat(&self, _: i32, _: i32) -> BinderResult<()> { todo!("b/339999649") } fn requestReadFmqUnsync(&self, _: i32) -> BinderResult { // The Rust interface to FMQ does not support `UnsynchronizedWrite`. Ok(false) } fn requestWriteFmqUnsync(&self, _: i32) -> BinderResult { // The Rust interface to FMQ does not support `UnsynchronizedWrite`. Ok(false) } }