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