blob: 441c055aba48326278e19d3a0df47cae4e6c43da [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
anyhow::{Context as _, Error},
fidl_fuchsia_bluetooth_bredr::{ProfileMarker, ProfileProxy},
fidl_fuchsia_bluetooth_test::HciEmulatorProxy,
fuchsia_bluetooth::expectation::asynchronous::{expectable, Expectable, ExpectableExt},
futures::future::BoxFuture,
futures::{FutureExt, StreamExt},
std::{
ops::{Deref, DerefMut},
sync::Arc,
},
test_harness::{SharedState, TestHarness},
};
use crate::{
core_realm::{CoreRealm, SHARED_STATE_INDEX},
emulator::EmulatorState,
host_watcher::ActivatedFakeHost,
};
#[derive(Clone, Debug, Default)]
pub struct ProfileState {
emulator_state: EmulatorState,
}
impl std::convert::AsMut<EmulatorState> for ProfileState {
fn as_mut(&mut self) -> &mut EmulatorState {
&mut self.emulator_state
}
}
impl std::convert::AsRef<EmulatorState> for ProfileState {
fn as_ref(&self) -> &EmulatorState {
&self.emulator_state
}
}
/// Auxilliary data for the ProfileHarness
pub struct Aux {
pub profile: ProfileProxy,
pub emulator: HciEmulatorProxy,
}
#[derive(Clone)]
pub struct ProfileHarness(Expectable<ProfileState, Aux>);
impl Deref for ProfileHarness {
type Target = Expectable<ProfileState, Aux>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for ProfileHarness {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl TestHarness for ProfileHarness {
type Env = (ActivatedFakeHost, Arc<CoreRealm>);
type Runner = BoxFuture<'static, Result<(), Error>>;
fn init(
shared_state: &Arc<SharedState>,
) -> BoxFuture<'static, Result<(Self, Self::Env, Self::Runner), Error>> {
let shared_state = shared_state.clone();
async move {
let realm =
shared_state.get_or_insert_with(SHARED_STATE_INDEX, CoreRealm::create).await?;
let host = ActivatedFakeHost::new(realm.clone()).await?;
let profile = realm
.instance()
.connect_to_protocol_at_exposed_dir::<ProfileMarker>()
.context("failed to connect to Profile service")?;
let harness = ProfileHarness(expectable(
Default::default(),
Aux { profile, emulator: host.emulator().clone() },
));
let run_profile = handle_profile_events(harness.clone()).boxed();
Ok((harness, (host, realm), run_profile))
}
.boxed()
}
fn terminate((emulator, realm): Self::Env) -> BoxFuture<'static, Result<(), Error>> {
// The realm must be kept alive in order for emulator.release() to work properly.
async move {
let _realm = realm;
emulator.release().await
}
.boxed()
}
}
pub async fn handle_profile_events(harness: ProfileHarness) -> Result<(), Error> {
let mut events = harness.aux().profile.take_event_stream();
while let Some(evt) = events.next().await {
let _ = evt?;
}
Ok(())
}