Skip to content

Commit

Permalink
looper: Model ALOOPER_EVENT with bitflags (#158)
Browse files Browse the repository at this point in the history
The `event` field/parameter cannot have more states than these few
carefully defined constants, and should be exposed as a proper
restricted type since it's part of the public API.
  • Loading branch information
MarijnS95 committed Jul 24, 2021
1 parent e533042 commit 49e8ed5
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 42 deletions.
1 change: 1 addition & 0 deletions ndk-glue/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Unreleased

- Reexport `android_logger` and `log` from the crate root for `ndk-macro` to use.
- Use new `FdEvents` `bitflags` for looper file descriptor events.

# 0.3.0 (2021-01-30)

Expand Down
6 changes: 3 additions & 3 deletions ndk-glue/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use lazy_static::lazy_static;
use log::Level;
use ndk::input_queue::InputQueue;
use ndk::looper::{ForeignLooper, ThreadLooper};
use ndk::looper::{FdEvent, ForeignLooper, ThreadLooper};
use ndk::native_activity::NativeActivity;
use ndk::native_window::NativeWindow;
use ndk_sys::{AInputQueue, ANativeActivity, ANativeWindow, ARect, ALOOPER_EVENT_INPUT};
use ndk_sys::{AInputQueue, ANativeActivity, ANativeWindow, ARect};
use std::ffi::{CStr, CString};
use std::fs::File;
use std::io::{BufRead, BufReader};
Expand Down Expand Up @@ -187,7 +187,7 @@ pub unsafe fn init(
.add_fd(
PIPE[0],
NDK_GLUE_LOOPER_EVENT_PIPE_IDENT,
ALOOPER_EVENT_INPUT as _,
FdEvent::INPUT,
std::ptr::null_mut(),
)
.unwrap();
Expand Down
2 changes: 2 additions & 0 deletions ndk/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- **Breaking** Model looper file descriptor events integer as `bitflags`.

# 0.3.0 (2021-01-30)

- **Breaking** Looper `ident` not passed in `data` pointer anymore.
Expand Down
3 changes: 2 additions & 1 deletion ndk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ api-level-30 = ["api-level-29"]
test = ["ffi/test", "jni", "jni-glue", "all"]

[dependencies]
num_enum = "0.5.1"
bitflags = "1.2.1"
jni-sys = "0.3.0"
num_enum = "0.5.1"
thiserror = "1.0.23"

[dependencies.jni]
Expand Down
100 changes: 62 additions & 38 deletions ndk/src/looper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//! thread; and
//! * [`ForeignLooper`], which has methods for the operations performable with any thread's looper.

use bitflags::bitflags;
use std::convert::TryInto;
use std::os::raw::c_void;
use std::os::unix::io::RawFd;
Expand All @@ -23,6 +24,17 @@ pub struct ThreadLooper {
foreign: ForeignLooper,
}

bitflags! {
/// Flags for file descriptor events that a looper can monitor.
pub struct FdEvent: u32 {
const INPUT = ffi::ALOOPER_EVENT_INPUT;
const OUTPUT = ffi::ALOOPER_EVENT_OUTPUT;
const ERROR = ffi::ALOOPER_EVENT_ERROR;
const HANGUP = ffi::ALOOPER_EVENT_HANGUP;
const INVALID = ffi::ALOOPER_EVENT_INVALID;
}
}

/// The poll result from a [`ThreadLooper`].
#[derive(Debug)]
pub enum Poll {
Expand All @@ -36,7 +48,7 @@ pub enum Poll {
Event {
ident: i32,
fd: RawFd,
events: i32,
events: FdEvent,
data: *mut c_void,
},
}
Expand Down Expand Up @@ -67,23 +79,22 @@ impl ThreadLooper {
}

fn poll_once_ms(&self, ms: i32) -> Result<Poll, LooperError> {
unsafe {
let mut fd: RawFd = -1;
let mut events: i32 = -1;
let mut data: *mut c_void = ptr::null_mut();
match ffi::ALooper_pollOnce(ms, &mut fd, &mut events, &mut data) {
ffi::ALOOPER_POLL_WAKE => Ok(Poll::Wake),
ffi::ALOOPER_POLL_CALLBACK => Ok(Poll::Callback),
ffi::ALOOPER_POLL_TIMEOUT => Ok(Poll::Timeout),
ffi::ALOOPER_POLL_ERROR => Err(LooperError),
ident if ident >= 0 => Ok(Poll::Event {
ident,
fd,
events,
data,
}),
_ => unreachable!(),
}
let mut fd: RawFd = -1;
let mut events: i32 = -1;
let mut data: *mut c_void = ptr::null_mut();
match unsafe { ffi::ALooper_pollOnce(ms, &mut fd, &mut events, &mut data) } {
ffi::ALOOPER_POLL_WAKE => Ok(Poll::Wake),
ffi::ALOOPER_POLL_CALLBACK => Ok(Poll::Callback),
ffi::ALOOPER_POLL_TIMEOUT => Ok(Poll::Timeout),
ffi::ALOOPER_POLL_ERROR => Err(LooperError),
ident if ident >= 0 => Ok(Poll::Event {
ident,
fd,
events: FdEvent::from_bits(events as u32)
.expect("poll event contains unknown bits"),
data,
}),
_ => unreachable!(),
}
}

Expand All @@ -109,22 +120,21 @@ impl ThreadLooper {
}

fn poll_all_ms(&self, ms: i32) -> Result<Poll, LooperError> {
unsafe {
let mut fd: RawFd = -1;
let mut events: i32 = -1;
let mut data: *mut c_void = ptr::null_mut();
match ffi::ALooper_pollAll(ms, &mut fd, &mut events, &mut data) {
ffi::ALOOPER_POLL_WAKE => Ok(Poll::Wake),
ffi::ALOOPER_POLL_TIMEOUT => Ok(Poll::Timeout),
ffi::ALOOPER_POLL_ERROR => Err(LooperError),
ident if ident >= 0 => Ok(Poll::Event {
ident,
fd,
events,
data,
}),
_ => unreachable!(),
}
let mut fd: RawFd = -1;
let mut events: i32 = -1;
let mut data: *mut c_void = ptr::null_mut();
match unsafe { ffi::ALooper_pollAll(ms, &mut fd, &mut events, &mut data) } {
ffi::ALOOPER_POLL_WAKE => Ok(Poll::Wake),
ffi::ALOOPER_POLL_TIMEOUT => Ok(Poll::Timeout),
ffi::ALOOPER_POLL_ERROR => Err(LooperError),
ident if ident >= 0 => Ok(Poll::Event {
ident,
fd,
events: FdEvent::from_bits(events as u32)
.expect("poll event contains unknown bits"),
data,
}),
_ => unreachable!(),
}
}

Expand Down Expand Up @@ -224,10 +234,17 @@ impl ForeignLooper {
&self,
fd: RawFd,
ident: i32,
event: i32,
events: FdEvent,
data: *mut c_void,
) -> Result<(), LooperError> {
match ffi::ALooper_addFd(self.ptr.as_ptr(), fd, ident, event, None, data) {
match ffi::ALooper_addFd(
self.ptr.as_ptr(),
fd,
ident,
events.bits() as i32,
None,
data,
) {
1 => Ok(()),
-1 => Err(LooperError),
_ => unreachable!(),
Expand All @@ -246,7 +263,7 @@ impl ForeignLooper {
&self,
fd: RawFd,
ident: i32,
event: i32,
events: FdEvent,
callback: Box<dyn FnMut(RawFd) -> bool>,
) -> Result<(), LooperError> {
extern "C" fn cb_handler(fd: RawFd, _events: i32, data: *mut c_void) -> i32 {
Expand All @@ -256,7 +273,14 @@ impl ForeignLooper {
}
}
let data: *mut c_void = Box::into_raw(Box::new(callback)) as *mut _;
match ffi::ALooper_addFd(self.ptr.as_ptr(), fd, ident, event, Some(cb_handler), data) {
match ffi::ALooper_addFd(
self.ptr.as_ptr(),
fd,
ident,
events.bits() as i32,
Some(cb_handler),
data,
) {
1 => Ok(()),
-1 => Err(LooperError),
_ => unreachable!(),
Expand Down

0 comments on commit 49e8ed5

Please sign in to comment.