Merge pull request #110 from rust-mobile/rib/pr/no-missing-input-queue-error

native-activity: don't treat missing input queue as error
This commit is contained in:
Robert Bragg
2023-08-15 21:13:47 +01:00
committed by GitHub
+21 -15
View File
@@ -13,7 +13,7 @@ use log::{error, trace};
use ndk::input_queue::InputQueue;
use ndk::{asset::AssetManager, native_window::NativeWindow};
use crate::error::{InternalAppError, InternalResult};
use crate::error::InternalResult;
use crate::input::{Axis, KeyCharacterMap, KeyCharacterMapBinding};
use crate::input::{TextInputState, TextSpan};
use crate::jni_utils::{self, CloneJavaVM};
@@ -434,11 +434,10 @@ impl AndroidAppInner {
let queue = self
.native_activity
.looper_attached_input_queue(self.looper(), LOOPER_ID_INPUT);
let queue = match queue {
Some(queue) => queue,
None => return Err(InternalAppError::InputUnavailable),
};
// Note: we don't treat it as an error if there is no queue, so if applications
// iterate input before a queue has been created (e.g. before onStart) then
// it will simply behave like there are no events available currently.
let receiver = Arc::new(InputReceiver { queue });
*guard = Some(Arc::downgrade(&receiver));
@@ -463,7 +462,7 @@ impl AndroidAppInner {
#[derive(Debug)]
pub(crate) struct InputReceiver {
queue: InputQueue,
queue: Option<InputQueue>,
}
impl<'a> From<Arc<InputReceiver>> for InputIteratorInner<'a> {
@@ -486,6 +485,15 @@ impl<'a> InputIteratorInner<'a> {
where
F: FnOnce(&input::InputEvent) -> InputStatus,
{
// XXX: would use `let Some(queue) = &self.receiver.queue else { return
// false; }` but we're stuck supporting Rust 1.64 for Winit currently
let queue = if let Some(queue) = &self.receiver.queue {
queue
} else {
log::trace!("no queue available for events");
return false;
};
// Note: we basically ignore errors from get_event() currently. Looking
// at the source code for Android's InputQueue, the only error that
// can be returned here is 'WOULD_BLOCK', which we want to just treat as
@@ -493,10 +501,10 @@ impl<'a> InputIteratorInner<'a> {
//
// ref: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/jni/android_view_InputQueue.cpp
//
if let Ok(Some(ndk_event)) = self.receiver.queue.get_event() {
log::info!("queue: got event: {ndk_event:?}");
if let Ok(Some(ndk_event)) = queue.get_event() {
log::trace!("queue: got event: {ndk_event:?}");
if let Some(ndk_event) = self.receiver.queue.pre_dispatch(ndk_event) {
if let Some(ndk_event) = queue.pre_dispatch(ndk_event) {
let event = match ndk_event {
ndk::event::InputEvent::MotionEvent(e) => {
input::InputEvent::MotionEvent(input::MotionEvent::new(e))
@@ -524,20 +532,18 @@ impl<'a> InputIteratorInner<'a> {
Ok(handled) => handled,
Err(payload) => {
log::error!("Calling `finish_event` after panic in input event handler, to try and avoid being killed via an ANR");
self.receiver.queue.finish_event(ndk_event, false);
queue.finish_event(ndk_event, false);
std::panic::resume_unwind(payload);
}
};
log::info!("queue: finishing event");
self.receiver
.queue
.finish_event(ndk_event, handled == InputStatus::Handled);
log::trace!("queue: finishing event");
queue.finish_event(ndk_event, handled == InputStatus::Handled);
}
true
} else {
log::info!("queue: no more events");
log::trace!("queue: no more events");
false
}
}