@@ -13,7 +13,7 @@ use log::{error, trace};
1313use ndk:: input_queue:: InputQueue ;
1414use ndk:: { asset:: AssetManager , native_window:: NativeWindow } ;
1515
16- use crate :: error:: { InternalAppError , InternalResult } ;
16+ use crate :: error:: InternalResult ;
1717use crate :: input:: { Axis , KeyCharacterMap , KeyCharacterMapBinding } ;
1818use crate :: input:: { TextInputState , TextSpan } ;
1919use 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 ) ]
465464pub ( crate ) struct InputReceiver {
466- queue : InputQueue ,
465+ queue : Option < InputQueue > ,
467466}
468467
469468impl < ' 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