@@ -13,7 +13,7 @@ use log::{error, trace};
13
13
use ndk:: input_queue:: InputQueue ;
14
14
use ndk:: { asset:: AssetManager , native_window:: NativeWindow } ;
15
15
16
- use crate :: error:: { InternalAppError , InternalResult } ;
16
+ use crate :: error:: InternalResult ;
17
17
use crate :: input:: { Axis , KeyCharacterMap , KeyCharacterMapBinding } ;
18
18
use crate :: input:: { TextInputState , TextSpan } ;
19
19
use crate :: jni_utils:: { self , CloneJavaVM } ;
@@ -434,11 +434,10 @@ impl AndroidAppInner {
434
434
let queue = self
435
435
. native_activity
436
436
. 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
- } ;
441
437
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.
442
441
let receiver = Arc :: new ( InputReceiver { queue } ) ;
443
442
444
443
* guard = Some ( Arc :: downgrade ( & receiver) ) ;
@@ -463,7 +462,7 @@ impl AndroidAppInner {
463
462
464
463
#[ derive( Debug ) ]
465
464
pub ( crate ) struct InputReceiver {
466
- queue : InputQueue ,
465
+ queue : Option < InputQueue > ,
467
466
}
468
467
469
468
impl < ' a > From < Arc < InputReceiver > > for InputIteratorInner < ' a > {
@@ -486,17 +485,26 @@ impl<'a> InputIteratorInner<'a> {
486
485
where
487
486
F : FnOnce ( & input:: InputEvent ) -> InputStatus ,
488
487
{
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
+
489
497
// Note: we basically ignore errors from get_event() currently. Looking
490
498
// at the source code for Android's InputQueue, the only error that
491
499
// can be returned here is 'WOULD_BLOCK', which we want to just treat as
492
500
// meaning the queue is empty.
493
501
//
494
502
// ref: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/jni/android_view_InputQueue.cpp
495
503
//
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:?}" ) ;
498
506
499
- if let Some ( ndk_event) = self . receiver . queue . pre_dispatch ( ndk_event) {
507
+ if let Some ( ndk_event) = queue. pre_dispatch ( ndk_event) {
500
508
let event = match ndk_event {
501
509
ndk:: event:: InputEvent :: MotionEvent ( e) => {
502
510
input:: InputEvent :: MotionEvent ( input:: MotionEvent :: new ( e) )
@@ -524,20 +532,18 @@ impl<'a> InputIteratorInner<'a> {
524
532
Ok ( handled) => handled,
525
533
Err ( payload) => {
526
534
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 ) ;
528
536
std:: panic:: resume_unwind ( payload) ;
529
537
}
530
538
} ;
531
539
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 ) ;
536
542
}
537
543
538
544
true
539
545
} else {
540
- log:: info !( "queue: no more events" ) ;
546
+ log:: trace !( "queue: no more events" ) ;
541
547
false
542
548
}
543
549
}
0 commit comments