system_update_committer/
fidl.rsuse anyhow::{anyhow, Context, Error};
use fidl_fuchsia_update::{CommitStatusProviderRequest, CommitStatusProviderRequestStream};
use fuchsia_component::server::{ServiceFs, ServiceObjLocal};
use futures::channel::oneshot;
use futures::prelude::*;
use std::sync::Arc;
use tracing::warn;
use zx::{self as zx, EventPair, HandleBased};
pub struct FidlServer {
p_external: EventPair,
blocker: future::Shared<oneshot::Receiver<()>>,
}
impl FidlServer {
pub fn new(p_external: EventPair, blocker: oneshot::Receiver<()>) -> Self {
Self { p_external, blocker: blocker.shared() }
}
pub async fn run(server: Arc<Self>, mut fs: ServiceFs<ServiceObjLocal<'_, IncomingService>>) {
fs.dir("svc").add_fidl_service(IncomingService::CommitStatusProvider);
fs.for_each_concurrent(None, |incoming_service| match incoming_service {
IncomingService::CommitStatusProvider(stream) => {
Self::handle_commit_status_provider_request_stream(Arc::clone(&server), stream)
.unwrap_or_else(|e| {
warn!(
"error handling fuchsia.update/CommitStatusProvider request stream: {:#}",
anyhow!(e)
)
})
}
})
.await;
}
async fn handle_commit_status_provider_request_stream(
server: Arc<Self>,
mut stream: CommitStatusProviderRequestStream,
) -> Result<(), Error> {
while let Some(request) =
stream.try_next().await.context("while receiving CommitStatusProvider request")?
{
let () =
Self::handle_commit_status_provider_request(Arc::clone(&server), request).await?;
}
Ok(())
}
async fn handle_commit_status_provider_request(
server: Arc<Self>,
req: CommitStatusProviderRequest,
) -> Result<(), Error> {
let () = server.blocker.clone().await.context("while unblocking fidl server")?;
let CommitStatusProviderRequest::IsCurrentSystemCommitted { responder } = req;
responder
.send(
server
.p_external
.duplicate_handle(zx::Rights::BASIC)
.context("while duplicating p_external")?,
)
.context("while sending IsCurrentSystemCommitted response")
}
}
pub enum IncomingService {
CommitStatusProvider(CommitStatusProviderRequestStream),
}