blob: f47310c2d86df0cc1d31bd1cd882912046b5ff30 [file] [log] [blame]
// Copyright 2019 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.
//! This module defines a watcher that subscribes to the device filesystem and
//! produces a stream of messages when bt-host devices are added or removed from
//! the system
use {
fuchsia_bluetooth::constants::HOST_DEVICE_DIR,
fuchsia_vfs_watcher::{self as vfs_watcher, WatchEvent, WatchMessage},
futures::{future, FutureExt, Stream, TryStreamExt},
io_util::{open_directory_in_namespace, OPEN_RIGHT_READABLE},
log::warn,
std::{
io,
path::{Path, PathBuf},
},
};
pub enum HostEvent {
HostAdded(PathBuf),
HostRemoved(PathBuf),
}
/// Watch the VFS for host devices being added or removed, and produce a stream of HostEvent messages
pub fn watch_hosts() -> impl Stream<Item = Result<HostEvent, io::Error>> {
async {
let directory = open_directory_in_namespace(HOST_DEVICE_DIR, OPEN_RIGHT_READABLE).unwrap();
let watcher = vfs_watcher::Watcher::new(directory)
.await
.expect("Cannot open vfs watcher for bt-host device path");
watcher.try_filter_map(|msg| future::ok(as_host_event(msg)))
}
.flatten_stream()
}
fn as_host_event(msg: WatchMessage) -> Option<HostEvent> {
let path = Path::new(HOST_DEVICE_DIR).join(&msg.filename);
match msg.event {
WatchEvent::EXISTING | WatchEvent::ADD_FILE => Some(HostEvent::HostAdded(path)),
WatchEvent::REMOVE_FILE => Some(HostEvent::HostRemoved(path)),
WatchEvent::IDLE => None,
e => {
warn!("Unrecognized host watch event: {:?}", e);
None
}
}
}