pub async fn open_capability_at_source(
    flags: u32,
    open_mode: u32,
    relative_path: PathBuf,
    source: CapabilitySource,
    target: &Arc<ComponentInstance>,
    server_chan: &mut zx::Channel,
) -> Result<(), ModelError> {
    target.try_get_context()?.policy().can_route_capability(&source, &target.abs_moniker)?;

    // When serving a collection, routing hasn't reached the source. The CapabilityRouted event
    // should not fire, nor should hooks be able to modify the provider (which is hosted by
    // component_manager). Once a component is routed to from the collection, CapabilityRouted will
    // fire as usual.
    match source {
        CapabilitySource::Collection { capability_provider, component, .. } => {
            return serve_collection(
                target.as_weak(),
                &component.upgrade()?,
                capability_provider,
                flags,
                open_mode,
                relative_path,
                server_chan,
            )
            .await;
        }
        _ => {}
    }

    let capability_provider = Arc::new(Mutex::new(get_default_provider(target.as_weak(), &source)));

    let event = Event::new(
        &target,
        Ok(EventPayload::CapabilityRouted {
            source: source.clone(),
            capability_provider: capability_provider.clone(),
        }),
    );
    // Get a capability provider from the tree
    target.hooks.dispatch(&event).await?;

    // This hack changes the flags for a scoped framework service
    let mut flags = flags;
    if let CapabilitySource::Framework { .. } = source {
        flags = SERVICE_OPEN_FLAGS;
    }

    let capability_provider = capability_provider.lock().await.take();

    // If a hook in the component tree gave a capability provider, then use it.
    if let Some(capability_provider) = capability_provider {
        if let Some(task) =
            capability_provider.open(flags, open_mode, relative_path, server_chan).await?.take()
        {
            let source_instance = source.source_instance().upgrade()?;
            match source_instance {
                ExtendedInstance::AboveRoot(top) => {
                    top.add_task(task).await;
                }
                ExtendedInstance::Component(component) => {
                    component.add_task(task).await;
                }
            }
        }
        Ok(())
    } else {
        // TODO(fsamuel): This is a temporary hack. If a global path-based framework capability
        // is not provided by a hook in the component tree, then attempt to connect to the service
        // in component manager's namespace. We could have modeled this as a default provider,
        // but several hooks (such as WorkScheduler) require that a provider is not set.
        let namespace_path = match &source {
            CapabilitySource::Component { .. } => {
                unreachable!(
                    "Capability source is a component, which should have been caught by \
                    default_capability_provider: {:?}",
                    source
                );
            }
            CapabilitySource::Framework { capability, component } => {
                return Err(RoutingError::capability_from_framework_not_found(
                    &component.moniker,
                    capability.source_name().to_string(),
                )
                .into());
            }
            CapabilitySource::Capability { source_capability, component } => {
                return Err(RoutingError::capability_from_capability_not_found(
                    &component.moniker,
                    source_capability.to_string(),
                )
                .into());
            }
            CapabilitySource::Builtin { capability, .. } => {
                return Err(ModelError::from(
                    RoutingError::capability_from_component_manager_not_found(
                        capability.source_name().to_string(),
                    ),
                ));
            }
            CapabilitySource::Namespace { capability, .. } => match capability.source_path() {
                Some(p) => p.clone(),
                _ => {
                    return Err(ModelError::from(
                        RoutingError::capability_from_component_manager_not_found(
                            capability.source_id(),
                        ),
                    ));
                }
            },
            CapabilitySource::Collection { .. } => {
                return Err(ModelError::unsupported("collections"));
            }
        };
        let namespace_path = namespace_path.to_path_buf().attach(relative_path);
        let namespace_path = namespace_path
            .to_str()
            .ok_or_else(|| ModelError::path_is_not_utf8(namespace_path.clone()))?;
        let server_chan = channel::take_channel(server_chan);
        io_util::connect_in_namespace(namespace_path, server_chan, flags).map_err(|e| {
            OpenResourceError::open_component_manager_namespace_failed(namespace_path, e).into()
        })
    }
}
/// Opens the capability at `source`, triggering a `CapabilityRouted` event and binding
/// to the source component instance if necessary.
///
/// If the capability is not allowed to be routed to the `target`, per the
/// [`crate::model::policy::GlobalPolicyChecker`], the capability is not opened and an error
/// is returned.
///
/// See [`fidl_fuchsia_io::Directory::Open`] for how the `flags`, `open_mode`, `relative_path`,
/// and `server_chan` parameters are used in the open call.
Opens the capability at `source`, triggering a `CapabilityRouted` event and binding
to the source component instance if necessary.




Opens the capability at ` source ` triggering a ` CapabilityRouted ` event and binding to the source component instance if necessary .
pub async fn open_capability_at_source(
    flags: u32,
    open_mode: u32,
    relative_path: PathBuf,
    source: CapabilitySource,
    target: &Arc<ComponentInstance>,
    server_chan: &mut zx::Channel,
) -> Result<(), ModelError> {
    target.try_get_context()?.policy().can_route_capability(&source, &target.abs_moniker)?;
    // When serving a collection, routing hasn't reached the source. The CapabilityRouted event
    // should not fire, nor should hooks be able to modify the provider (which is hosted by
    // component_manager). Once a component is routed to from the collection, CapabilityRouted will
    // fire as usual.
    match source {
        CapabilitySource::Collection { capability_provider, component, .. } => {
            return serve_collection(
                target.as_weak(),
                &component.upgrade()?,
                capability_provider,
                flags,
                open_mode,
                relative_path,
                server_chan,
            )
            .await;
        }
        _ => {}
    }
    let capability_provider = Arc::new(Mutex::new(get_default_provider(target.as_weak(), &source)));
    let event = Event::new(
        &target,
        Ok(EventPayload::CapabilityRouted {
            source: source.clone(),
            capability_provider: capability_provider.clone(),
        }),
    );
    // Get a capability provider from the tree
    target.hooks.dispatch(&event).await?;
    // This hack changes the flags for a scoped framework service
    let mut flags = flags;
    if let CapabilitySource::Framework { .. } = source {
        flags = SERVICE_OPEN_FLAGS;
    }
    let capability_provider = capability_provider.lock().await.take();
    // If a hook in the component tree gave a capability provider, then use it.
    if let Some(capability_provider) = capability_provider {
        if let Some(task) =
            capability_provider.open(flags, open_mode, relative_path, server_chan).await?.take()
        {
            let source_instance = source.source_instance().upgrade()?;
            match source_instance {
                ExtendedInstance::AboveRoot(top) => {
                    top.add_task(task).await;
                }
                ExtendedInstance::Component(component) => {
                    component.add_task(task).await;
                }
            }
        }
        Ok(())
    } else {
        // TODO(fsamuel): This is a temporary hack. If a global path-based framework capability
        // is not provided by a hook in the component tree, then attempt to connect to the service
        // in component manager's namespace. We could have modeled this as a default provider,
        // but several hooks (such as WorkScheduler) require that a provider is not set.
        let namespace_path = match &source {
            CapabilitySource::Component { .. } => {
                unreachable!(
                    "Capability source is a component, which should have been caught by \
                    default_capability_provider: {:?}",
                    source
                );
            }
            CapabilitySource::Framework { capability, component } => {
                return Err(RoutingError::capability_from_framework_not_found(
                    &component.moniker,
                    capability.source_name().to_string(),
                )
                .into());
            }
            CapabilitySource::Capability { source_capability, component } => {
                return Err(RoutingError::capability_from_capability_not_found(
                    &component.moniker,
                    source_capability.to_string(),
                )
                .into());
            }
            CapabilitySource::Builtin { capability, .. } => {
                return Err(ModelError::from(
                    RoutingError::capability_from_component_manager_not_found(
                        capability.source_name().to_string(),
                    ),
                ));
            }
            CapabilitySource::Namespace { capability, .. } => match capability.source_path() {
                Some(p) => p.clone(),
                _ => {
                    return Err(ModelError::from(
                        RoutingError::capability_from_component_manager_not_found(
                            capability.source_id(),
                        ),
                    ));
                }
            },
            CapabilitySource::Collection { .. } => {
                return Err(ModelError::unsupported("collections"));
            }
        };
        let namespace_path = namespace_path.to_path_buf().attach(relative_path);
        let namespace_path = namespace_path
            .to_str()
            .ok_or_else(|| ModelError::path_is_not_utf8(namespace_path.clone()))?;
        let server_chan = channel::take_channel(server_chan);
        io_util::connect_in_namespace(namespace_path, server_chan, flags).map_err(|e| {
            OpenResourceError::open_component_manager_namespace_failed(namespace_path, e).into()
        })
    }
}
pub async fn open_capability_at_source ( flags : u32 , open_mode : u32 , relative_path : PathBuf , source : CapabilitySource , target : & Arc < ComponentInstance > , server_chan : & mut zx :: Channel , ) -> Result < ( ) , ModelError > { target . try_get_context ( ) ? . policy ( ) . can_route_capability ( & source , & target . abs_moniker ) ? ; // When serving a collection, routing hasn't reached the source. The CapabilityRouted event // should not fire, nor should hooks be able to modify the provider (which is hosted by // component_manager). Once a component is routed to from the collection, CapabilityRouted will // fire as usual. match source { CapabilitySource :: Collection { capability_provider , component , .. } => { return serve_collection ( target . as_weak ( ) , & component . upgrade ( ) ? , capability_provider , flags , open_mode , relative_path , server_chan , ) . await ; } _ => { } } let capability_provider = Arc :: new ( Mutex :: new ( get_default_provider ( target . as_weak ( ) , & source ) ) ) ; let event = Event :: new ( & target , Ok ( EventPayload :: CapabilityRouted { source : source . clone ( ) , capability_provider : capability_provider . clone ( ) , } ) , ) ; // Get a capability provider from the tree target . hooks . dispatch ( & event ) . await ? ; // This hack changes the flags for a scoped framework service let mut flags = flags ; if let CapabilitySource :: Framework { .. } = source { flags = SERVICE_OPEN_FLAGS ; } let capability_provider = capability_provider . lock ( ) . await . take ( ) ; // If a hook in the component tree gave a capability provider, then use it. if let Some ( capability_provider ) = capability_provider { if let Some ( task ) = capability_provider . open ( flags , open_mode , relative_path , server_chan ) . await ? . take ( ) { let source_instance = source . source_instance ( ) . upgrade ( ) ? ; match source_instance { ExtendedInstance :: AboveRoot ( top ) => { top . add_task ( task ) . await ; } ExtendedInstance :: Component ( component ) => { component . add_task ( task ) . await ; } } } Ok ( ( ) ) } else { // TODO(fsamuel): This is a temporary hack. If a global path-based framework capability // is not provided by a hook in the component tree, then attempt to connect to the service // in component manager's namespace. We could have modeled this as a default provider, // but several hooks (such as WorkScheduler) require that a provider is not set. let namespace_path = match & source { CapabilitySource :: Component { .. } => { unreachable ! ( " \
 " source ) ; } CapabilitySource :: Framework { capability , component } => { return Err ( RoutingError :: capability_from_framework_not_found ( & component . moniker , capability . source_name ( ) . to_string ( ) , ) . into ( ) ) ; } CapabilitySource :: Capability { source_capability , component } => { return Err ( RoutingError :: capability_from_capability_not_found ( & component . moniker , source_capability . to_string ( ) , ) . into ( ) ) ; } CapabilitySource :: Builtin { capability , .. } => { return Err ( ModelError :: from ( RoutingError :: capability_from_component_manager_not_found ( capability . source_name ( ) . to_string ( ) , ) , ) ) ; } CapabilitySource :: Namespace { capability , .. } => match capability . source_path ( ) { Some ( p ) => p . clone ( ) , _ => { return Err ( ModelError :: from ( RoutingError :: capability_from_component_manager_not_found ( capability . source_id ( ) , ) , ) ) ; } } , CapabilitySource :: Collection { .. } => { return Err ( ModelError :: unsupported ( " " ) ) ; } } ; let namespace_path = namespace_path . to_path_buf ( ) . attach ( relative_path ) ; let namespace_path = namespace_path . to_str ( ) . ok_or_else ( | | ModelError :: path_is_not_utf8 ( namespace_path . clone ( ) ) ) ? ; let server_chan = channel :: take_channel ( server_chan ) ; io_util :: connect_in_namespace ( namespace_path , server_chan , flags ) . map_err ( | e | { OpenResourceError :: open_component_manager_namespace_failed ( namespace_path , e ) . into ( ) } ) } }
Opens the capability at `source`, triggering a `CapabilityRouted` event and binding
to the source component instance if necessary.
Opens the capability at ` source ` triggering a ` CapabilityRouted ` event and binding to the source component instance if necessary .
flags
u32
open_mode
u32
relative_path
PathBuf
source
CapabilitySource
target
&Arc<ComponentInstance>
server_chan
&mut zx::Channel
flags
u32
open_mode
u32
relative_path
PathBuf
source
CapabilitySource
target
&Arc<ComponentInstance>
server_chan
&mut zx::Channel