[SetUI][Agent] Remove individual stage contexts.
This changelist removes the initialization stage context
and moves the available components to the overall
agent context.
The test_available_components test is no longer
relevant without the components in stage contexts.
Pipelining available components is still covered by
the restore agent test.
Fixed: 52428
Test: fx test -o setui_service_tests
Change-Id: I5158b0f7981ec25bab95fe4e233bebd23218d725
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/402559
Commit-Queue: Bryce Lee <brycelee@google.com>
Reviewed-by: Chip Fukuhara <cfukuhara@google.com>
Testability-Review: Chip Fukuhara <cfukuhara@google.com>
diff --git a/garnet/bin/setui/src/agent/authority_impl.rs b/garnet/bin/setui/src/agent/authority_impl.rs
index 1960dfd..f5cb21e 100644
--- a/garnet/bin/setui/src/agent/authority_impl.rs
+++ b/garnet/bin/setui/src/agent/authority_impl.rs
@@ -9,8 +9,10 @@
use crate::internal::switchboard;
use crate::message::base::{Audience, MessengerType};
use crate::service_context::ServiceContextHandle;
+use crate::switchboard::base::SettingType;
use anyhow::{format_err, Error};
use async_trait::async_trait;
+use std::collections::HashSet;
/// AuthorityImpl is the default implementation of the Authority trait. It
/// provides the ability to execute agents sequentially or simultaneously for a
@@ -26,6 +28,8 @@
messenger: agent::message::Messenger,
// Factory to generate event messengers
event_factory: event::message::Factory,
+ // Available components
+ available_components: HashSet<SettingType>,
}
impl AuthorityImpl {
@@ -33,6 +37,7 @@
messenger_factory: agent::message::Factory,
switchboard_messenger_factory: switchboard::message::Factory,
event_factory: event::message::Factory,
+ available_components: HashSet<SettingType>,
) -> Result<AuthorityImpl, Error> {
let messenger_result = messenger_factory.create(MessengerType::Unbound).await;
@@ -47,6 +52,7 @@
switchboard_messenger_factory,
messenger: client,
event_factory,
+ available_components,
});
}
@@ -128,6 +134,7 @@
blueprint.get_descriptor(),
self.switchboard_messenger_factory.clone(),
self.event_factory.clone(),
+ self.available_components.clone(),
)
.await,
)
diff --git a/garnet/bin/setui/src/agent/base.rs b/garnet/bin/setui/src/agent/base.rs
index d7883c3..bf55667 100644
--- a/garnet/bin/setui/src/agent/base.rs
+++ b/garnet/bin/setui/src/agent/base.rs
@@ -37,11 +37,11 @@
Component(&'static str),
}
-/// TODO(fxb/52428): Move lifecycle stage context contents here.
pub struct Context {
pub receptor: Receptor,
publisher: event::Publisher,
switchboard_messenger_factory: switchboard::message::Factory,
+ pub available_components: HashSet<SettingType>,
}
impl Context {
@@ -50,12 +50,14 @@
descriptor: Descriptor,
switchboard_messenger_factory: switchboard::message::Factory,
event_factory: event::message::Factory,
+ available_components: HashSet<SettingType>,
) -> Self {
Self {
receptor,
publisher: event::Publisher::create(&event_factory, event::Address::Agent(descriptor))
.await,
switchboard_messenger_factory,
+ available_components,
}
}
@@ -79,22 +81,12 @@
/// The scope of an agent's life. Initialization components should
/// only run at the beginning of the service. Service components follow
/// initialization and run for the duration of the service.
-#[derive(Clone, Debug)]
+#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Lifespan {
- Initialization(InitializationContext),
+ Initialization,
Service,
}
-#[derive(Clone, Debug)]
-pub struct InitializationContext {
- pub available_components: HashSet<SettingType>,
-}
-
-impl InitializationContext {
- pub fn new(components: HashSet<SettingType>) -> Self {
- Self { available_components: components }
- }
-}
/// Struct of information passed to the agent during each invocation.
#[derive(Clone, Debug)]
pub struct Invocation {
diff --git a/garnet/bin/setui/src/agent/earcons/agent.rs b/garnet/bin/setui/src/agent/earcons/agent.rs
index 141f998..2f423eb 100644
--- a/garnet/bin/setui/src/agent/earcons/agent.rs
+++ b/garnet/bin/setui/src/agent/earcons/agent.rs
@@ -61,34 +61,34 @@
async fn handle(&mut self, invocation: Invocation) -> InvocationResult {
// Only process service lifespans.
- if let Lifespan::Initialization(_context) = invocation.lifespan {
- let common_earcons_params = CommonEarconsParams {
- service_context: invocation.service_context,
- sound_player_added_files: Arc::new(Mutex::new(HashSet::new())),
- sound_player_connection: self.sound_player_connection.clone(),
- };
-
- if VolumeChangeHandler::create(
- common_earcons_params.clone(),
- self.switchboard_messenger.clone(),
- )
- .await
- .is_err()
- {
- // For now, report back as an error to prevent issues on
- // platforms that don't support the handler's dependencies.
- fx_log_err!("Could not set up VolumeChangeHandler");
- }
-
- fasync::spawn(async move {
- // Watch for bluetooth connections and play sounds on change.
- let bluetooth_connection_active = Arc::new(AtomicBool::new(true));
- watch_bluetooth_connections(common_earcons_params, bluetooth_connection_active);
- });
-
- return Ok(());
- } else {
+ if Lifespan::Initialization != invocation.lifespan {
return Err(AgentError::UnhandledLifespan);
}
+
+ let common_earcons_params = CommonEarconsParams {
+ service_context: invocation.service_context,
+ sound_player_added_files: Arc::new(Mutex::new(HashSet::new())),
+ sound_player_connection: self.sound_player_connection.clone(),
+ };
+
+ if VolumeChangeHandler::create(
+ common_earcons_params.clone(),
+ self.switchboard_messenger.clone(),
+ )
+ .await
+ .is_err()
+ {
+ // For now, report back as an error to prevent issues on
+ // platforms that don't support the handler's dependencies.
+ fx_log_err!("Could not set up VolumeChangeHandler");
+ }
+
+ fasync::spawn(async move {
+ // Watch for bluetooth connections and play sounds on change.
+ let bluetooth_connection_active = Arc::new(AtomicBool::new(true));
+ watch_bluetooth_connections(common_earcons_params, bluetooth_connection_active);
+ });
+
+ return Ok(());
}
}
diff --git a/garnet/bin/setui/src/agent/restore_agent.rs b/garnet/bin/setui/src/agent/restore_agent.rs
index 4dbe46b..7e0f54e 100644
--- a/garnet/bin/setui/src/agent/restore_agent.rs
+++ b/garnet/bin/setui/src/agent/restore_agent.rs
@@ -10,10 +10,11 @@
use crate::internal::event::{restore, Event, Publisher};
use crate::internal::switchboard;
use crate::message::base::{Audience, MessageEvent};
-use crate::switchboard::base::{SettingRequest, SwitchboardError};
+use crate::switchboard::base::{SettingRequest, SettingType, SwitchboardError};
use fuchsia_async as fasync;
use fuchsia_syslog::{fx_log_err, fx_log_info};
use futures::StreamExt;
+use std::collections::HashSet;
blueprint_definition!(
crate::agent::base::Descriptor::Component("restore_agent"),
@@ -24,6 +25,7 @@
pub struct RestoreAgent {
switchboard_messenger: switchboard::message::Messenger,
event_publisher: Publisher,
+ available_components: HashSet<SettingType>,
}
impl RestoreAgent {
@@ -40,6 +42,7 @@
let mut agent = RestoreAgent {
switchboard_messenger: messenger,
event_publisher: context.get_publisher(),
+ available_components: context.available_components.clone(),
};
fasync::spawn(async move {
@@ -52,9 +55,9 @@
}
async fn handle(&mut self, invocation: Invocation) -> InvocationResult {
- match invocation.lifespan.clone() {
- Lifespan::Initialization(context) => {
- for component in context.available_components {
+ match invocation.lifespan {
+ Lifespan::Initialization => {
+ for component in self.available_components.clone() {
let mut receptor = self
.switchboard_messenger
.message(
diff --git a/garnet/bin/setui/src/lib.rs b/garnet/bin/setui/src/lib.rs
index 3d13f05..5167ed7 100644
--- a/garnet/bin/setui/src/lib.rs
+++ b/garnet/bin/setui/src/lib.rs
@@ -9,9 +9,7 @@
crate::accessibility::accessibility_controller::AccessibilityController,
crate::account::account_controller::AccountController,
crate::agent::authority_impl::AuthorityImpl,
- crate::agent::base::{
- Authority, BlueprintHandle as AgentBlueprintHandle, InitializationContext, Lifespan,
- },
+ crate::agent::base::{Authority, BlueprintHandle as AgentBlueprintHandle, Lifespan},
crate::audio::audio_controller::AudioController,
crate::config::base::ControllerFlag,
crate::device::device_controller::DeviceController,
@@ -446,6 +444,7 @@
internal::agent::message::create_hub(),
switchboard_messenger_factory.clone(),
event_messenger_factory.clone(),
+ components.clone(),
)
.await?;
@@ -575,11 +574,7 @@
// Execute initialization agents sequentially
if agent_authority
- .execute_lifespan(
- Lifespan::Initialization(InitializationContext { available_components: components }),
- service_context_handle.clone(),
- true,
- )
+ .execute_lifespan(Lifespan::Initialization, service_context_handle.clone(), true)
.await
.is_err()
{
diff --git a/garnet/bin/setui/src/tests/agent_tests.rs b/garnet/bin/setui/src/tests/agent_tests.rs
index 1b3b521..538881e 100644
--- a/garnet/bin/setui/src/tests/agent_tests.rs
+++ b/garnet/bin/setui/src/tests/agent_tests.rs
@@ -5,8 +5,7 @@
#[cfg(test)]
use crate::agent::authority_impl::AuthorityImpl;
use crate::agent::base::{
- AgentError, Authority, BlueprintHandle, Context, InitializationContext, Invocation,
- InvocationResult, Lifespan,
+ AgentError, Authority, BlueprintHandle, Context, Invocation, InvocationResult, Lifespan,
};
use crate::internal::agent;
use crate::internal::event;
@@ -117,7 +116,7 @@
async fn handle(&mut self, invocation: Invocation) -> InvocationResult {
match invocation.lifespan.clone() {
- Lifespan::Initialization(_) => {
+ Lifespan::Initialization => {
if self.lifespan_target != LifespanTarget::Initialization {
return Err(AgentError::UnhandledLifespan);
}
@@ -208,6 +207,7 @@
agent::message::create_hub(),
switchboard::message::create_hub(),
event::message::create_hub(),
+ HashSet::new(),
)
.await
.unwrap()
@@ -248,11 +248,7 @@
// Ensure lifespan execution completes.
assert!(authority
- .execute_lifespan(
- Lifespan::Initialization(InitializationContext::new(HashSet::new(),)),
- service_context,
- true,
- )
+ .execute_lifespan(Lifespan::Initialization, service_context, true,)
.await
.is_ok());
}
@@ -289,11 +285,7 @@
// Execute lifespan non-sequentially.
assert!(authority
- .execute_lifespan(
- Lifespan::Initialization(InitializationContext::new(HashSet::new(),)),
- service_context,
- false,
- )
+ .execute_lifespan(Lifespan::Initialization, service_context, false,)
.await
.is_ok());
}
@@ -339,70 +331,13 @@
// Execute lifespan sequentially. Should fail since agent 2 returns an error.
assert!(authority
- .execute_lifespan(
- Lifespan::Initialization(InitializationContext::new(HashSet::new(),)),
- service_context,
- true,
- )
+ .execute_lifespan(Lifespan::Initialization, service_context, true,)
.await
.is_err());
assert!(agent2_lock.lock().await.last_invocation().is_none());
}
-/// Checks to see if available components are passed properly from
-/// execute_lifespan.
-#[fuchsia_async::run_until_stalled(test)]
-async fn test_available_components() {
- let (tx, mut rx) = futures::channel::mpsc::unbounded::<(u32, Invocation, AckSender)>();
- let mut authority = create_authority().await;
- let service_context = ServiceContext::create(None);
- let mut rng = rand::thread_rng();
-
- let agent_id = TestAgent::create_and_register(
- rng.gen(),
- LifespanTarget::Initialization,
- &mut authority,
- tx.clone(),
- )
- .await
- .unwrap()
- .lock()
- .await
- .id();
-
- let mut available_components = HashSet::new();
-
- available_components.insert(SettingType::Display);
- available_components.insert(SettingType::Intl);
-
- let available_components_clone = available_components.clone();
- fasync::spawn(async move {
- // Ensure the first agent received an invocation and verify components match
- if let Some((id, invocation, tx)) = rx.next().await {
- assert_eq!(agent_id, id);
- if let Lifespan::Initialization(context) = invocation.lifespan.clone() {
- assert_eq!(available_components_clone, context.available_components);
- assert!(tx.send(Ok(())).is_ok());
- } else {
- panic!("should have encountered initialization lifespan");
- }
- } else {
- panic!("did not receive expected response from agent");
- }
- });
-
- // Execute lifespan sequentially
- assert!(authority
- .execute_lifespan(
- Lifespan::Initialization(InitializationContext::new(available_components.clone(),)),
- service_context,
- true,
- )
- .await
- .is_ok());
-}
-
async fn create_agents(
count: u32,
lifespan_target: LifespanTarget,