Merge "UWB: Cleanup in default HAL" into main

This commit is contained in:
Henri Chataing 2023-10-06 00:11:30 +00:00 committed by Gerrit Code Review
commit ed2acd8952
2 changed files with 16 additions and 16 deletions

View file

@ -15,6 +15,7 @@ rust_binary {
prefer_rlib: true, prefer_rlib: true,
rustlibs: [ rustlibs: [
"android.hardware.uwb-V1-rust", "android.hardware.uwb-V1-rust",
"liblibc",
"liblogger", "liblogger",
"liblog_rust", "liblog_rust",
"libbinder_rs", "libbinder_rs",

View file

@ -6,7 +6,6 @@ use android_hardware_uwb::binder;
use async_trait::async_trait; use async_trait::async_trait;
use binder::{DeathRecipient, IBinder, Result, Strong}; use binder::{DeathRecipient, IBinder, Result, Strong};
use log::info;
use std::sync::Arc; use std::sync::Arc;
use tokio::io::unix::AsyncFd; use tokio::io::unix::AsyncFd;
use tokio::select; use tokio::select;
@ -16,12 +15,13 @@ use tokio_util::sync::CancellationToken;
use std::fs::{File, OpenOptions}; use std::fs::{File, OpenOptions};
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use std::os::fd::AsRawFd; use std::os::fd::AsRawFd;
use std::os::unix::fs::OpenOptionsExt;
enum State { enum State {
Closed, Closed,
Opened { Opened {
callbacks: Strong<dyn IUwbClientCallback>, callbacks: Strong<dyn IUwbClientCallback>,
_handle: tokio::task::JoinHandle<()>, handle: tokio::task::JoinHandle<()>,
serial: File, serial: File,
death_recipient: DeathRecipient, death_recipient: DeathRecipient,
token: CancellationToken, token: CancellationToken,
@ -46,12 +46,12 @@ impl UwbChip {
impl State { impl State {
/// Terminate the reader task. /// Terminate the reader task.
#[allow(dead_code)] async fn close(&mut self) -> Result<()> {
fn close(&mut self) -> Result<()> { if let State::Opened { ref mut token, ref callbacks, ref mut death_recipient, ref mut handle, .. } = *self {
if let State::Opened { ref mut token, ref callbacks, ref mut death_recipient, .. } = *self {
log::info!("waiting for task cancellation"); log::info!("waiting for task cancellation");
callbacks.as_binder().unlink_to_death(death_recipient)?; callbacks.as_binder().unlink_to_death(death_recipient)?;
token.cancel(); token.cancel();
handle.await.unwrap();
log::info!("task successfully cancelled"); log::info!("task successfully cancelled");
callbacks.onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK)?; callbacks.onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK)?;
*self = State::Closed; *self = State::Closed;
@ -69,11 +69,6 @@ pub fn makeraw(file: File) -> io::Result<File> {
cfmakeraw(&mut attrs); cfmakeraw(&mut attrs);
tcsetattr(fd, SetArg::TCSANOW, &attrs)?; tcsetattr(fd, SetArg::TCSANOW, &attrs)?;
// Configure the file descriptor as non blocking.
use nix::fcntl::*;
let flags = OFlag::from_bits(fcntl(fd, FcntlArg::F_GETFL)?).unwrap();
fcntl(fd, FcntlArg::F_SETFL(flags | OFlag::O_NONBLOCK))?;
Ok(file) Ok(file)
} }
@ -114,6 +109,7 @@ impl IUwbChipAsyncServer for UwbChip {
.read(true) .read(true)
.write(true) .write(true)
.create(false) .create(false)
.custom_flags(libc::O_NONBLOCK)
.open(&self.path) .open(&self.path)
.and_then(makeraw) .and_then(makeraw)
.map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?; .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
@ -122,7 +118,10 @@ impl IUwbChipAsyncServer for UwbChip {
let mut death_recipient = DeathRecipient::new(move || { let mut death_recipient = DeathRecipient::new(move || {
let mut state = state_death_recipient.blocking_lock(); let mut state = state_death_recipient.blocking_lock();
log::info!("Uwb service has died"); log::info!("Uwb service has died");
state.close().unwrap(); if let State::Opened { ref mut token, .. } = *state {
token.cancel();
*state = State::Closed;
}
}); });
callbacks.as_binder().link_to_death(&mut death_recipient)?; callbacks.as_binder().link_to_death(&mut death_recipient)?;
@ -137,7 +136,7 @@ impl IUwbChipAsyncServer for UwbChip {
.map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?; .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
let join_handle = tokio::task::spawn(async move { let join_handle = tokio::task::spawn(async move {
info!("UCI reader task started"); log::info!("UCI reader task started");
let mut reader = AsyncFd::new(reader).unwrap(); let mut reader = AsyncFd::new(reader).unwrap();
loop { loop {
@ -159,7 +158,7 @@ impl IUwbChipAsyncServer for UwbChip {
// the OS will only notify Tokio when the file descriptor // the OS will only notify Tokio when the file descriptor
// transitions from not-ready to ready. For this to work // transitions from not-ready to ready. For this to work
// you should first try to read or write and only poll for // you should first try to read or write and only poll for
// readiness if that fails with an error of  // readiness if that fails with an error of
// std::io::ErrorKind::WouldBlock. // std::io::ErrorKind::WouldBlock.
match reader.get_mut().read(&mut buffer) { match reader.get_mut().read(&mut buffer) {
Ok(0) => { Ok(0) => {
@ -173,7 +172,7 @@ impl IUwbChipAsyncServer for UwbChip {
let mut guard = select! { let mut guard = select! {
_ = cloned_token.cancelled() => { _ = cloned_token.cancelled() => {
info!("task is cancelled!"); log::info!("task is cancelled!");
return; return;
}, },
result = reader.readable() => result.unwrap() result = reader.readable() => result.unwrap()
@ -199,7 +198,7 @@ impl IUwbChipAsyncServer for UwbChip {
*state = State::Opened { *state = State::Opened {
callbacks: callbacks.clone(), callbacks: callbacks.clone(),
_handle: join_handle, handle: join_handle,
serial, serial,
death_recipient, death_recipient,
token, token,
@ -214,7 +213,7 @@ impl IUwbChipAsyncServer for UwbChip {
let mut state = self.state.lock().await; let mut state = self.state.lock().await;
if matches!(*state, State::Opened { .. }) { if matches!(*state, State::Opened { .. }) {
state.close() state.close().await
} else { } else {
Err(binder::ExceptionCode::ILLEGAL_STATE.into()) Err(binder::ExceptionCode::ILLEGAL_STATE.into())
} }