[Android] Fix crash on some key repeat events (#165307)
## Description This PR fixes a crash on Android related to specific keyboard events. It is very similar to http://github.com/flutter/engine/issues/35924 which was related to down events. This PR fixes the similar logic related to repeat events. ## Related Issue Fixes [Flutter 3.29 Fatal crash with java.lang.AssertionError](https://github.com/flutter/flutter/issues/164626) ## Tests Adds 1 test.
This commit is contained in:
@@ -183,7 +183,7 @@ public class KeyEmbedderResponder implements KeyboardManager.Responder {
|
||||
postSynchronize.add(
|
||||
() ->
|
||||
synthesizeEvent(
|
||||
false, key.logicalKey, key.physicalKey, event.getEventTime()));
|
||||
false, key.logicalKey, eventPhysicalKey, event.getEventTime()));
|
||||
}
|
||||
preEventStates[keyIdx] = nowStates[keyIdx];
|
||||
postEventAnyPressed = true;
|
||||
|
||||
@@ -1669,6 +1669,68 @@ public class KeyboardManagerTest {
|
||||
calls.clear();
|
||||
}
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/164626.
|
||||
@Test
|
||||
public void synchronizeModifiersForZeroedScanCodeOnRepeatEvent() {
|
||||
// Test if ShiftLeft can be correctly synchronized during down events of
|
||||
// ShiftLeft that have 0 for their metaState and 0 for their scanCode.
|
||||
final KeyboardTester tester = new KeyboardTester();
|
||||
final ArrayList<CallRecord> calls = new ArrayList<>();
|
||||
|
||||
tester.recordEmbedderCallsTo(calls);
|
||||
tester.respondToTextInputWith(true); // Suppress redispatching
|
||||
|
||||
// Test: repeat event when the meta state is 0 and scanCode is 0.
|
||||
final KeyEvent shiftLeftKeyEvent =
|
||||
new FakeKeyEvent(ACTION_DOWN, 0, KEYCODE_SHIFT_LEFT, 1, '\0', 0);
|
||||
// Compute physicalKey in the same way as KeyboardManager.getPhysicalKey.
|
||||
final Long shiftLeftPhysicalKey = KEYCODE_SHIFT_LEFT | KeyboardMap.kAndroidPlane;
|
||||
|
||||
assertEquals(tester.keyboardManager.handleEvent(shiftLeftKeyEvent), true);
|
||||
assertEquals(calls.size(), 2);
|
||||
assertEmbedderEventEquals(
|
||||
calls.get(0).keyData,
|
||||
Type.kDown,
|
||||
shiftLeftPhysicalKey,
|
||||
LOGICAL_SHIFT_LEFT,
|
||||
null,
|
||||
false,
|
||||
DeviceType.kKeyboard);
|
||||
assertEmbedderEventEquals(
|
||||
calls.get(1).keyData,
|
||||
Type.kUp,
|
||||
shiftLeftPhysicalKey,
|
||||
LOGICAL_SHIFT_LEFT,
|
||||
null,
|
||||
true,
|
||||
DeviceType.kKeyboard);
|
||||
calls.clear();
|
||||
|
||||
// Similar check for AltLeft.
|
||||
final KeyEvent altLeftKeyEvent = new FakeKeyEvent(ACTION_DOWN, 0, KEYCODE_ALT_LEFT, 1, '\0', 0);
|
||||
final Long altLeftPhysicalKey = KEYCODE_ALT_LEFT | KeyboardMap.kAndroidPlane;
|
||||
|
||||
assertEquals(tester.keyboardManager.handleEvent(altLeftKeyEvent), true);
|
||||
assertEquals(calls.size(), 2);
|
||||
assertEmbedderEventEquals(
|
||||
calls.get(0).keyData,
|
||||
Type.kDown,
|
||||
altLeftPhysicalKey,
|
||||
LOGICAL_ALT_LEFT,
|
||||
null,
|
||||
false,
|
||||
DeviceType.kKeyboard);
|
||||
assertEmbedderEventEquals(
|
||||
calls.get(1).keyData,
|
||||
Type.kUp,
|
||||
altLeftPhysicalKey,
|
||||
LOGICAL_ALT_LEFT,
|
||||
null,
|
||||
true,
|
||||
DeviceType.kKeyboard);
|
||||
calls.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void normalCapsLockEvents() {
|
||||
final KeyboardTester tester = new KeyboardTester();
|
||||
|
||||
Reference in New Issue
Block a user