summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShreshta Manu <shreshtabm@google.com>2022-01-21 07:15:01 +0000
committerShreshta Manu <shreshtabm@google.com>2022-01-21 21:17:57 +0000
commit16ee1a32f68d5836d63fc0d605024a2a1b549c53 (patch)
tree71d7fd4f65da458013829c332a19e439834a14a0
parent1d73ae5c93b4f5f715367a30b097308078fde06d (diff)
downloaduwb-16ee1a32f68d5836d63fc0d605024a2a1b549c53.tar.gz
Added a new trait which is implemented by EventManager and EventManagerTest.
Dispatcher can now be initialized from unit tests. Test: libuwb_uci_rust_tests Bug: 197341298 Change-Id: I20b4c39ee9e98bb5f16f15405f9064207615de7d
-rw-r--r--src/rust/event_manager/mod.rs154
-rw-r--r--src/rust/uci/mod.rs39
2 files changed, 119 insertions, 74 deletions
diff --git a/src/rust/event_manager/mod.rs b/src/rust/event_manager/mod.rs
index aa59f75..b8f6f46 100644
--- a/src/rust/event_manager/mod.rs
+++ b/src/rust/event_manager/mod.rs
@@ -48,6 +48,21 @@ const EXTENDED_MAC_ADDRESS_LEN: usize = 8;
// TODO: We could consider caching the method ids rather than recomputing them each time at the cost
// of less safety.
+pub trait Manager {
+ fn device_status_notification_received(&self, data: DeviceStatusNtfPacket) -> Result<()>;
+ fn core_generic_error_notification_received(&self, data: GenericErrorPacket) -> Result<()>;
+ fn session_status_notification_received(&self, data: SessionStatusNtfPacket) -> Result<()>;
+ fn short_range_data_notification(&self, data: ShortMacTwoWayRangeDataNtfPacket) -> Result<()>;
+ fn extended_range_data_notification(
+ &self,
+ data: ExtendedMacTwoWayRangeDataNtfPacket,
+ ) -> Result<()>;
+ fn session_update_controller_multicast_list_notification(
+ &self,
+ data: SessionUpdateControllerMulticastListNtfPacket,
+ ) -> Result<()>;
+}
+
// Manages calling Java callbacks through the JNI.
pub struct EventManager {
jvm: JavaVM,
@@ -56,6 +71,56 @@ pub struct EventManager {
class_loader_obj: GlobalRef,
}
+impl Manager for EventManager {
+ fn device_status_notification_received(&self, data: DeviceStatusNtfPacket) -> Result<()> {
+ let env = self.jvm.attach_current_thread()?;
+ let result = self.handle_device_status_notification_received(&env, data);
+ self.clear_exception(env);
+ result
+ }
+
+ fn core_generic_error_notification_received(&self, data: GenericErrorPacket) -> Result<()> {
+ let env = self.jvm.attach_current_thread()?;
+ let result = self.handle_core_generic_error_notification_received(&env, data);
+ self.clear_exception(env);
+ result
+ }
+
+ fn session_status_notification_received(&self, data: SessionStatusNtfPacket) -> Result<()> {
+ let env = self.jvm.attach_current_thread()?;
+ let result = self.handle_session_status_notification_received(&env, data);
+ self.clear_exception(env);
+ result
+ }
+
+ fn short_range_data_notification(&self, data: ShortMacTwoWayRangeDataNtfPacket) -> Result<()> {
+ let env = self.jvm.attach_current_thread()?;
+ let result = self.handle_short_range_data_notification(&env, data);
+ self.clear_exception(env);
+ result
+ }
+
+ fn extended_range_data_notification(
+ &self,
+ data: ExtendedMacTwoWayRangeDataNtfPacket,
+ ) -> Result<()> {
+ let env = self.jvm.attach_current_thread()?;
+ let result = self.handle_extended_range_data_notification(&env, data);
+ self.clear_exception(env);
+ result
+ }
+
+ fn session_update_controller_multicast_list_notification(
+ &self,
+ data: SessionUpdateControllerMulticastListNtfPacket,
+ ) -> Result<()> {
+ let env = self.jvm.attach_current_thread()?;
+ let result = self.handle_session_update_controller_multicast_list_notification(&env, data);
+ self.clear_exception(env);
+ result
+ }
+}
+
impl EventManager {
/// Creates a new EventManager.
pub fn new(env: JNIEnv, obj: JObject) -> Result<Self> {
@@ -110,13 +175,6 @@ impl EventManager {
.map(|_| ()) // drop void method return
}
- pub fn device_status_notification_received(&self, data: DeviceStatusNtfPacket) -> Result<()> {
- let env = self.jvm.attach_current_thread()?;
- let result = self.handle_device_status_notification_received(&env, data);
- self.clear_exception(env);
- result
- }
-
fn handle_session_status_notification_received(
&self,
env: &JNIEnv,
@@ -137,13 +195,6 @@ impl EventManager {
.map(|_| ()) // drop void method return
}
- pub fn session_status_notification_received(&self, data: SessionStatusNtfPacket) -> Result<()> {
- let env = self.jvm.attach_current_thread()?;
- let result = self.handle_session_status_notification_received(&env, data);
- self.clear_exception(env);
- result
- }
-
fn handle_core_generic_error_notification_received(
&self,
env: &JNIEnv,
@@ -159,13 +210,6 @@ impl EventManager {
.map(|_| ()) // drop void method return
}
- pub fn core_generic_error_notification_received(&self, data: GenericErrorPacket) -> Result<()> {
- let env = self.jvm.attach_current_thread()?;
- let result = self.handle_core_generic_error_notification_received(&env, data);
- self.clear_exception(env);
- result
- }
-
fn create_zeroed_two_way_measurement_java<'a>(
env: &'a JNIEnv,
two_way_measurement_class: JClass,
@@ -463,16 +507,6 @@ impl EventManager {
.map(|_| ()) // drop void method return
}
- pub fn short_range_data_notification(
- &self,
- data: ShortMacTwoWayRangeDataNtfPacket,
- ) -> Result<()> {
- let env = self.jvm.attach_current_thread()?;
- let result = self.handle_short_range_data_notification(&env, data);
- self.clear_exception(env);
- result
- }
-
fn handle_extended_range_data_notification(
&self,
env: &JNIEnv,
@@ -527,16 +561,6 @@ impl EventManager {
.map(|_| ()) // drop void method return
}
- pub fn extended_range_data_notification(
- &self,
- data: ExtendedMacTwoWayRangeDataNtfPacket,
- ) -> Result<()> {
- let env = self.jvm.attach_current_thread()?;
- let result = self.handle_extended_range_data_notification(&env, data);
- self.clear_exception(env);
- result
- }
-
pub fn handle_session_update_controller_multicast_list_notification(
&self,
env: &JNIEnv,
@@ -594,16 +618,6 @@ impl EventManager {
.map(|_| ()) // drop void method return
}
- pub fn session_update_controller_multicast_list_notification(
- &self,
- data: SessionUpdateControllerMulticastListNtfPacket,
- ) -> Result<()> {
- let env = self.jvm.attach_current_thread()?;
- let result = self.handle_session_update_controller_multicast_list_notification(&env, data);
- self.clear_exception(env);
- result
- }
-
// Attempts to clear an exception. If we do not do this, the exception continues being thrown
// when the control flow returns to Java. We discard errors here (after logging them) rather
// than propagating them to the caller since there's nothing they can do with that information.
@@ -618,3 +632,41 @@ impl EventManager {
}
}
}
+
+#[cfg(test)]
+pub struct EventManagerTest {}
+
+#[cfg(test)]
+impl EventManagerTest {
+ pub fn new() -> Self {
+ Self {}
+ }
+}
+
+#[cfg(test)]
+impl Manager for EventManagerTest {
+ fn device_status_notification_received(&self, data: DeviceStatusNtfPacket) -> Result<()> {
+ Ok(())
+ }
+ fn core_generic_error_notification_received(&self, data: GenericErrorPacket) -> Result<()> {
+ Ok(())
+ }
+ fn session_status_notification_received(&self, data: SessionStatusNtfPacket) -> Result<()> {
+ Ok(())
+ }
+ fn short_range_data_notification(&self, data: ShortMacTwoWayRangeDataNtfPacket) -> Result<()> {
+ Ok(())
+ }
+ fn extended_range_data_notification(
+ &self,
+ data: ExtendedMacTwoWayRangeDataNtfPacket,
+ ) -> Result<()> {
+ Ok(())
+ }
+ fn session_update_controller_multicast_list_notification(
+ &self,
+ data: SessionUpdateControllerMulticastListNtfPacket,
+ ) -> Result<()> {
+ Ok(())
+ }
+}
diff --git a/src/rust/uci/mod.rs b/src/rust/uci/mod.rs
index ee4e7d0..15ff203 100644
--- a/src/rust/uci/mod.rs
+++ b/src/rust/uci/mod.rs
@@ -20,7 +20,7 @@ pub mod uci_hrcv;
use crate::adaptation::UwbAdaptation;
use crate::error::UwbErr;
-use crate::event_manager::EventManager;
+use crate::event_manager::{EventManager, Manager};
use crate::uci::uci_hrcv::UciResponse;
use android_hardware_uwb::aidl::android::hardware::uwb::{
UwbEvent::UwbEvent, UwbStatus::UwbStatus,
@@ -39,6 +39,9 @@ use uwb_uci_packets::{
SessionGetStateCmdBuilder, SessionState, SessionStatusNtfPacket, StatusCode,
};
+#[cfg(test)]
+use crate::event_manager::EventManagerTest;
+
pub type Result<T> = std::result::Result<T, UwbErr>;
pub type UciResponseHandle = oneshot::Sender<UciResponse>;
@@ -152,18 +155,18 @@ async fn option_future<R, T: Future<Output = R>>(mf: Option<T>) -> Option<R> {
}
}
-struct Driver {
+struct Driver<T: Manager> {
adaptation: Arc<UwbAdaptation>,
- event_manager: EventManager,
+ event_manager: T,
cmd_receiver: mpsc::UnboundedReceiver<(JNICommand, Option<UciResponseHandle>)>,
rsp_receiver: mpsc::UnboundedReceiver<HalCallback>,
response_channel: Option<(UciResponseHandle, Retryer)>,
}
// Creates a future that handles messages from JNI and the HAL.
-async fn drive(
+async fn drive<T: Manager>(
adaptation: UwbAdaptation,
- event_manager: EventManager,
+ event_manager: T,
cmd_receiver: mpsc::UnboundedReceiver<(JNICommand, Option<UciResponseHandle>)>,
rsp_receiver: mpsc::UnboundedReceiver<HalCallback>,
) -> Result<()> {
@@ -173,10 +176,10 @@ async fn drive(
const MAX_RETRIES: usize = 10;
const RETRY_DELAY_MS: u64 = 100;
-impl Driver {
+impl<T: Manager> Driver<T> {
fn new(
adaptation: Arc<UwbAdaptation>,
- event_manager: EventManager,
+ event_manager: T,
cmd_receiver: mpsc::UnboundedReceiver<(JNICommand, Option<UciResponseHandle>)>,
rsp_receiver: mpsc::UnboundedReceiver<HalCallback>,
) -> Self {
@@ -380,7 +383,7 @@ pub struct Dispatcher {
}
impl Dispatcher {
- pub fn new(event_manager: EventManager) -> Result<Dispatcher> {
+ pub fn new<T: 'static + Manager + std::marker::Send>(event_manager: T) -> Result<Dispatcher> {
info!("initializing dispatcher");
let (cmd_sender, cmd_receiver) =
mpsc::unbounded_channel::<(JNICommand, Option<UciResponseHandle>)>();
@@ -430,21 +433,11 @@ mod tests {
logger::init(
logger::Config::default().with_tag_on_device("uwb").with_min_level(log::Level::Error),
);
- // TODO : Consider below ways to write the unit test
- // 1
- // Create test-only methods on EventManager that allow you to construct one without Java
- // (and to have dummy/tracked effects when callbacks get called).
- //
- // 2 and recommended way
- // Take the signature of EventManager and make it a trait, which would allow you to impl that
- // trait again on a test-only mock type
-
- //let mut dispatcher = Dispatcher::new()?;
- //dispatcher.send_hal_response(HalCallback::A)?;
- //dispatcher.send_jni_command(JNICommand::Enable)?;
- //dispatcher.block_on_jni_command(JNICommand::GetDeviceInfo)?;
- //dispatcher.exit()?;
- //assert!(dispatcher.send_hal_response(HalCallback::B).is_err());
+
+ let event_manager = EventManagerTest::new();
+ let mut dispatcher = Dispatcher::new(event_manager)?;
+ dispatcher.send_jni_command(JNICommand::Enable)?;
+ dispatcher.exit()?;
Ok(())
}
}