• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //! MockHal
18 
19 use android_hardware_uwb::aidl::android::hardware::uwb::{
20     IUwbChip::IUwbChipAsync, IUwbClientCallback::IUwbClientCallback,
21 };
22 use android_hardware_uwb::binder::{Result as BinderResult, Strong};
23 use async_trait::async_trait;
24 use binder::{SpIBinder, StatusCode};
25 use std::collections::VecDeque;
26 use std::sync::Mutex as StdMutex;
27 
28 #[cfg(test)]
29 enum ExpectedHalCall {
30     Open { out: BinderResult<()> },
31     Close { out: BinderResult<()> },
32     CoreInit { out: BinderResult<()> },
33     SessionInit { expected_session_id: i32, out: BinderResult<()> },
34     SendUciMessage { expected_data: Vec<u8>, out: BinderResult<i32> },
35 }
36 
37 #[cfg(test)]
38 pub struct MockHal {
39     expected_calls: StdMutex<VecDeque<ExpectedHalCall>>,
40 }
41 
42 #[cfg(test)]
43 impl MockHal {
new() -> Self44     pub fn new() -> Self {
45         Self { expected_calls: StdMutex::new(VecDeque::new()) }
46     }
47     #[allow(dead_code)]
expect_open(&self, out: BinderResult<()>)48     pub fn expect_open(&self, out: BinderResult<()>) {
49         self.expected_calls.lock().unwrap().push_back(ExpectedHalCall::Open { out });
50     }
51     #[allow(dead_code)]
expect_close(&self, out: BinderResult<()>)52     pub fn expect_close(&self, out: BinderResult<()>) {
53         self.expected_calls.lock().unwrap().push_back(ExpectedHalCall::Close { out });
54     }
55     #[allow(dead_code)]
expect_core_init(&self, out: BinderResult<()>)56     pub fn expect_core_init(&self, out: BinderResult<()>) {
57         self.expected_calls.lock().unwrap().push_back(ExpectedHalCall::CoreInit { out });
58     }
59     #[allow(dead_code)]
expect_session_init(&self, expected_session_id: i32, out: BinderResult<()>)60     pub fn expect_session_init(&self, expected_session_id: i32, out: BinderResult<()>) {
61         self.expected_calls
62             .lock()
63             .unwrap()
64             .push_back(ExpectedHalCall::SessionInit { expected_session_id, out });
65     }
expect_send_uci_message(&self, expected_data: Vec<u8>, out: BinderResult<i32>)66     pub fn expect_send_uci_message(&self, expected_data: Vec<u8>, out: BinderResult<i32>) {
67         self.expected_calls
68             .lock()
69             .unwrap()
70             .push_back(ExpectedHalCall::SendUciMessage { expected_data, out });
71     }
72 }
73 
74 #[cfg(test)]
75 impl Drop for MockHal {
drop(&mut self)76     fn drop(&mut self) {
77         assert!(self.expected_calls.lock().unwrap().is_empty());
78     }
79 }
80 
81 #[cfg(test)]
82 impl Default for MockHal {
default() -> Self83     fn default() -> Self {
84         Self::new()
85     }
86 }
87 
88 #[cfg(test)]
89 impl binder::Interface for MockHal {}
90 
91 #[cfg(test)]
92 impl binder::FromIBinder for MockHal {
try_from(_ibinder: SpIBinder) -> std::result::Result<Strong<Self>, binder::StatusCode>93     fn try_from(_ibinder: SpIBinder) -> std::result::Result<Strong<Self>, binder::StatusCode> {
94         Err(binder::StatusCode::OK)
95     }
96 }
97 
98 #[cfg(test)]
99 #[async_trait]
100 impl<P: binder::BinderAsyncPool> IUwbChipAsync<P> for MockHal {
getName(&self) -> binder::BoxFuture<BinderResult<String>>101     fn getName(&self) -> binder::BoxFuture<BinderResult<String>> {
102         Box::pin(std::future::ready(Ok("default".into())))
103     }
104 
open<'a>( &'a self, _cb: &'a binder::Strong<dyn IUwbClientCallback>, ) -> binder::BoxFuture<'a, BinderResult<()>>105     fn open<'a>(
106         &'a self,
107         _cb: &'a binder::Strong<dyn IUwbClientCallback>,
108     ) -> binder::BoxFuture<'a, BinderResult<()>> {
109         let expected_out = {
110             let mut expected_calls = self.expected_calls.lock().unwrap();
111             match expected_calls.pop_front() {
112                 Some(ExpectedHalCall::Open { out }) => Some(out),
113                 Some(call) => {
114                     expected_calls.push_front(call);
115                     None
116                 }
117                 None => None,
118             }
119         };
120 
121         match expected_out {
122             Some(out) => Box::pin(std::future::ready(out)),
123             None => Box::pin(std::future::ready(Err(StatusCode::UNKNOWN_ERROR.into()))),
124         }
125     }
126 
close(&self) -> binder::BoxFuture<BinderResult<()>>127     fn close(&self) -> binder::BoxFuture<BinderResult<()>> {
128         let expected_out = {
129             let mut expected_calls = self.expected_calls.lock().unwrap();
130             match expected_calls.pop_front() {
131                 Some(ExpectedHalCall::Close { out }) => Some(out),
132                 Some(call) => {
133                     expected_calls.push_front(call);
134                     None
135                 }
136                 None => None,
137             }
138         };
139 
140         match expected_out {
141             Some(out) => Box::pin(std::future::ready(out)),
142             None => Box::pin(std::future::ready(Err(StatusCode::UNKNOWN_ERROR.into()))),
143         }
144     }
145 
coreInit(&self) -> binder::BoxFuture<BinderResult<()>>146     fn coreInit(&self) -> binder::BoxFuture<BinderResult<()>> {
147         let expected_out = {
148             let mut expected_calls = self.expected_calls.lock().unwrap();
149             match expected_calls.pop_front() {
150                 Some(ExpectedHalCall::CoreInit { out }) => Some(out),
151                 Some(call) => {
152                     expected_calls.push_front(call);
153                     None
154                 }
155                 None => None,
156             }
157         };
158 
159         match expected_out {
160             Some(out) => Box::pin(std::future::ready(out)),
161             None => Box::pin(std::future::ready(Err(StatusCode::UNKNOWN_ERROR.into()))),
162         }
163     }
164 
sessionInit(&self, session_id: i32) -> binder::BoxFuture<BinderResult<()>>165     fn sessionInit(&self, session_id: i32) -> binder::BoxFuture<BinderResult<()>> {
166         let expected_out = {
167             let mut expected_calls = self.expected_calls.lock().unwrap();
168             match expected_calls.pop_front() {
169                 Some(ExpectedHalCall::SessionInit { expected_session_id, out })
170                     if expected_session_id == session_id =>
171                 {
172                     Some(out)
173                 }
174                 Some(call) => {
175                     expected_calls.push_front(call);
176                     None
177                 }
178                 None => None,
179             }
180         };
181 
182         match expected_out {
183             Some(out) => Box::pin(std::future::ready(out)),
184             None => Box::pin(std::future::ready(Err(StatusCode::UNKNOWN_ERROR.into()))),
185         }
186     }
187 
getSupportedAndroidUciVersion(&self) -> binder::BoxFuture<BinderResult<i32>>188     fn getSupportedAndroidUciVersion(&self) -> binder::BoxFuture<BinderResult<i32>> {
189         Box::pin(std::future::ready(Ok(0)))
190     }
191 
sendUciMessage(&self, cmd: &[u8]) -> binder::BoxFuture<BinderResult<i32>>192     fn sendUciMessage(&self, cmd: &[u8]) -> binder::BoxFuture<BinderResult<i32>> {
193         let expected_out = {
194             let mut expected_calls = self.expected_calls.lock().unwrap();
195             match expected_calls.pop_front() {
196                 Some(ExpectedHalCall::SendUciMessage { expected_data, out })
197                     if expected_data == cmd =>
198                 {
199                     Some(out)
200                 }
201                 Some(call) => {
202                     expected_calls.push_front(call);
203                     None
204                 }
205                 None => None,
206             }
207         };
208         match expected_out {
209             Some(out) => Box::pin(std::future::ready(out)),
210             None => Box::pin(std::future::ready(Err(StatusCode::UNKNOWN_ERROR.into()))),
211         }
212     }
213 }
214