11
11
import androidx .annotation .Nullable ;
12
12
import io .flutter .Log ;
13
13
import io .flutter .embedding .engine .systemchannels .KeyEventChannel ;
14
- import io .flutter .embedding .engine .systemchannels .KeyEventChannel .FlutterKeyEvent ;
15
14
import io .flutter .plugin .editing .TextInputPlugin ;
16
- import java .util .AbstractMap .SimpleImmutableEntry ;
17
15
import java .util .ArrayDeque ;
18
16
import java .util .Deque ;
19
- import java .util .Map .Entry ;
20
17
21
18
/**
22
19
* A class to process key events from Android, passing them to the framework as messages using
@@ -96,20 +93,19 @@ public boolean onKeyEvent(@NonNull KeyEvent event) {
96
93
// case the theory is wrong.
97
94
return false ;
98
95
}
99
- long eventId = FlutterKeyEvent .computeEventId (event );
100
- if (eventResponder .isHeadEvent (eventId )) {
96
+ if (eventResponder .isHeadEvent (event )) {
101
97
// If the event is at the head of the queue of pending events we've seen,
102
98
// and has the same id, then we know that this is a re-dispatched event, and
103
99
// we shouldn't respond to it, but we should remove it from tracking now.
104
- eventResponder .removePendingEvent ( eventId );
100
+ eventResponder .removeHeadEvent ( );
105
101
return false ;
106
102
}
107
103
108
104
Character complexCharacter = applyCombiningCharacterToBaseCharacter (event .getUnicodeChar ());
109
105
KeyEventChannel .FlutterKeyEvent flutterEvent =
110
106
new KeyEventChannel .FlutterKeyEvent (event , complexCharacter );
111
107
112
- eventResponder .addEvent (flutterEvent . eventId , event );
108
+ eventResponder .addEvent (event );
113
109
if (action == KeyEvent .ACTION_DOWN ) {
114
110
keyEventChannel .keyDown (flutterEvent );
115
111
} else {
@@ -127,8 +123,7 @@ public boolean onKeyEvent(@NonNull KeyEvent event) {
127
123
* @return
128
124
*/
129
125
public boolean isCurrentEvent (@ NonNull KeyEvent event ) {
130
- long id = FlutterKeyEvent .computeEventId (event );
131
- return eventResponder .isHeadEvent (id );
126
+ return eventResponder .isHeadEvent (event );
132
127
}
133
128
134
129
/**
@@ -194,7 +189,7 @@ private static class EventResponder implements KeyEventChannel.EventResponseHand
194
189
// The maximum number of pending events that are held before starting to
195
190
// complain.
196
191
private static final long MAX_PENDING_EVENTS = 1000 ;
197
- final Deque <Entry < Long , KeyEvent >> pendingEvents = new ArrayDeque <Entry < Long , KeyEvent > >();
192
+ final Deque <KeyEvent > pendingEvents = new ArrayDeque <KeyEvent >();
198
193
@ NonNull private final View view ;
199
194
@ NonNull private final TextInputPlugin textInputPlugin ;
200
195
@@ -203,67 +198,54 @@ public EventResponder(@NonNull View view, @NonNull TextInputPlugin textInputPlug
203
198
this .textInputPlugin = textInputPlugin ;
204
199
}
205
200
206
- /**
207
- * Removes the pending event with the given id from the cache of pending events.
208
- *
209
- * @param id the id of the event to be removed.
210
- */
211
- private KeyEvent removePendingEvent (long id ) {
212
- if (pendingEvents .getFirst ().getKey () != id ) {
213
- throw new AssertionError (
214
- "Event response received out of order. Should have seen event "
215
- + pendingEvents .getFirst ().getKey ()
216
- + " first. Instead, received "
217
- + id );
218
- }
219
- return pendingEvents .removeFirst ().getValue ();
201
+ /** Removes the first pending event from the cache of pending events. */
202
+ private KeyEvent removeHeadEvent () {
203
+ return pendingEvents .removeFirst ();
220
204
}
221
205
222
- private KeyEvent findPendingEvent ( long id ) {
206
+ private KeyEvent checkIsHeadEvent ( KeyEvent event ) {
223
207
if (pendingEvents .size () == 0 ) {
224
208
throw new AssertionError (
225
- "Event response received when no events are in the queue. Received id " + id );
209
+ "Event response received when no events are in the queue. Received event " + event );
226
210
}
227
- if (pendingEvents .getFirst (). getKey () != id ) {
211
+ if (pendingEvents .getFirst () != event ) {
228
212
throw new AssertionError (
229
213
"Event response received out of order. Should have seen event "
230
- + pendingEvents .getFirst (). getKey ()
214
+ + pendingEvents .getFirst ()
231
215
+ " first. Instead, received "
232
- + id );
216
+ + event );
233
217
}
234
- return pendingEvents .getFirst (). getValue () ;
218
+ return pendingEvents .getFirst ();
235
219
}
236
220
237
- private boolean isHeadEvent (long id ) {
238
- return pendingEvents .size () > 0 && pendingEvents .getFirst (). getKey () == id ;
221
+ private boolean isHeadEvent (KeyEvent event ) {
222
+ return pendingEvents .size () > 0 && pendingEvents .getFirst () == event ;
239
223
}
240
224
241
225
/**
242
226
* Called whenever the framework responds that a given key event was handled by the framework.
243
227
*
244
- * @param id the event id of the event to be marked as being handled by the framework. Must not
245
- * be null.
228
+ * @param event the event to be marked as being handled by the framework. Must not be null.
246
229
*/
247
230
@ Override
248
- public void onKeyEventHandled (long id ) {
249
- removePendingEvent ( id );
231
+ public void onKeyEventHandled (KeyEvent event ) {
232
+ removeHeadEvent ( );
250
233
}
251
234
252
235
/**
253
236
* Called whenever the framework responds that a given key event wasn't handled by the
254
237
* framework.
255
238
*
256
- * @param id the event id of the event to be marked as not being handled by the framework. Must
257
- * not be null.
239
+ * @param event the event to be marked as not being handled by the framework. Must not be null.
258
240
*/
259
241
@ Override
260
- public void onKeyEventNotHandled (long id ) {
261
- dispatchKeyEvent ( findPendingEvent ( id ), id );
242
+ public void onKeyEventNotHandled (KeyEvent event ) {
243
+ redispatchKeyEvent ( checkIsHeadEvent ( event ) );
262
244
}
263
245
264
- /** Adds an Android key event with an id to the event responder to wait for a response. */
265
- public void addEvent (long id , @ NonNull KeyEvent event ) {
266
- pendingEvents .addLast (new SimpleImmutableEntry < Long , KeyEvent >( id , event ) );
246
+ /** Adds an Android key event to the event responder to wait for a response. */
247
+ public void addEvent (@ NonNull KeyEvent event ) {
248
+ pendingEvents .addLast (event );
267
249
if (pendingEvents .size () > MAX_PENDING_EVENTS ) {
268
250
Log .e (
269
251
TAG ,
@@ -279,15 +261,15 @@ public void addEvent(long id, @NonNull KeyEvent event) {
279
261
*
280
262
* @param event the event to be dispatched to the activity.
281
263
*/
282
- public void dispatchKeyEvent (KeyEvent event , long id ) {
264
+ private void redispatchKeyEvent (KeyEvent event ) {
283
265
// If the textInputPlugin is still valid and accepting text, then we'll try
284
266
// and send the key event to it, assuming that if the event can be sent,
285
267
// that it has been handled.
286
268
if (textInputPlugin .getInputMethodManager ().isAcceptingText ()
287
269
&& textInputPlugin .getLastInputConnection () != null
288
270
&& textInputPlugin .getLastInputConnection ().sendKeyEvent (event )) {
289
271
// The event was handled, so we can remove it from the queue.
290
- removePendingEvent ( id );
272
+ removeHeadEvent ( );
291
273
return ;
292
274
}
293
275
0 commit comments