Skip to content

Commit

Permalink
ndk/event: Implement SourceClass bitflag and provide `Source::cla…
Browse files Browse the repository at this point in the history
…ss()` getter (#458)

* ndk/event: Implement `SourceClass` `bitflag` and provide `Source::class()` getter

This `enum` was never `pub` even though it serves a slight purpose to
more easily classify various event sources, which is accounted for in
the bitmask-like value of `AINPUT_SOURCE_XXX`.  Even though every source
currently only appears to use a single class value, the class variants
all describe an individual bit and should be treated as a bitflags type.

* ndk: Add `_ = !0` catch-all constant to all `bitflags`, allowing them to be extended

Android may return values in `bitflags` that are not yet mapped or
recognized in the `ndk` crate.  This makes functions like `all()` and
`!` behave unexpectedly when they truncate or limit their operation to
known bits exclusively.

A more likable solution is disabling functions that are susceptible to
this, as was done in the `ash` crate.
  • Loading branch information
MarijnS95 committed Jan 27, 2024
1 parent 12eb049 commit f216886
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 19 deletions.
2 changes: 2 additions & 0 deletions ndk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
- media_format: Expose `MediaFormat::copy()` and `MediaFormat::clear()` from API level 29. (#449)
- input_queue: Add `from_java()` constructor, available since API level 33. (#456)
- event: Add `from_java()` constructors to `KeyEvent` and `MotionEvent`, available since API level 31. (#456)
- event: Implement `SourceClass` `bitflag` and provide `Source::class()` getter. (#458)
- Ensure all `bitflags` implementations consider all (including unknown) bits in negation and `all()`. (#458)

# 0.8.0 (2023-10-15)

Expand Down
2 changes: 1 addition & 1 deletion ndk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ api-level-33 = ["api-level-32"]
test = ["ffi/test", "jni", "all"]

[dependencies]
bitflags = "2.2"
bitflags = "2.4" # At least 2.4.0 for `const _ = !0`
jni-sys = "0.3"
log = "0.4.6"
num_enum = "0.7"
Expand Down
38 changes: 26 additions & 12 deletions ndk/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,32 @@ pub enum Source {
Any = ffi::AINPUT_SOURCE_ANY,
}

/// An enum representing the class of an [`InputEvent`] source.
///
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-35)
#[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
#[repr(u32)]
enum Class {
None = ffi::AINPUT_SOURCE_CLASS_NONE,
Button = ffi::AINPUT_SOURCE_CLASS_BUTTON,
Pointer = ffi::AINPUT_SOURCE_CLASS_POINTER,
Navigation = ffi::AINPUT_SOURCE_CLASS_NAVIGATION,
Position = ffi::AINPUT_SOURCE_CLASS_POSITION,
Joystick = ffi::AINPUT_SOURCE_CLASS_JOYSTICK,
impl Source {
pub fn class(self) -> SourceClass {
let class = u32::from(self) & ffi::AINPUT_SOURCE_CLASS_MASK;
// The mask fits in a u8.
SourceClass::from_bits_retain(class as u8)
}
}

bitflags::bitflags! {
/// Flags representing the class of an [`InputEvent`] [`Source`].
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SourceClass : u8 {
#[doc(alias = "AINPUT_SOURCE_CLASS_BUTTON")]
const BUTTON = ffi::AINPUT_SOURCE_CLASS_BUTTON as u8;
#[doc(alias = "AINPUT_SOURCE_CLASS_POINTER")]
const POINTER = ffi::AINPUT_SOURCE_CLASS_POINTER as u8;
#[doc(alias = "AINPUT_SOURCE_CLASS_NAVIGATION")]
const NAVIGATION = ffi::AINPUT_SOURCE_CLASS_NAVIGATION as u8;
#[doc(alias = "AINPUT_SOURCE_CLASS_POSITION")]
const POSITION = ffi::AINPUT_SOURCE_CLASS_POSITION as u8;
#[doc(alias = "AINPUT_SOURCE_CLASS_JOYSTICK")]
const JOYSTICK = ffi::AINPUT_SOURCE_CLASS_JOYSTICK as u8;

// https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags
const _ = ffi::AINPUT_SOURCE_CLASS_MASK as u8;
}
}

impl InputEvent {
Expand Down
8 changes: 5 additions & 3 deletions ndk/src/looper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
//!
//! [`ALooper`]: https://developer.android.com/ndk/reference/group/looper#alooper

use bitflags::bitflags;
use std::mem::ManuallyDrop;
use std::os::{
fd::{AsRawFd, BorrowedFd, RawFd},
Expand All @@ -31,12 +30,12 @@ pub struct ThreadLooper {
foreign: ForeignLooper,
}

bitflags! {
bitflags::bitflags! {
/// Flags for file descriptor events that a looper can monitor.
///
/// These flag bits can be combined to monitor multiple events at once.
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct FdEvent: u32 {
pub struct FdEvent : u32 {
/// The file descriptor is available for read operations.
#[doc(alias = "ALOOPER_EVENT_INPUT")]
const INPUT = ffi::ALOOPER_EVENT_INPUT;
Expand Down Expand Up @@ -65,6 +64,9 @@ bitflags! {
/// necessary to specify this event flag in the requested event set.
#[doc(alias = "ALOOPER_EVENT_INVALID")]
const INVALID = ffi::ALOOPER_EVENT_INVALID;

// https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags
const _ = !0;
}
}

Expand Down
8 changes: 5 additions & 3 deletions ndk/src/native_activity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,21 @@
//! [`ANativeActivity`]: https://developer.android.com/ndk/reference/group/native-activity#anativeactivity

use super::hardware_buffer_format::HardwareBufferFormat;
use bitflags::bitflags;
use std::{
ffi::{CStr, OsStr},
os::{raw::c_void, unix::prelude::OsStrExt},
path::Path,
ptr::NonNull,
};

bitflags! {
bitflags::bitflags! {
/// Window flags, as per the Java API at [`android.view.WindowManager.LayoutParams`].
///
/// <https://developer.android.com/ndk/reference/group/native-activity#group___native_activity_1ga2f1398dba5e4a5616b83437528bdb28e>
///
/// [`android.view.WindowManager.LayoutParams`]: https://developer.android.com/reference/android/view/WindowManager.LayoutParams
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct WindowFlags: u32 {
pub struct WindowFlags : u32 {
const ALLOW_LOCK_WHILE_SCREEN_ON = ffi::AWINDOW_FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
const DIM_BEHIND = ffi::AWINDOW_FLAG_DIM_BEHIND;
#[deprecated = "Deprecated. Blurring is no longer supported."]
Expand Down Expand Up @@ -48,6 +47,9 @@ bitflags! {
#[cfg_attr(feature = "api-level-26", deprecated = "This constant was deprecated in API level 26. Use `SHOW_WHEN_LOCKED` instead.")]
const DISMISS_KEYGUARD = ffi::AWINDOW_FLAG_DISMISS_KEYGUARD;
const ATTACHED_IN_DECOR = 0x40000000;

// https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags
const _ = !0;
}
}

Expand Down
3 changes: 3 additions & 0 deletions ndk/src/native_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,9 @@ bitflags::bitflags! {
const TRANSFORM_ROTATE_180 = ffi::ANativeWindowTransform::ANATIVEWINDOW_TRANSFORM_ROTATE_180.0;
#[doc(alias = "ANATIVEWINDOW_TRANSFORM_ROTATE_270")]
const TRANSFORM_ROTATE_270 = ffi::ANativeWindowTransform::ANATIVEWINDOW_TRANSFORM_ROTATE_270.0;

// https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags
const _ = !0;
}
}

Expand Down

0 comments on commit f216886

Please sign in to comment.