1*be431cd8SAndroid Build Coastguard Worker //! This module implements the ITestAidlMsgQ AIDL interface 2*be431cd8SAndroid Build Coastguard Worker 3*be431cd8SAndroid Build Coastguard Worker /* 4*be431cd8SAndroid Build Coastguard Worker * Copyright (C) 2024 The Android Open Source Project 5*be431cd8SAndroid Build Coastguard Worker * 6*be431cd8SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 7*be431cd8SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 8*be431cd8SAndroid Build Coastguard Worker * You may obtain a copy of the License at 9*be431cd8SAndroid Build Coastguard Worker * 10*be431cd8SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 11*be431cd8SAndroid Build Coastguard Worker * 12*be431cd8SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 13*be431cd8SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 14*be431cd8SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15*be431cd8SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 16*be431cd8SAndroid Build Coastguard Worker * limitations under the License. 17*be431cd8SAndroid Build Coastguard Worker */ 18*be431cd8SAndroid Build Coastguard Worker 19*be431cd8SAndroid Build Coastguard Worker use android_fmq_test::aidl::android::fmq::test::ITestAidlMsgQ::ITestAidlMsgQ; 20*be431cd8SAndroid Build Coastguard Worker use android_fmq_test::binder::{self, Interface, Result as BinderResult}; 21*be431cd8SAndroid Build Coastguard Worker 22*be431cd8SAndroid Build Coastguard Worker /// Struct implementing the ITestAidlMsgQ AIDL interface 23*be431cd8SAndroid Build Coastguard Worker #[derive(Default)] 24*be431cd8SAndroid Build Coastguard Worker pub struct MsgQTestService { 25*be431cd8SAndroid Build Coastguard Worker queue_sync: std::sync::Mutex<Option<fmq::MessageQueue<i32>>>, 26*be431cd8SAndroid Build Coastguard Worker } 27*be431cd8SAndroid Build Coastguard Worker 28*be431cd8SAndroid Build Coastguard Worker impl Interface for MsgQTestService {} 29*be431cd8SAndroid Build Coastguard Worker 30*be431cd8SAndroid Build Coastguard Worker use android_hardware_common_fmq::aidl::android::hardware::common::fmq::{ 31*be431cd8SAndroid Build Coastguard Worker MQDescriptor::MQDescriptor, SynchronizedReadWrite::SynchronizedReadWrite, 32*be431cd8SAndroid Build Coastguard Worker UnsynchronizedWrite::UnsynchronizedWrite, 33*be431cd8SAndroid Build Coastguard Worker }; 34*be431cd8SAndroid Build Coastguard Worker 35*be431cd8SAndroid Build Coastguard Worker impl ITestAidlMsgQ for MsgQTestService { 36*be431cd8SAndroid Build Coastguard Worker /** 37*be431cd8SAndroid Build Coastguard Worker * This method requests the service to set up a synchronous read/write 38*be431cd8SAndroid Build Coastguard Worker * wait-free FMQ using the input descriptor with the client as reader. 39*be431cd8SAndroid Build Coastguard Worker * 40*be431cd8SAndroid Build Coastguard Worker * @param mqDesc This structure describes the FMQ that was set up by the 41*be431cd8SAndroid Build Coastguard Worker * client. Server uses this descriptor to set up a FMQ object at its end. 42*be431cd8SAndroid Build Coastguard Worker * 43*be431cd8SAndroid Build Coastguard Worker * @return True if the setup is successful. 44*be431cd8SAndroid Build Coastguard Worker */ configureFmqSyncReadWrite( &self, mq_desc: &MQDescriptor<i32, SynchronizedReadWrite>, ) -> BinderResult<bool>45*be431cd8SAndroid Build Coastguard Worker fn configureFmqSyncReadWrite( 46*be431cd8SAndroid Build Coastguard Worker &self, 47*be431cd8SAndroid Build Coastguard Worker mq_desc: &MQDescriptor<i32, SynchronizedReadWrite>, 48*be431cd8SAndroid Build Coastguard Worker ) -> BinderResult<bool> { 49*be431cd8SAndroid Build Coastguard Worker *self.queue_sync.lock().unwrap() = Some(fmq::MessageQueue::from_desc(mq_desc, false)); 50*be431cd8SAndroid Build Coastguard Worker /* TODO(b/339999649) in C++ we set the EventFlag word with bit FMQ_NOT_FULL: */ 51*be431cd8SAndroid Build Coastguard Worker /*auto evFlagWordPtr = mFmqSynchronized->getEventFlagWord(); 52*be431cd8SAndroid Build Coastguard Worker if (evFlagWordPtr != nullptr) { 53*be431cd8SAndroid Build Coastguard Worker std::atomic_init(evFlagWordPtr, static_cast<uint32_t>(EventFlagBits::FMQ_NOT_FULL)); 54*be431cd8SAndroid Build Coastguard Worker }*/ 55*be431cd8SAndroid Build Coastguard Worker 56*be431cd8SAndroid Build Coastguard Worker Ok(true) 57*be431cd8SAndroid Build Coastguard Worker } 58*be431cd8SAndroid Build Coastguard Worker 59*be431cd8SAndroid Build Coastguard Worker /** 60*be431cd8SAndroid Build Coastguard Worker * This method requests the service to read from the synchronized read/write 61*be431cd8SAndroid Build Coastguard Worker * FMQ. 62*be431cd8SAndroid Build Coastguard Worker * 63*be431cd8SAndroid Build Coastguard Worker * @param count Number to messages to read. 64*be431cd8SAndroid Build Coastguard Worker * 65*be431cd8SAndroid Build Coastguard Worker * @return True if the read operation was successful. 66*be431cd8SAndroid Build Coastguard Worker */ requestReadFmqSync(&self, count: i32) -> BinderResult<bool>67*be431cd8SAndroid Build Coastguard Worker fn requestReadFmqSync(&self, count: i32) -> BinderResult<bool> { 68*be431cd8SAndroid Build Coastguard Worker let mut queue_guard = self.queue_sync.lock().unwrap(); 69*be431cd8SAndroid Build Coastguard Worker let Some(ref mut mq) = *queue_guard else { 70*be431cd8SAndroid Build Coastguard Worker return Err(binder::Status::new_service_specific_error_str(107, Some("no fmq set up"))); 71*be431cd8SAndroid Build Coastguard Worker }; 72*be431cd8SAndroid Build Coastguard Worker let rc = mq.read_many(count.try_into().unwrap()); 73*be431cd8SAndroid Build Coastguard Worker match rc { 74*be431cd8SAndroid Build Coastguard Worker Some(mut rc) => { 75*be431cd8SAndroid Build Coastguard Worker for _ in 0..count { 76*be431cd8SAndroid Build Coastguard Worker rc.read().unwrap(); 77*be431cd8SAndroid Build Coastguard Worker } 78*be431cd8SAndroid Build Coastguard Worker Ok(true) 79*be431cd8SAndroid Build Coastguard Worker } 80*be431cd8SAndroid Build Coastguard Worker None => { 81*be431cd8SAndroid Build Coastguard Worker eprintln!("failed to read_many({count})"); 82*be431cd8SAndroid Build Coastguard Worker Ok(false) 83*be431cd8SAndroid Build Coastguard Worker } 84*be431cd8SAndroid Build Coastguard Worker } 85*be431cd8SAndroid Build Coastguard Worker } 86*be431cd8SAndroid Build Coastguard Worker 87*be431cd8SAndroid Build Coastguard Worker /** 88*be431cd8SAndroid Build Coastguard Worker * This method requests the service to write into the synchronized read/write 89*be431cd8SAndroid Build Coastguard Worker * flavor of the FMQ. 90*be431cd8SAndroid Build Coastguard Worker * 91*be431cd8SAndroid Build Coastguard Worker * @param count Number to messages to write. 92*be431cd8SAndroid Build Coastguard Worker * 93*be431cd8SAndroid Build Coastguard Worker * @return True if the write operation was successful. 94*be431cd8SAndroid Build Coastguard Worker */ requestWriteFmqSync(&self, count: i32) -> BinderResult<bool>95*be431cd8SAndroid Build Coastguard Worker fn requestWriteFmqSync(&self, count: i32) -> BinderResult<bool> { 96*be431cd8SAndroid Build Coastguard Worker let mut queue_guard = self.queue_sync.lock().unwrap(); 97*be431cd8SAndroid Build Coastguard Worker let Some(ref mut mq) = *queue_guard else { 98*be431cd8SAndroid Build Coastguard Worker return Err(binder::Status::new_service_specific_error_str(107, Some("no fmq set up"))); 99*be431cd8SAndroid Build Coastguard Worker }; 100*be431cd8SAndroid Build Coastguard Worker let wc = mq.write_many(count.try_into().unwrap()); 101*be431cd8SAndroid Build Coastguard Worker match wc { 102*be431cd8SAndroid Build Coastguard Worker Some(mut wc) => { 103*be431cd8SAndroid Build Coastguard Worker for i in 0..count { 104*be431cd8SAndroid Build Coastguard Worker wc.write(i).unwrap(); 105*be431cd8SAndroid Build Coastguard Worker } 106*be431cd8SAndroid Build Coastguard Worker drop(wc); 107*be431cd8SAndroid Build Coastguard Worker Ok(true) 108*be431cd8SAndroid Build Coastguard Worker } 109*be431cd8SAndroid Build Coastguard Worker None => { 110*be431cd8SAndroid Build Coastguard Worker eprintln!("failed to write_many({count})"); 111*be431cd8SAndroid Build Coastguard Worker Ok(false) 112*be431cd8SAndroid Build Coastguard Worker } 113*be431cd8SAndroid Build Coastguard Worker } 114*be431cd8SAndroid Build Coastguard Worker } 115*be431cd8SAndroid Build Coastguard Worker getFmqUnsyncWrite( &self, _: bool, _: bool, _: &mut MQDescriptor<i32, UnsynchronizedWrite>, ) -> BinderResult<bool>116*be431cd8SAndroid Build Coastguard Worker fn getFmqUnsyncWrite( 117*be431cd8SAndroid Build Coastguard Worker &self, 118*be431cd8SAndroid Build Coastguard Worker _: bool, 119*be431cd8SAndroid Build Coastguard Worker _: bool, 120*be431cd8SAndroid Build Coastguard Worker _: &mut MQDescriptor<i32, UnsynchronizedWrite>, 121*be431cd8SAndroid Build Coastguard Worker ) -> BinderResult<bool> { 122*be431cd8SAndroid Build Coastguard Worker // The Rust interface to FMQ does not support `UnsynchronizedWrite`. 123*be431cd8SAndroid Build Coastguard Worker Ok(false) 124*be431cd8SAndroid Build Coastguard Worker } 125*be431cd8SAndroid Build Coastguard Worker 126*be431cd8SAndroid Build Coastguard Worker /** 127*be431cd8SAndroid Build Coastguard Worker * This method requests the service to trigger a blocking read. 128*be431cd8SAndroid Build Coastguard Worker * 129*be431cd8SAndroid Build Coastguard Worker * @param count Number of messages to read. 130*be431cd8SAndroid Build Coastguard Worker * 131*be431cd8SAndroid Build Coastguard Worker */ requestBlockingRead(&self, _: i32) -> BinderResult<()>132*be431cd8SAndroid Build Coastguard Worker fn requestBlockingRead(&self, _: i32) -> BinderResult<()> { 133*be431cd8SAndroid Build Coastguard Worker todo!("b/339999649") 134*be431cd8SAndroid Build Coastguard Worker } requestBlockingReadDefaultEventFlagBits(&self, _: i32) -> BinderResult<()>135*be431cd8SAndroid Build Coastguard Worker fn requestBlockingReadDefaultEventFlagBits(&self, _: i32) -> BinderResult<()> { 136*be431cd8SAndroid Build Coastguard Worker todo!("b/339999649") 137*be431cd8SAndroid Build Coastguard Worker } requestBlockingReadRepeat(&self, _: i32, _: i32) -> BinderResult<()>138*be431cd8SAndroid Build Coastguard Worker fn requestBlockingReadRepeat(&self, _: i32, _: i32) -> BinderResult<()> { 139*be431cd8SAndroid Build Coastguard Worker todo!("b/339999649") 140*be431cd8SAndroid Build Coastguard Worker } requestReadFmqUnsync(&self, _: i32) -> BinderResult<bool>141*be431cd8SAndroid Build Coastguard Worker fn requestReadFmqUnsync(&self, _: i32) -> BinderResult<bool> { 142*be431cd8SAndroid Build Coastguard Worker // The Rust interface to FMQ does not support `UnsynchronizedWrite`. 143*be431cd8SAndroid Build Coastguard Worker Ok(false) 144*be431cd8SAndroid Build Coastguard Worker } requestWriteFmqUnsync(&self, _: i32) -> BinderResult<bool>145*be431cd8SAndroid Build Coastguard Worker fn requestWriteFmqUnsync(&self, _: i32) -> BinderResult<bool> { 146*be431cd8SAndroid Build Coastguard Worker // The Rust interface to FMQ does not support `UnsynchronizedWrite`. 147*be431cd8SAndroid Build Coastguard Worker Ok(false) 148*be431cd8SAndroid Build Coastguard Worker } 149*be431cd8SAndroid Build Coastguard Worker } 150