Skip to content

Commit 2654c96

Browse files
authored
Merge pull request #110 from rust-mobile/rib/pr/no-missing-input-queue-error
native-activity: don't treat missing input queue as error
2 parents 242285b + 35fe600 commit 2654c96

File tree

1 file changed

+21
-15
lines changed
  • android-activity/src/native_activity

1 file changed

+21
-15
lines changed

android-activity/src/native_activity/mod.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use log::{error, trace};
1313
use ndk::input_queue::InputQueue;
1414
use ndk::{asset::AssetManager, native_window::NativeWindow};
1515

16-
use crate::error::{InternalAppError, InternalResult};
16+
use crate::error::InternalResult;
1717
use crate::input::{Axis, KeyCharacterMap, KeyCharacterMapBinding};
1818
use crate::input::{TextInputState, TextSpan};
1919
use crate::jni_utils::{self, CloneJavaVM};
@@ -434,11 +434,10 @@ impl AndroidAppInner {
434434
let queue = self
435435
.native_activity
436436
.looper_attached_input_queue(self.looper(), LOOPER_ID_INPUT);
437-
let queue = match queue {
438-
Some(queue) => queue,
439-
None => return Err(InternalAppError::InputUnavailable),
440-
};
441437

438+
// Note: we don't treat it as an error if there is no queue, so if applications
439+
// iterate input before a queue has been created (e.g. before onStart) then
440+
// it will simply behave like there are no events available currently.
442441
let receiver = Arc::new(InputReceiver { queue });
443442

444443
*guard = Some(Arc::downgrade(&receiver));
@@ -463,7 +462,7 @@ impl AndroidAppInner {
463462

464463
#[derive(Debug)]
465464
pub(crate) struct InputReceiver {
466-
queue: InputQueue,
465+
queue: Option<InputQueue>,
467466
}
468467

469468
impl<'a> From<Arc<InputReceiver>> for InputIteratorInner<'a> {
@@ -486,17 +485,26 @@ impl<'a> InputIteratorInner<'a> {
486485
where
487486
F: FnOnce(&input::InputEvent) -> InputStatus,
488487
{
488+
// XXX: would use `let Some(queue) = &self.receiver.queue else { return
489+
// false; }` but we're stuck supporting Rust 1.64 for Winit currently
490+
let queue = if let Some(queue) = &self.receiver.queue {
491+
queue
492+
} else {
493+
log::trace!("no queue available for events");
494+
return false;
495+
};
496+
489497
// Note: we basically ignore errors from get_event() currently. Looking
490498
// at the source code for Android's InputQueue, the only error that
491499
// can be returned here is 'WOULD_BLOCK', which we want to just treat as
492500
// meaning the queue is empty.
493501
//
494502
// ref: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/jni/android_view_InputQueue.cpp
495503
//
496-
if let Ok(Some(ndk_event)) = self.receiver.queue.get_event() {
497-
log::info!("queue: got event: {ndk_event:?}");
504+
if let Ok(Some(ndk_event)) = queue.get_event() {
505+
log::trace!("queue: got event: {ndk_event:?}");
498506

499-
if let Some(ndk_event) = self.receiver.queue.pre_dispatch(ndk_event) {
507+
if let Some(ndk_event) = queue.pre_dispatch(ndk_event) {
500508
let event = match ndk_event {
501509
ndk::event::InputEvent::MotionEvent(e) => {
502510
input::InputEvent::MotionEvent(input::MotionEvent::new(e))
@@ -524,20 +532,18 @@ impl<'a> InputIteratorInner<'a> {
524532
Ok(handled) => handled,
525533
Err(payload) => {
526534
log::error!("Calling `finish_event` after panic in input event handler, to try and avoid being killed via an ANR");
527-
self.receiver.queue.finish_event(ndk_event, false);
535+
queue.finish_event(ndk_event, false);
528536
std::panic::resume_unwind(payload);
529537
}
530538
};
531539

532-
log::info!("queue: finishing event");
533-
self.receiver
534-
.queue
535-
.finish_event(ndk_event, handled == InputStatus::Handled);
540+
log::trace!("queue: finishing event");
541+
queue.finish_event(ndk_event, handled == InputStatus::Handled);
536542
}
537543

538544
true
539545
} else {
540-
log::info!("queue: no more events");
546+
log::trace!("queue: no more events");
541547
false
542548
}
543549
}

0 commit comments

Comments
 (0)