Skip to content

Commit

Permalink
ndk/event: Add API-31 from_java() constructors to KeyEvent and `M…
Browse files Browse the repository at this point in the history
…otionEvent`
  • Loading branch information
MarijnS95 committed Dec 23, 2023
1 parent 3329510 commit 2ae4d4f
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 3 deletions.
1 change: 1 addition & 0 deletions ndk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- Move `MediaFormat` from `media::media_codec` to its own `media::media_format` module. (#442)
- 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)

# 0.8.0 (2023-10-15)

Expand Down
68 changes: 65 additions & 3 deletions ndk/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
//! [`android.view.KeyEvent`].
//!
//! [`AInputEvent`, `AKeyEvent` and `AMotionEvent`]: https://developer.android.com/ndk/reference/group/input
//! [`android.view.InputEvent`]: https://developer.android.com/reference/android/view/InputEvent.html
//! [`android.view.MotionEvent`]: https://developer.android.com/reference/android/view/MotionEvent.html
//! [`android.view.InputEvent`]: https://developer.android.com/reference/android/view/InputEvent
//! [`android.view.MotionEvent`]: https://developer.android.com/reference/android/view/MotionEvent
//! [`android.view.KeyEvent`]: https://developer.android.com/reference/android/view/KeyEvent
use num_enum::{IntoPrimitive, TryFromPrimitive};
use std::ptr::NonNull;

#[cfg(feature = "api-level-31")]
use jni_sys::{jobject, JNIEnv};
use num_enum::{IntoPrimitive, TryFromPrimitive};

/// A native [`AInputEvent *`]
///
/// [`AInputEvent *`]: https://developer.android.com/ndk/reference/group/input#ainputevent
Expand All @@ -22,6 +25,27 @@ pub enum InputEvent {
KeyEvent(KeyEvent),
}

/// Wraps a Java [`InputEvent`] acquired from [`KeyEvent::from_java()`] or
/// [`MotionEvent::from_java()`] with respective [`Drop`] semantics.
#[cfg(feature = "api-level-31")]
#[derive(Debug)]
pub struct InputEventJava(InputEvent);

impl Drop for InputEventJava {
/// Releases interface objects created by [`KeyEvent::from_java()`] or
/// [`MotionEvent::from_java()`].
///
/// The underlying Java object remains valid and does not change its state.
#[doc(alias = "AInputEvent_release")]
fn drop(&mut self) {
let ptr = match self.0 {
InputEvent::MotionEvent(MotionEvent { ptr })
| InputEvent::KeyEvent(KeyEvent { ptr }) => ptr.as_ptr().cast(),
};
unsafe { ffi::AInputEvent_release(ptr) }
}
}

/// An enum representing the source of an [`InputEvent`].
///
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-36)
Expand Down Expand Up @@ -373,6 +397,25 @@ impl MotionEvent {
Self { ptr }
}

/// Creates a native [`InputEvent`] object that is a copy of the specified
/// Java [`android.view.MotionEvent`]. The result may be used with generic and
/// [`MotionEvent`]-specific functions.
///
/// # Safety
///
/// This function should be called with a healthy JVM pointer and with a non-null
/// [`android.view.MotionEvent`], which must be kept alive on the Java/Kotlin side.
///
/// [`android.view.MotionEvent`]: https://developer.android.com/reference/android/view/MotionEvent
#[cfg(feature = "api-level-31")]
#[doc(alias = "AMotionEvent_fromJava")]
pub unsafe fn from_java(env: *mut JNIEnv, key_event: jobject) -> Option<InputEventJava> {
let ptr = unsafe { ffi::AMotionEvent_fromJava(env, key_event) };
Some(InputEventJava(InputEvent::MotionEvent(Self::from_ptr(
NonNull::new(ptr.cast_mut())?,
))))
}

/// Returns a pointer to the native [`ffi::AInputEvent`]
#[inline]
pub fn ptr(&self) -> NonNull<ffi::AInputEvent> {
Expand Down Expand Up @@ -1342,6 +1385,25 @@ impl KeyEvent {
Self { ptr }
}

/// Creates a native [`InputEvent`] object that is a copy of the specified Java
/// [`android.view.KeyEvent`]. The result may be used with generic and [`KeyEvent`]-specific
/// functions.
///
/// # Safety
///
/// This function should be called with a healthy JVM pointer and with a non-null
/// [`android.view.InputEvent`], which must be kept alive on the Java/Kotlin side.
///
/// [`android.view.InputEvent`]: https://developer.android.com/reference/android/view/InputEvent
#[cfg(feature = "api-level-31")]
#[doc(alias = "AKeyEvent_fromJava")]
pub unsafe fn from_java(env: *mut JNIEnv, key_event: jobject) -> Option<InputEventJava> {
let ptr = unsafe { ffi::AKeyEvent_fromJava(env, key_event) };
Some(InputEventJava(InputEvent::KeyEvent(Self::from_ptr(
NonNull::new(ptr.cast_mut())?,
))))
}

/// Returns a pointer to the native [`ffi::AInputEvent`]
#[inline]
pub fn ptr(&self) -> NonNull<ffi::AInputEvent> {
Expand Down

0 comments on commit 2ae4d4f

Please sign in to comment.