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