blob: 8b8574ef2e1cc1a7120521dec8f9a52f303ca6c5 [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::model::{
error::ModelError,
hooks::{Event, EventError, EventErrorPayload, EventPayload},
realm::{Component, Realm, RealmState, WeakExtendedRealm},
resolver::Resolver,
},
moniker::ChildMoniker,
std::convert::TryFrom,
std::sync::Arc,
};
pub(super) async fn do_resolve(realm: &Arc<Realm>) -> Result<Component, ModelError> {
let result = async move {
let component = realm
.environment
.resolve(&realm.component_url)
.await
.map_err(|err| ModelError::from(err))?;
let component = Component::try_from(component)?;
let created_new_realm_state = {
let mut state = realm.lock_state().await;
if state.is_none() {
*state = Some(RealmState::new(realm, component.decl.clone()).await?);
true
} else {
false
}
};
Ok((created_new_realm_state, component))
}
.await;
// If a `RealmState` was installed in this call, first dispatch
// `Resolved` for the component itrealm and then dispatch
// `Discovered` for every static child that was discovered in the
// manifest.
match result {
Ok((false, component)) => Ok(component),
Ok((true, component)) => {
if let WeakExtendedRealm::AboveRoot(_) = &realm.parent {
let event = Event::new(realm, Ok(EventPayload::Discovered));
realm.hooks.dispatch(&event).await?;
}
let event =
Event::new(realm, Ok(EventPayload::Resolved { decl: component.decl.clone() }));
realm.hooks.dispatch(&event).await?;
for child in component.decl.children.iter() {
let child_moniker = ChildMoniker::new(child.name.clone(), None, 0);
let child_abs_moniker = realm.abs_moniker.child(child_moniker);
let event = Event::child_discovered(child_abs_moniker, child.url.clone());
realm.hooks.dispatch(&event).await?;
}
Ok(component)
}
Err(e) => {
let event = Event::new(realm, Err(EventError::new(&e, EventErrorPayload::Resolved)));
realm.hooks.dispatch(&event).await?;
Err(e)
}
}
}