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