Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 311cef9

Browse files
committed
Review changes
1 parent 63be4d3 commit 311cef9

File tree

4 files changed

+60
-93
lines changed

4 files changed

+60
-93
lines changed

shell/platform/android/io/flutter/embedding/android/AndroidKeyProcessor.java

Lines changed: 27 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,9 @@
1111
import androidx.annotation.Nullable;
1212
import io.flutter.Log;
1313
import io.flutter.embedding.engine.systemchannels.KeyEventChannel;
14-
import io.flutter.embedding.engine.systemchannels.KeyEventChannel.FlutterKeyEvent;
1514
import io.flutter.plugin.editing.TextInputPlugin;
16-
import java.util.AbstractMap.SimpleImmutableEntry;
1715
import java.util.ArrayDeque;
1816
import java.util.Deque;
19-
import java.util.Map.Entry;
2017

2118
/**
2219
* 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) {
9693
// case the theory is wrong.
9794
return false;
9895
}
99-
long eventId = FlutterKeyEvent.computeEventId(event);
100-
if (eventResponder.isHeadEvent(eventId)) {
96+
if (eventResponder.isHeadEvent(event)) {
10197
// If the event is at the head of the queue of pending events we've seen,
10298
// and has the same id, then we know that this is a re-dispatched event, and
10399
// we shouldn't respond to it, but we should remove it from tracking now.
104-
eventResponder.removePendingEvent(eventId);
100+
eventResponder.removeHeadEvent();
105101
return false;
106102
}
107103

108104
Character complexCharacter = applyCombiningCharacterToBaseCharacter(event.getUnicodeChar());
109105
KeyEventChannel.FlutterKeyEvent flutterEvent =
110106
new KeyEventChannel.FlutterKeyEvent(event, complexCharacter);
111107

112-
eventResponder.addEvent(flutterEvent.eventId, event);
108+
eventResponder.addEvent(event);
113109
if (action == KeyEvent.ACTION_DOWN) {
114110
keyEventChannel.keyDown(flutterEvent);
115111
} else {
@@ -127,8 +123,7 @@ public boolean onKeyEvent(@NonNull KeyEvent event) {
127123
* @return
128124
*/
129125
public boolean isCurrentEvent(@NonNull KeyEvent event) {
130-
long id = FlutterKeyEvent.computeEventId(event);
131-
return eventResponder.isHeadEvent(id);
126+
return eventResponder.isHeadEvent(event);
132127
}
133128

134129
/**
@@ -194,7 +189,7 @@ private static class EventResponder implements KeyEventChannel.EventResponseHand
194189
// The maximum number of pending events that are held before starting to
195190
// complain.
196191
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>();
198193
@NonNull private final View view;
199194
@NonNull private final TextInputPlugin textInputPlugin;
200195

@@ -203,67 +198,54 @@ public EventResponder(@NonNull View view, @NonNull TextInputPlugin textInputPlug
203198
this.textInputPlugin = textInputPlugin;
204199
}
205200

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();
220204
}
221205

222-
private KeyEvent findPendingEvent(long id) {
206+
private KeyEvent checkIsHeadEvent(KeyEvent event) {
223207
if (pendingEvents.size() == 0) {
224208
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);
226210
}
227-
if (pendingEvents.getFirst().getKey() != id) {
211+
if (pendingEvents.getFirst() != event) {
228212
throw new AssertionError(
229213
"Event response received out of order. Should have seen event "
230-
+ pendingEvents.getFirst().getKey()
214+
+ pendingEvents.getFirst()
231215
+ " first. Instead, received "
232-
+ id);
216+
+ event);
233217
}
234-
return pendingEvents.getFirst().getValue();
218+
return pendingEvents.getFirst();
235219
}
236220

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;
239223
}
240224

241225
/**
242226
* Called whenever the framework responds that a given key event was handled by the framework.
243227
*
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.
246229
*/
247230
@Override
248-
public void onKeyEventHandled(long id) {
249-
removePendingEvent(id);
231+
public void onKeyEventHandled(KeyEvent event) {
232+
removeHeadEvent();
250233
}
251234

252235
/**
253236
* Called whenever the framework responds that a given key event wasn't handled by the
254237
* framework.
255238
*
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.
258240
*/
259241
@Override
260-
public void onKeyEventNotHandled(long id) {
261-
dispatchKeyEvent(findPendingEvent(id), id);
242+
public void onKeyEventNotHandled(KeyEvent event) {
243+
redispatchKeyEvent(checkIsHeadEvent(event));
262244
}
263245

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);
267249
if (pendingEvents.size() > MAX_PENDING_EVENTS) {
268250
Log.e(
269251
TAG,
@@ -279,15 +261,15 @@ public void addEvent(long id, @NonNull KeyEvent event) {
279261
*
280262
* @param event the event to be dispatched to the activity.
281263
*/
282-
public void dispatchKeyEvent(KeyEvent event, long id) {
264+
private void redispatchKeyEvent(KeyEvent event) {
283265
// If the textInputPlugin is still valid and accepting text, then we'll try
284266
// and send the key event to it, assuming that if the event can be sent,
285267
// that it has been handled.
286268
if (textInputPlugin.getInputMethodManager().isAcceptingText()
287269
&& textInputPlugin.getLastInputConnection() != null
288270
&& textInputPlugin.getLastInputConnection().sendKeyEvent(event)) {
289271
// The event was handled, so we can remove it from the queue.
290-
removePendingEvent(id);
272+
removeHeadEvent();
291273
return;
292274
}
293275

shell/platform/android/io/flutter/embedding/engine/systemchannels/KeyEventChannel.java

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,17 @@ public interface EventResponseHandler {
4343
/**
4444
* Called whenever the framework responds that a given key event was handled by the framework.
4545
*
46-
* @param id the event id of the event to be marked as being handled by the framework. Must not
47-
* be null.
46+
* @param event the event to be marked as being handled by the framework. Must not be null.
4847
*/
49-
public void onKeyEventHandled(long id);
48+
public void onKeyEventHandled(KeyEvent event);
5049

5150
/**
5251
* Called whenever the framework responds that a given key event wasn't handled by the
5352
* framework.
5453
*
55-
* @param id the event id of the event to be marked as not being handled by the framework. Must
56-
* not be null.
54+
* @param event the event to be marked as not being handled by the framework. Must not be null.
5755
*/
58-
public void onKeyEventNotHandled(long id);
56+
public void onKeyEventNotHandled(KeyEvent event);
5957
}
6058

6159
/**
@@ -69,31 +67,31 @@ public KeyEventChannel(@NonNull BinaryMessenger binaryMessenger) {
6967
}
7068

7169
/**
72-
* Creates a reply handler for this an event with the given eventId.
70+
* Creates a reply handler for the given key event.
7371
*
74-
* @param eventId the event ID to create a reply for.
72+
* @param event the Android key event to create a reply for.
7573
*/
76-
BasicMessageChannel.Reply<Object> createReplyHandler(long eventId) {
74+
BasicMessageChannel.Reply<Object> createReplyHandler(KeyEvent event) {
7775
return message -> {
7876
if (eventResponseHandler == null) {
7977
return;
8078
}
8179

8280
try {
8381
if (message == null) {
84-
eventResponseHandler.onKeyEventNotHandled(eventId);
82+
eventResponseHandler.onKeyEventNotHandled(event);
8583
return;
8684
}
8785
final JSONObject annotatedEvent = (JSONObject) message;
8886
final boolean handled = annotatedEvent.getBoolean("handled");
8987
if (handled) {
90-
eventResponseHandler.onKeyEventHandled(eventId);
88+
eventResponseHandler.onKeyEventHandled(event);
9189
} else {
92-
eventResponseHandler.onKeyEventNotHandled(eventId);
90+
eventResponseHandler.onKeyEventNotHandled(event);
9391
}
9492
} catch (JSONException e) {
9593
Log.e(TAG, "Unable to unpack JSON message: " + e);
96-
eventResponseHandler.onKeyEventNotHandled(eventId);
94+
eventResponseHandler.onKeyEventNotHandled(event);
9795
}
9896
};
9997
}
@@ -106,7 +104,7 @@ public void keyUp(@NonNull FlutterKeyEvent keyEvent) {
106104
message.put("keymap", "android");
107105
encodeKeyEvent(keyEvent, message);
108106

109-
channel.send(message, createReplyHandler(keyEvent.eventId));
107+
channel.send(message, createReplyHandler(keyEvent.event));
110108
}
111109

112110
public void keyDown(@NonNull FlutterKeyEvent keyEvent) {
@@ -115,7 +113,7 @@ public void keyDown(@NonNull FlutterKeyEvent keyEvent) {
115113
message.put("keymap", "android");
116114
encodeKeyEvent(keyEvent, message);
117115

118-
channel.send(message, createReplyHandler(keyEvent.eventId));
116+
channel.send(message, createReplyHandler(keyEvent.event));
119117
}
120118

121119
private void encodeKeyEvent(
@@ -222,25 +220,12 @@ public static class FlutterKeyEvent {
222220
*/
223221
public final int repeatCount;
224222
/**
225-
* The unique id for this Flutter key event.
223+
* The Android key event that this Flutter key event was created from.
226224
*
227-
* <p>This id is used to identify pending events when results are received from the framework.
228-
* This ID does not come from Android, but instead is derived from attributes of this event that
229-
* can be recognized if the event is re-dispatched.
230-
*/
231-
public final long eventId;
232-
233-
/**
234-
* Creates a unique id for a Flutter key event from an Android KeyEvent.
235-
*
236-
* <p>This id is used to identify pending key events when results are received from the
225+
* <p>This event is used to identify pending events when results are received from the
237226
* framework.
238227
*/
239-
public static long computeEventId(@NonNull KeyEvent event) {
240-
return (event.getEventTime() & 0xffffffff)
241-
| ((long) (event.getAction() == KeyEvent.ACTION_DOWN ? 0x1 : 0x0)) << 32
242-
| ((long) (event.getScanCode() & 0xffff)) << 33;
243-
}
228+
public final KeyEvent event;
244229

245230
public FlutterKeyEvent(@NonNull KeyEvent androidKeyEvent) {
246231
this(androidKeyEvent, null);
@@ -259,7 +244,7 @@ public FlutterKeyEvent(
259244
androidKeyEvent.getMetaState(),
260245
androidKeyEvent.getSource(),
261246
androidKeyEvent.getRepeatCount(),
262-
computeEventId(androidKeyEvent));
247+
androidKeyEvent);
263248
}
264249

265250
public FlutterKeyEvent(
@@ -273,7 +258,7 @@ public FlutterKeyEvent(
273258
int metaState,
274259
int source,
275260
int repeatCount,
276-
long eventId) {
261+
KeyEvent event) {
277262
this.deviceId = deviceId;
278263
this.flags = flags;
279264
this.plainCodePoint = plainCodePoint;
@@ -284,7 +269,7 @@ public FlutterKeyEvent(
284269
this.metaState = metaState;
285270
this.source = source;
286271
this.repeatCount = repeatCount;
287-
this.eventId = eventId;
272+
this.event = event;
288273
InputDevice device = InputDevice.getDevice(deviceId);
289274
if (device != null) {
290275
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

shell/platform/android/test/io/flutter/embedding/android/AndroidKeyProcessorTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public Boolean answer(InvocationOnMock invocation) throws Throwable {
117117
});
118118

119119
// Fake a response from the framework.
120-
handlerCaptor.getValue().onKeyEventNotHandled(eventCaptor.getValue().eventId);
120+
handlerCaptor.getValue().onKeyEventNotHandled(eventCaptor.getValue().event);
121121
verify(fakeView, times(1)).dispatchKeyEvent(fakeKeyEvent);
122122
assertEquals(false, dispatchResult[0]);
123123
verify(fakeKeyEventChannel, times(0)).keyUp(any(KeyEventChannel.FlutterKeyEvent.class));
@@ -167,7 +167,7 @@ public Boolean answer(InvocationOnMock invocation) throws Throwable {
167167
});
168168

169169
// Fake a response from the framework.
170-
handlerCaptor.getValue().onKeyEventNotHandled(eventCaptor.getValue().eventId);
170+
handlerCaptor.getValue().onKeyEventNotHandled(eventCaptor.getValue().event);
171171
verify(fakeView, times(1)).dispatchKeyEvent(fakeKeyEvent);
172172
assertEquals(false, dispatchResult[0]);
173173
verify(fakeKeyEventChannel, times(0)).keyUp(any(KeyEventChannel.FlutterKeyEvent.class));

shell/platform/android/test/io/flutter/embedding/engine/systemchannels/KeyEventChannelTest.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,17 @@ public void keyDownEventIsSentToFramework() throws JSONException {
4545
BinaryMessenger fakeMessenger = mock(BinaryMessenger.class);
4646
KeyEventChannel keyEventChannel = new KeyEventChannel(fakeMessenger);
4747
final boolean[] handled = {false};
48-
final long[] handledId = {-1};
48+
final KeyEvent[] handledKeyEvents = {null};
4949
keyEventChannel.setEventResponseHandler(
5050
new KeyEventChannel.EventResponseHandler() {
51-
public void onKeyEventHandled(@NonNull long id) {
51+
public void onKeyEventHandled(@NonNull KeyEvent event) {
5252
handled[0] = true;
53-
handledId[0] = id;
53+
handledKeyEvents[0] = event;
5454
}
5555

56-
public void onKeyEventNotHandled(@NonNull long id) {
56+
public void onKeyEventNotHandled(@NonNull KeyEvent event) {
5757
handled[0] = false;
58-
handledId[0] = id;
58+
handledKeyEvents[0] = event;
5959
}
6060
});
6161
verify(fakeMessenger, times(0)).send(any(), any(), any());
@@ -78,25 +78,25 @@ public void onKeyEventNotHandled(@NonNull long id) {
7878
// Simulate a reply, and see that it is handled.
7979
sendReply(true, replyArgumentCaptor.getValue());
8080
assertTrue(handled[0]);
81-
assertEquals(KeyEventChannel.FlutterKeyEvent.computeEventId(event), handledId[0]);
81+
assertEquals(event, handledKeyEvents[0]);
8282
}
8383

8484
@Test
8585
public void keyUpEventIsSentToFramework() throws JSONException {
8686
BinaryMessenger fakeMessenger = mock(BinaryMessenger.class);
8787
KeyEventChannel keyEventChannel = new KeyEventChannel(fakeMessenger);
8888
final boolean[] handled = {false};
89-
final long[] handledId = {-1};
89+
final KeyEvent[] handledKeyEvents = {null};
9090
keyEventChannel.setEventResponseHandler(
9191
new KeyEventChannel.EventResponseHandler() {
92-
public void onKeyEventHandled(long id) {
92+
public void onKeyEventHandled(@NonNull KeyEvent event) {
9393
handled[0] = true;
94-
handledId[0] = id;
94+
handledKeyEvents[0] = event;
9595
}
9696

97-
public void onKeyEventNotHandled(long id) {
97+
public void onKeyEventNotHandled(@NonNull KeyEvent event) {
9898
handled[0] = false;
99-
handledId[0] = id;
99+
handledKeyEvents[0] = event;
100100
}
101101
});
102102
verify(fakeMessenger, times(0)).send(any(), any(), any());
@@ -119,6 +119,6 @@ public void onKeyEventNotHandled(long id) {
119119
// Simulate a reply, and see that it is handled.
120120
sendReply(true, replyArgumentCaptor.getValue());
121121
assertTrue(handled[0]);
122-
assertEquals(KeyEventChannel.FlutterKeyEvent.computeEventId(event), handledId[0]);
122+
assertEquals(event, handledKeyEvents[0]);
123123
}
124124
}

0 commit comments

Comments
 (0)