bt_test_harness/
profile.rs1use anyhow::{Context as _, Error};
6use fidl_fuchsia_bluetooth_bredr::{ProfileMarker, ProfileProxy};
7use fidl_fuchsia_hardware_bluetooth::EmulatorProxy;
8use fuchsia_bluetooth::expectation::asynchronous::{expectable, Expectable, ExpectableExt};
9use futures::future::BoxFuture;
10use futures::{FutureExt, StreamExt};
11use std::ops::{Deref, DerefMut};
12use std::sync::Arc;
13use test_harness::{SharedState, TestHarness, SHARED_STATE_TEST_COMPONENT_INDEX};
14
15use crate::core_realm::{CoreRealm, SHARED_STATE_INDEX};
16use crate::emulator::EmulatorState;
17use crate::host_watcher::ActivatedFakeHost;
18
19#[derive(Clone, Debug, Default)]
20pub struct ProfileState {
21 emulator_state: EmulatorState,
22}
23
24impl std::convert::AsMut<EmulatorState> for ProfileState {
25 fn as_mut(&mut self) -> &mut EmulatorState {
26 &mut self.emulator_state
27 }
28}
29
30impl std::convert::AsRef<EmulatorState> for ProfileState {
31 fn as_ref(&self) -> &EmulatorState {
32 &self.emulator_state
33 }
34}
35
36pub struct Aux {
38 pub profile: ProfileProxy,
39 pub emulator: EmulatorProxy,
40}
41
42#[derive(Clone)]
43pub struct ProfileHarness(Expectable<ProfileState, Aux>);
44
45impl Deref for ProfileHarness {
46 type Target = Expectable<ProfileState, Aux>;
47
48 fn deref(&self) -> &Self::Target {
49 &self.0
50 }
51}
52
53impl DerefMut for ProfileHarness {
54 fn deref_mut(&mut self) -> &mut Self::Target {
55 &mut self.0
56 }
57}
58
59impl TestHarness for ProfileHarness {
60 type Env = (ActivatedFakeHost, Arc<CoreRealm>);
61 type Runner = BoxFuture<'static, Result<(), Error>>;
62
63 fn init(
64 shared_state: &Arc<SharedState>,
65 ) -> BoxFuture<'static, Result<(Self, Self::Env, Self::Runner), Error>> {
66 let shared_state = shared_state.clone();
67 async move {
68 let test_component: Arc<String> = shared_state
69 .get(SHARED_STATE_TEST_COMPONENT_INDEX)
70 .expect("SharedState must have TEST-COMPONENT")?;
71 let inserter = move || CoreRealm::create(test_component.to_string());
72 let realm = shared_state.get_or_insert_with(SHARED_STATE_INDEX, inserter).await?;
73 let host = ActivatedFakeHost::new(realm.clone()).await?;
74 let profile = realm
75 .instance()
76 .connect_to_protocol_at_exposed_dir::<ProfileMarker>()
77 .context("failed to connect to Profile service")?;
78 let harness = ProfileHarness(expectable(
79 Default::default(),
80 Aux { profile, emulator: host.emulator().clone() },
81 ));
82
83 let run_profile = handle_profile_events(harness.clone()).boxed();
84 Ok((harness, (host, realm), run_profile))
85 }
86 .boxed()
87 }
88
89 fn terminate((emulator, realm): Self::Env) -> BoxFuture<'static, Result<(), Error>> {
90 async move {
92 let _realm = realm;
93 emulator.release().await
94 }
95 .boxed()
96 }
97}
98
99pub async fn handle_profile_events(harness: ProfileHarness) -> Result<(), Error> {
100 let mut events = harness.aux().profile.take_event_stream();
101
102 while let Some(evt) = events.next().await {
103 let _ = evt?;
104 }
105 Ok(())
106}