blob: 12f182fd69cda1a3e419b5c619155a5dd43cd4f6 [file] [log] [blame]
// Copyright 2022, The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::collections::VecDeque;
use std::sync::{Arc, Mutex};
use tokio::sync::Notify;
use tokio::time::{timeout, Duration};
use crate::params::{DeviceState, ReasonCode, SessionId, SessionState};
use crate::service::uwb_service::UwbServiceCallback;
use crate::uci::SessionRangeData;
#[derive(Clone, Default)]
pub(crate) struct MockUwbServiceCallback {
expected_calls: Arc<Mutex<VecDeque<ExpectedCall>>>,
expect_call_consumed: Arc<Notify>,
}
impl MockUwbServiceCallback {
pub fn new() -> Self {
Default::default()
}
pub fn expect_on_service_reset(&mut self, success: bool) {
self.push_expected_call(ExpectedCall::ServiceReset { success });
}
pub fn expect_on_uci_device_status_changed(&mut self, state: DeviceState) {
self.push_expected_call(ExpectedCall::UciDeviceStatus { state });
}
pub fn expect_on_session_state_changed(
&mut self,
session_id: SessionId,
session_state: SessionState,
reason_code: ReasonCode,
) {
self.push_expected_call(ExpectedCall::SessionState {
session_id,
session_state,
reason_code,
});
}
pub fn expect_on_range_data_received(
&mut self,
session_id: SessionId,
range_data: SessionRangeData,
) {
self.push_expected_call(ExpectedCall::RangeData { session_id, range_data });
}
pub fn expect_on_vendor_notification_received(&mut self, gid: u32, oid: u32, payload: Vec<u8>) {
self.push_expected_call(ExpectedCall::VendorNotification { gid, oid, payload });
}
pub async fn wait_expected_calls_done(&mut self) -> bool {
while !self.expected_calls.lock().unwrap().is_empty() {
if timeout(Duration::from_secs(1), self.expect_call_consumed.notified()).await.is_err()
{
return false;
}
}
true
}
fn push_expected_call(&mut self, call: ExpectedCall) {
self.expected_calls.lock().unwrap().push_back(call);
}
fn pop_expected_call(&mut self) -> ExpectedCall {
let call = self.expected_calls.lock().unwrap().pop_front().unwrap();
self.expect_call_consumed.notify_one();
call
}
}
impl UwbServiceCallback for MockUwbServiceCallback {
fn on_service_reset(&mut self, success: bool) {
assert_eq!(self.pop_expected_call(), ExpectedCall::ServiceReset { success });
}
fn on_uci_device_status_changed(&mut self, state: DeviceState) {
assert_eq!(self.pop_expected_call(), ExpectedCall::UciDeviceStatus { state });
}
fn on_session_state_changed(
&mut self,
session_id: SessionId,
session_state: SessionState,
reason_code: ReasonCode,
) {
assert_eq!(
self.pop_expected_call(),
ExpectedCall::SessionState { session_id, session_state, reason_code }
);
}
fn on_range_data_received(&mut self, session_id: SessionId, range_data: SessionRangeData) {
assert_eq!(self.pop_expected_call(), ExpectedCall::RangeData { session_id, range_data });
}
fn on_vendor_notification_received(&mut self, gid: u32, oid: u32, payload: Vec<u8>) {
assert_eq!(
self.pop_expected_call(),
ExpectedCall::VendorNotification { gid, oid, payload }
);
}
}
#[derive(PartialEq, Debug)]
pub(crate) enum ExpectedCall {
ServiceReset { success: bool },
UciDeviceStatus { state: DeviceState },
SessionState { session_id: SessionId, session_state: SessionState, reason_code: ReasonCode },
RangeData { session_id: SessionId, range_data: SessionRangeData },
VendorNotification { gid: u32, oid: u32, payload: Vec<u8> },
}