Skip to content

Commit d0ef1c1

Browse files
authored
[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](flutter/flutter#164626) ## Tests Adds 1 test.
1 parent df0e5d0 commit d0ef1c1

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

engine/src/flutter/shell/platform/android/io/flutter/embedding/android/KeyEmbedderResponder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ void synchronizePressingKey(
183183
postSynchronize.add(
184184
() ->
185185
synthesizeEvent(
186-
false, key.logicalKey, key.physicalKey, event.getEventTime()));
186+
false, key.logicalKey, eventPhysicalKey, event.getEventTime()));
187187
}
188188
preEventStates[keyIdx] = nowStates[keyIdx];
189189
postEventAnyPressed = true;

engine/src/flutter/shell/platform/android/test/io/flutter/embedding/android/KeyboardManagerTest.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,6 +1669,68 @@ public void synchronizeModifiersForZeroedScanCode() {
16691669
calls.clear();
16701670
}
16711671

1672+
// Regression test for https://github.com/flutter/flutter/issues/164626.
1673+
@Test
1674+
public void synchronizeModifiersForZeroedScanCodeOnRepeatEvent() {
1675+
// Test if ShiftLeft can be correctly synchronized during down events of
1676+
// ShiftLeft that have 0 for their metaState and 0 for their scanCode.
1677+
final KeyboardTester tester = new KeyboardTester();
1678+
final ArrayList<CallRecord> calls = new ArrayList<>();
1679+
1680+
tester.recordEmbedderCallsTo(calls);
1681+
tester.respondToTextInputWith(true); // Suppress redispatching
1682+
1683+
// Test: repeat event when the meta state is 0 and scanCode is 0.
1684+
final KeyEvent shiftLeftKeyEvent =
1685+
new FakeKeyEvent(ACTION_DOWN, 0, KEYCODE_SHIFT_LEFT, 1, '\0', 0);
1686+
// Compute physicalKey in the same way as KeyboardManager.getPhysicalKey.
1687+
final Long shiftLeftPhysicalKey = KEYCODE_SHIFT_LEFT | KeyboardMap.kAndroidPlane;
1688+
1689+
assertEquals(tester.keyboardManager.handleEvent(shiftLeftKeyEvent), true);
1690+
assertEquals(calls.size(), 2);
1691+
assertEmbedderEventEquals(
1692+
calls.get(0).keyData,
1693+
Type.kDown,
1694+
shiftLeftPhysicalKey,
1695+
LOGICAL_SHIFT_LEFT,
1696+
null,
1697+
false,
1698+
DeviceType.kKeyboard);
1699+
assertEmbedderEventEquals(
1700+
calls.get(1).keyData,
1701+
Type.kUp,
1702+
shiftLeftPhysicalKey,
1703+
LOGICAL_SHIFT_LEFT,
1704+
null,
1705+
true,
1706+
DeviceType.kKeyboard);
1707+
calls.clear();
1708+
1709+
// Similar check for AltLeft.
1710+
final KeyEvent altLeftKeyEvent = new FakeKeyEvent(ACTION_DOWN, 0, KEYCODE_ALT_LEFT, 1, '\0', 0);
1711+
final Long altLeftPhysicalKey = KEYCODE_ALT_LEFT | KeyboardMap.kAndroidPlane;
1712+
1713+
assertEquals(tester.keyboardManager.handleEvent(altLeftKeyEvent), true);
1714+
assertEquals(calls.size(), 2);
1715+
assertEmbedderEventEquals(
1716+
calls.get(0).keyData,
1717+
Type.kDown,
1718+
altLeftPhysicalKey,
1719+
LOGICAL_ALT_LEFT,
1720+
null,
1721+
false,
1722+
DeviceType.kKeyboard);
1723+
assertEmbedderEventEquals(
1724+
calls.get(1).keyData,
1725+
Type.kUp,
1726+
altLeftPhysicalKey,
1727+
LOGICAL_ALT_LEFT,
1728+
null,
1729+
true,
1730+
DeviceType.kKeyboard);
1731+
calls.clear();
1732+
}
1733+
16721734
@Test
16731735
public void normalCapsLockEvents() {
16741736
final KeyboardTester tester = new KeyboardTester();

0 commit comments

Comments
 (0)