blob: b3a0318d819dbbd4491a56a9202ff4dd4a1b7adf [file] [log] [blame]
// Copyright 2020 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 crate::audio::build_audio_default_settings;
use crate::audio::types::{AudioInfo, AudioStreamType};
#[cfg(test)]
use crate::audio::{create_default_audio_stream, StreamVolumeControl};
use crate::message::base::MessengerType;
use crate::service_context::{ExternalServiceEvent, ServiceContext};
use crate::tests::fakes::audio_core_service;
use crate::tests::fakes::service_registry::ServiceRegistry;
use crate::{clock, event, service};
use futures::lock::Mutex;
use futures::StreamExt;
use std::sync::Arc;
fn default_audio_info() -> AudioInfo {
let mut audio_configuration = build_audio_default_settings();
audio_configuration
.load_default_value()
.expect("config should exist and parse for test")
.unwrap()
}
// Returns a registry populated with the AudioCore service.
async fn create_service() -> Arc<Mutex<ServiceRegistry>> {
let service_registry = ServiceRegistry::create();
let audio_core_service_handle = audio_core_service::Builder::new(default_audio_info())
.set_suppress_client_errors(true)
.build();
service_registry.lock().await.register_service(audio_core_service_handle.clone());
service_registry
}
// Tests that the volume event stream thread exits when the StreamVolumeControl is deleted.
#[fuchsia::test(allow_stalls = false)]
async fn test_drop_thread() {
let delegate = service::MessageHub::create_hub();
let mut receptor = service::build_event_listener(&delegate).await;
let publisher = event::Publisher::create(&delegate, MessengerType::Unbound).await;
let service_context =
ServiceContext::new(Some(ServiceRegistry::serve(create_service().await)), None);
let audio_proxy = service_context
.connect::<fidl_fuchsia_media::AudioCoreMarker>()
.await
.expect("service should be present");
let _ = StreamVolumeControl::create(
0.into(),
&audio_proxy,
create_default_audio_stream(AudioStreamType::Media),
None,
Some(publisher),
)
.await;
let req = "unknown";
let req_timestamp = "unknown";
let resp_timestamp = clock::inspect_format_now();
assert_eq!(
receptor
.next_of::<event::Payload>()
.await
.expect("First message should have been the closed event")
.0,
event::Payload::Event(event::Event::ExternalServiceEvent(ExternalServiceEvent::Closed(
"volume_control_events",
req.into(),
req_timestamp.into(),
resp_timestamp.into(),
)))
);
}
// Ensures that the StreamVolumeControl properly fires the provided early exit
// closure when the underlying AudioCoreService closes unexpectedly.
#[fuchsia::test(allow_stalls = false)]
async fn test_detect_early_exit() {
let service_registry = ServiceRegistry::create();
let audio_core_service_handle = audio_core_service::Builder::new(default_audio_info())
.set_suppress_client_errors(true)
.build();
service_registry.lock().await.register_service(audio_core_service_handle.clone());
let service_context = ServiceContext::new(Some(ServiceRegistry::serve(service_registry)), None);
let audio_proxy = service_context
.connect::<fidl_fuchsia_media::AudioCoreMarker>()
.await
.expect("proxy should be present");
let (tx, mut rx) = futures::channel::mpsc::unbounded::<()>();
// Create StreamVolumeControl, specifying firing an event as the early exit
// action. Note that we must store the returned value or else the normal
// drop behavior will clean up it before the AudioCoreService's exit can
// be detected.
let _stream_volume_control = StreamVolumeControl::create(
0.into(),
&audio_proxy,
create_default_audio_stream(AudioStreamType::Media),
Some(Arc::new(move || {
tx.unbounded_send(()).unwrap();
})),
None,
)
.await
.expect("should successfully build");
// Trigger AudioCoreService exit.
audio_core_service_handle.lock().await.exit();
// Check to make sure early exit event was received.
assert!(matches!(rx.next().await, Some(..)));
}