Flutter Linux Embedder
fl_key_embedder_responder_test.cc File Reference
#include "flutter/shell/platform/linux/fl_key_embedder_responder.h"
#include "gtest/gtest.h"
#include "flutter/shell/platform/embedder/test_utils/key_codes.g.h"
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/testing/fl_test.h"

Go to the source code of this file.

Classes

struct  _FlKeyEmbedderCallRecord
 

Functions

static void g_ptr_array_clear (GPtrArray *array)
 
 G_DECLARE_FINAL_TYPE (FlKeyEmbedderCallRecord, fl_key_embedder_call_record, FL, KEY_EMBEDDER_CALL_RECORD, GObject)
 
 G_DEFINE_TYPE (FlKeyEmbedderCallRecord, fl_key_embedder_call_record, G_TYPE_OBJECT) static void fl_key_embedder_call_record_init(FlKeyEmbedderCallRecord *self)
 
static void fl_key_embedder_call_record_dispose (GObject *object)
 
static void fl_key_embedder_call_record_class_init (FlKeyEmbedderCallRecordClass *klass)
 
static FlKeyEmbedderCallRecord * fl_key_embedder_call_record_new (const FlutterKeyEvent *event, FlutterKeyEventCallback callback, gpointer user_data)
 
static void verify_response_handled (bool handled, gpointer user_data)
 
static void invoke_record_callback_and_verify (FlKeyEmbedderCallRecord *record, bool expected_handled, void *expected_user_data)
 
static void record_calls (const FlutterKeyEvent *event, FlutterKeyEventCallback callback, void *callback_user_data, void *send_key_event_user_data)
 
static void clear_g_call_records ()
 
 TEST (FlKeyEmbedderResponderTest, SendKeyEvent)
 
 TEST (FlKeyEmbedderResponderTest, UsesSpecifiedLogicalKey)
 
 TEST (FlKeyEmbedderResponderTest, PressShiftDuringLetterKeyTap)
 
 TEST (FlKeyEmbedderResponderTest, TapNumPadKeysBetweenNumLockEvents)
 
 TEST (FlKeyEmbedderResponderTest, ReleaseShiftKeyBetweenDigitKeyEvents)
 
 TEST (FlKeyEmbedderResponderTest, TapLetterKeysBetweenCapsLockEvents)
 
 TEST (FlKeyEmbedderResponderTest, TapLetterKeysBetweenCapsLockEventsReversed)
 
 TEST (FlKeyEmbedderResponderTest, TurnDuplicateDownEventsToRepeats)
 
 TEST (FlKeyEmbedderResponderTest, IgnoreAbruptUpEvent)
 
 TEST (FlKeyEmbedderResponderTest, SynthesizeForDesyncPressingStateOnSelfEvents)
 
 TEST (FlKeyEmbedderResponderTest, SynthesizeForDesyncPressingStateOnNonSelfEvents)
 
 TEST (FlKeyEmbedderResponderTest, SynthesizeForDesyncPressingStateOnRemappedEvents)
 
 TEST (FlKeyEmbedderResponderTest, SynthesizeForDesyncLockModeOnNonSelfEvents)
 
 TEST (FlKeyEmbedderResponderTest, SynthesizeForDesyncLockModeOnSelfEvents)
 
 TEST (FlKeyEmbedderResponderTest, SynthesizationOccursOnIgnoredEvents)
 
 TEST (FlKeyEmbedderResponderTest, HandlesShiftAltVersusGroupNext)
 
 TEST (FlKeyEmbedderResponderTest, HandlesShiftAltLeftIsMetaLeft)
 

Variables

static gboolean g_expected_handled
 
static gpointer g_expected_user_data
 

Function Documentation

◆ clear_g_call_records()

static void clear_g_call_records ( )
static

Definition at line 132 of file fl_key_embedder_responder_test.cc.

132  {
133  g_ptr_array_free(g_call_records, TRUE);
134  g_call_records = nullptr;
135 }

References TRUE.

Referenced by TEST().

◆ fl_key_embedder_call_record_class_init()

static void fl_key_embedder_call_record_class_init ( FlKeyEmbedderCallRecordClass *  klass)
static

Definition at line 71 of file fl_key_embedder_responder_test.cc.

72  {
73  G_OBJECT_CLASS(klass)->dispose = fl_key_embedder_call_record_dispose;
74 }

References fl_key_embedder_call_record_dispose().

◆ fl_key_embedder_call_record_dispose()

static void fl_key_embedder_call_record_dispose ( GObject *  object)
static

Definition at line 59 of file fl_key_embedder_responder_test.cc.

59  {
60  g_return_if_fail(FL_IS_KEY_EMBEDDER_CALL_RECORD(object));
61 
62  FlKeyEmbedderCallRecord* self = FL_KEY_EMBEDDER_CALL_RECORD(object);
63  if (self->event != nullptr) {
64  g_free(const_cast<char*>(self->event->character));
65  g_free(self->event);
66  }
67  G_OBJECT_CLASS(fl_key_embedder_call_record_parent_class)->dispose(object);
68 }

Referenced by fl_key_embedder_call_record_class_init().

◆ fl_key_embedder_call_record_new()

static FlKeyEmbedderCallRecord* fl_key_embedder_call_record_new ( const FlutterKeyEvent *  event,
FlutterKeyEventCallback  callback,
gpointer  user_data 
)
static

Definition at line 76 of file fl_key_embedder_responder_test.cc.

79  {
80  g_return_val_if_fail(event != nullptr, nullptr);
81 
82  FlKeyEmbedderCallRecord* self = FL_KEY_EMBEDDER_CALL_RECORD(
83  g_object_new(fl_key_embedder_call_record_get_type(), nullptr));
84 
85  FlutterKeyEvent* clone_event = g_new(FlutterKeyEvent, 1);
86  *clone_event = *event;
87  if (event->character != nullptr) {
88  size_t character_length = strlen(event->character);
89  char* clone_character = g_new(char, character_length + 1);
90  strncpy(clone_character, event->character, character_length + 1);
91  clone_event->character = clone_character;
92  }
93  self->event = clone_event;
94  self->callback = callback;
95  self->user_data = user_data;
96 
97  return self;
98 }

References callback, event, and user_data.

Referenced by record_calls().

◆ G_DECLARE_FINAL_TYPE()

G_DECLARE_FINAL_TYPE ( FlKeyEmbedderCallRecord  ,
fl_key_embedder_call_record  ,
FL  ,
KEY_EMBEDDER_CALL_RECORD  ,
GObject   
)

◆ G_DEFINE_TYPE()

G_DEFINE_TYPE ( FlKeyEmbedderCallRecord  ,
fl_key_embedder_call_record  ,
G_TYPE_OBJECT   
)

Definition at line 52 of file fl_key_embedder_responder_test.cc.

56  {}

◆ g_ptr_array_clear()

static void g_ptr_array_clear ( GPtrArray *  array)
static

Definition at line 34 of file fl_key_embedder_responder_test.cc.

34  {
35  g_ptr_array_remove_range(array, 0, array->len);
36 }

Referenced by TEST().

◆ invoke_record_callback_and_verify()

static void invoke_record_callback_and_verify ( FlKeyEmbedderCallRecord *  record,
bool  expected_handled,
void *  expected_user_data 
)
static

Definition at line 107 of file fl_key_embedder_responder_test.cc.

109  {
110  g_return_if_fail(record->callback != nullptr);
112  g_expected_user_data = expected_user_data;
113  record->callback(expected_handled, record->user_data);
114 }

References expected_handled, g_expected_handled, and g_expected_user_data.

Referenced by TEST().

◆ record_calls()

static void record_calls ( const FlutterKeyEvent *  event,
FlutterKeyEventCallback  callback,
void *  callback_user_data,
void *  send_key_event_user_data 
)
static

Definition at line 120 of file fl_key_embedder_responder_test.cc.

123  {
124  GPtrArray* records_array =
125  reinterpret_cast<GPtrArray*>(send_key_event_user_data);
126  if (records_array != nullptr) {
127  g_ptr_array_add(records_array, fl_key_embedder_call_record_new(
128  event, callback, callback_user_data));
129  }
130 }

References callback, event, and fl_key_embedder_call_record_new().

Referenced by TEST().

◆ TEST() [1/17]

TEST ( FlKeyEmbedderResponderTest  ,
HandlesShiftAltLeftIsMetaLeft   
)

Definition at line 1683 of file fl_key_embedder_responder_test.cc.

1683  {
1684  EXPECT_EQ(g_call_records, nullptr);
1685  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1686  FlKeyResponder* responder = FL_KEY_RESPONDER(
1687  fl_key_embedder_responder_new(record_calls, g_call_records));
1688 
1689  g_expected_handled = true;
1690  guint32 now_time = 1;
1691  // A convenient shorthand to simulate events.
1692  auto send_key_event = [responder, &now_time](bool is_press, guint keyval,
1693  guint16 keycode,
1694  GdkModifierType state) {
1695  now_time += 1;
1696  int user_data = 123; // Arbitrary user data
1697  g_autoptr(FlKeyEvent) event =
1698  fl_key_event_new(now_time, is_press, keycode, keyval, state, 0);
1700  &user_data);
1701  };
1702 
1703  FlKeyEmbedderCallRecord* record;
1704 
1705  // ShiftLeft + AltLeft
1706  send_key_event(kPress, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1707  GDK_MODIFIER_RESERVED_25_MASK);
1708  EXPECT_EQ(g_call_records->len, 1u);
1709  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1710  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1711  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1712  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
1713  EXPECT_EQ(record->event->synthesized, false);
1714 
1715  send_key_event(kPress, GDK_KEY_Meta_L, kKeyCodeAltLeft,
1716  static_cast<GdkModifierType>(GDK_SHIFT_MASK |
1717  GDK_MODIFIER_RESERVED_25_MASK));
1718  EXPECT_EQ(g_call_records->len, 2u);
1719  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1720  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1721  EXPECT_EQ(record->event->physical, kPhysicalMetaLeft);
1722  EXPECT_EQ(record->event->logical, kLogicalMetaLeft);
1723  EXPECT_EQ(record->event->synthesized, false);
1724 
1725  send_key_event(kRelease, GDK_KEY_Meta_L, kKeyCodeAltLeft,
1726  static_cast<GdkModifierType>(GDK_MODIFIER_RESERVED_13_MASK |
1727  GDK_MODIFIER_RESERVED_25_MASK));
1728  send_key_event(kRelease, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1729  GDK_MODIFIER_RESERVED_25_MASK);
1730  g_ptr_array_clear(g_call_records);
1731 
1732  // ShiftRight + AltLeft
1733  send_key_event(kPress, GDK_KEY_Shift_R, kKeyCodeShiftRight,
1734  GDK_MODIFIER_RESERVED_25_MASK);
1735  EXPECT_EQ(g_call_records->len, 1u);
1736  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1737  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1738  EXPECT_EQ(record->event->physical, kPhysicalShiftRight);
1739  EXPECT_EQ(record->event->logical, kLogicalShiftRight);
1740  EXPECT_EQ(record->event->synthesized, false);
1741 
1742  send_key_event(kPress, GDK_KEY_Meta_L, kKeyCodeAltLeft,
1743  static_cast<GdkModifierType>(GDK_SHIFT_MASK |
1744  GDK_MODIFIER_RESERVED_25_MASK));
1745  EXPECT_EQ(g_call_records->len, 2u);
1746  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1747  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1748  EXPECT_EQ(record->event->physical, kPhysicalMetaLeft);
1749  EXPECT_EQ(record->event->logical, kLogicalMetaLeft);
1750  EXPECT_EQ(record->event->synthesized, false);
1751 
1753  g_object_unref(responder);
1754 }

References clear_g_call_records(), event, fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_expected_handled, g_ptr_array_clear(), record_calls(), send_key_event(), state, user_data, and verify_response_handled().

◆ TEST() [2/17]

TEST ( FlKeyEmbedderResponderTest  ,
HandlesShiftAltVersusGroupNext   
)

Definition at line 1575 of file fl_key_embedder_responder_test.cc.

1575  {
1576  EXPECT_EQ(g_call_records, nullptr);
1577  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1578  FlKeyResponder* responder = FL_KEY_RESPONDER(
1579  fl_key_embedder_responder_new(record_calls, g_call_records));
1580 
1581  g_expected_handled = true;
1582  guint32 now_time = 1;
1583  // A convenient shorthand to simulate events.
1584  auto send_key_event = [responder, &now_time](bool is_press, guint keyval,
1585  guint16 keycode,
1586  GdkModifierType state) {
1587  now_time += 1;
1588  int user_data = 123; // Arbitrary user data
1589  g_autoptr(FlKeyEvent) event =
1590  fl_key_event_new(now_time, is_press, keycode, keyval, state, 0);
1592  &user_data);
1593  };
1594 
1595  FlKeyEmbedderCallRecord* record;
1596 
1597  send_key_event(kPress, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1598  GDK_MODIFIER_RESERVED_25_MASK);
1599  EXPECT_EQ(g_call_records->len, 1u);
1600  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1601  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1602  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1603  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
1604  EXPECT_EQ(record->event->synthesized, false);
1605 
1606  send_key_event(kPress, GDK_KEY_Meta_R, kKeyCodeAltRight,
1607  static_cast<GdkModifierType>(GDK_SHIFT_MASK |
1608  GDK_MODIFIER_RESERVED_25_MASK));
1609  EXPECT_EQ(g_call_records->len, 2u);
1610  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1611  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1612  EXPECT_EQ(record->event->physical, kPhysicalAltRight);
1613  EXPECT_EQ(record->event->logical, kLogicalMetaRight);
1614  EXPECT_EQ(record->event->synthesized, false);
1615 
1616  send_key_event(kRelease, GDK_KEY_ISO_Next_Group, kKeyCodeShiftLeft,
1617  static_cast<GdkModifierType>(GDK_SHIFT_MASK | GDK_MOD1_MASK |
1618  GDK_MODIFIER_RESERVED_25_MASK));
1619  EXPECT_EQ(g_call_records->len, 5u);
1620  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 2));
1621  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1622  EXPECT_EQ(record->event->physical, kPhysicalAltLeft);
1623  EXPECT_EQ(record->event->logical, kLogicalAltLeft);
1624  EXPECT_EQ(record->event->synthesized, true);
1625 
1626  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 3));
1627  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1628  EXPECT_EQ(record->event->physical, kPhysicalAltRight);
1629  EXPECT_EQ(record->event->logical, kLogicalMetaRight);
1630  EXPECT_EQ(record->event->synthesized, true);
1631 
1632  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 4));
1633  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1634  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1635  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
1636  EXPECT_EQ(record->event->synthesized, false);
1637 
1638  send_key_event(kPress, GDK_KEY_ISO_Next_Group, kKeyCodeShiftLeft,
1639  static_cast<GdkModifierType>(GDK_MOD1_MASK |
1640  GDK_MODIFIER_RESERVED_25_MASK));
1641  EXPECT_EQ(g_call_records->len, 6u);
1642  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 5));
1643  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1644  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1645  EXPECT_EQ(record->event->logical, kLogicalGroupNext);
1646  EXPECT_EQ(record->event->synthesized, false);
1647 
1648  send_key_event(kRelease, GDK_KEY_ISO_Level3_Shift, kKeyCodeAltRight,
1649  static_cast<GdkModifierType>(GDK_MOD1_MASK |
1650  GDK_MODIFIER_RESERVED_13_MASK |
1651  GDK_MODIFIER_RESERVED_25_MASK));
1652  EXPECT_EQ(g_call_records->len, 7u);
1653  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 6));
1654  EXPECT_EQ(record->event->physical, 0u);
1655  EXPECT_EQ(record->event->logical, 0u);
1656 
1657  send_key_event(kRelease, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1658  static_cast<GdkModifierType>(GDK_MODIFIER_RESERVED_13_MASK |
1659  GDK_MODIFIER_RESERVED_25_MASK));
1660  EXPECT_EQ(g_call_records->len, 9u);
1661  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 7));
1662  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1663  EXPECT_EQ(record->event->physical, kPhysicalAltLeft);
1664  EXPECT_EQ(record->event->logical, kLogicalAltLeft);
1665  EXPECT_EQ(record->event->synthesized, true);
1666 
1667  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 8));
1668  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1669  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1670  EXPECT_EQ(record->event->logical, kLogicalGroupNext);
1671  EXPECT_EQ(record->event->synthesized, false);
1672 
1674  g_object_unref(responder);
1675 }

References clear_g_call_records(), event, fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_expected_handled, record_calls(), send_key_event(), state, user_data, and verify_response_handled().

◆ TEST() [3/17]

TEST ( FlKeyEmbedderResponderTest  ,
IgnoreAbruptUpEvent   
)

Definition at line 969 of file fl_key_embedder_responder_test.cc.

969  {
970  FlKeyEmbedderCallRecord* record;
971 
972  EXPECT_EQ(g_call_records, nullptr);
973  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
974  FlKeyResponder* responder = FL_KEY_RESPONDER(
976  int user_data = 123; // Arbitrary user data
977 
978  // Release KeyA before it was even pressed.
979  g_expected_handled = true; // The empty event is always handled.
980  g_autoptr(FlKeyEvent) event =
981  fl_key_event_new(103, kRelease, kKeyCodeKeyA, GDK_KEY_q,
982  static_cast<GdkModifierType>(0), 0);
984  &user_data);
985 
986  EXPECT_EQ(g_call_records->len, 1u);
987 
988  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
989  EXPECT_EQ(record->event->physical, 0ull);
990  EXPECT_EQ(record->event->logical, 0ull);
991  EXPECT_STREQ(record->event->character, nullptr);
992  EXPECT_EQ(record->event->synthesized, false);
993  EXPECT_EQ(record->callback, nullptr);
994 
996  g_object_unref(responder);
997 }

References clear_g_call_records(), event, fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_expected_handled, record_calls(), user_data, and verify_response_handled().

◆ TEST() [4/17]

TEST ( FlKeyEmbedderResponderTest  ,
PressShiftDuringLetterKeyTap   
)

Definition at line 269 of file fl_key_embedder_responder_test.cc.

269  {
270  EXPECT_EQ(g_call_records, nullptr);
271  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
272  FlKeyResponder* responder = FL_KEY_RESPONDER(
274  int user_data = 123; // Arbitrary user data
275 
276  FlKeyEmbedderCallRecord* record;
277 
278  // Press shift right
279  g_autoptr(FlKeyEvent) event1 =
280  fl_key_event_new(101, kPress, kKeyCodeShiftRight, GDK_KEY_Shift_R,
281  static_cast<GdkModifierType>(0), 0);
283  &user_data);
284 
285  EXPECT_EQ(g_call_records->len, 1u);
286  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
287  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
288  EXPECT_EQ(record->event->physical, kPhysicalShiftRight);
289  EXPECT_EQ(record->event->logical, kLogicalShiftRight);
290  EXPECT_STREQ(record->event->character, nullptr);
291  EXPECT_EQ(record->event->synthesized, false);
292 
294  g_ptr_array_clear(g_call_records);
295 
296  // Press key A
297  g_autoptr(FlKeyEvent) event2 =
298  fl_key_event_new(102, kPress, kKeyCodeKeyA, GDK_KEY_A, GDK_SHIFT_MASK, 0);
300  &user_data);
301 
302  EXPECT_EQ(g_call_records->len, 1u);
303  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
304  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
305  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
306  EXPECT_EQ(record->event->logical, kLogicalKeyA);
307  EXPECT_STREQ(record->event->character, "A");
308  EXPECT_EQ(record->event->synthesized, false);
309 
311  g_ptr_array_clear(g_call_records);
312 
313  // Release shift right
314  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(
315  103, kRelease, kKeyCodeShiftRight, GDK_KEY_Shift_R, GDK_SHIFT_MASK, 0);
317  &user_data);
318 
319  EXPECT_EQ(g_call_records->len, 1u);
320  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
321  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
322  EXPECT_EQ(record->event->physical, kPhysicalShiftRight);
323  EXPECT_EQ(record->event->logical, kLogicalShiftRight);
324  EXPECT_STREQ(record->event->character, nullptr);
325  EXPECT_EQ(record->event->synthesized, false);
326 
328  g_ptr_array_clear(g_call_records);
329 
330  // Release key A
331  g_autoptr(FlKeyEvent) event4 =
332  fl_key_event_new(104, kRelease, kKeyCodeKeyA, GDK_KEY_A,
333  static_cast<GdkModifierType>(0), 0);
335  &user_data);
336 
337  EXPECT_EQ(g_call_records->len, 1u);
338  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
339  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
340  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
341  EXPECT_EQ(record->event->logical, kLogicalKeyA);
342  EXPECT_STREQ(record->event->character, nullptr);
343  EXPECT_EQ(record->event->synthesized, false);
344 
346  g_ptr_array_clear(g_call_records);
347 
349  g_object_unref(responder);
350 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_ptr_array_clear(), invoke_record_callback_and_verify(), record_calls(), TRUE, user_data, and verify_response_handled().

◆ TEST() [5/17]

TEST ( FlKeyEmbedderResponderTest  ,
ReleaseShiftKeyBetweenDigitKeyEvents   
)

Definition at line 515 of file fl_key_embedder_responder_test.cc.

515  {
516  EXPECT_EQ(g_call_records, nullptr);
517  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
518  FlKeyResponder* responder = FL_KEY_RESPONDER(
520  int user_data = 123; // Arbitrary user data
521 
522  FlKeyEmbedderCallRecord* record;
523 
524  GdkModifierType state = static_cast<GdkModifierType>(0);
525 
526  // Press shift left
527  g_autoptr(FlKeyEvent) event1 = fl_key_event_new(
528  101, kPress, kKeyCodeShiftLeft, GDK_KEY_Shift_L, state, 0);
530  &user_data);
531 
532  EXPECT_EQ(g_call_records->len, 1u);
533  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
534  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
535  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
536  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
537  EXPECT_STREQ(record->event->character, nullptr);
538  EXPECT_EQ(record->event->synthesized, false);
539 
541  g_ptr_array_clear(g_call_records);
542 
543  state = GDK_SHIFT_MASK;
544 
545  // Press digit 1, which is '!' on a US keyboard
546  g_autoptr(FlKeyEvent) event2 =
547  fl_key_event_new(102, kPress, kKeyCodeDigit1, GDK_KEY_exclam, state, 0);
549  &user_data);
550 
551  EXPECT_EQ(g_call_records->len, 1u);
552  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
553  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
554  EXPECT_EQ(record->event->physical, kPhysicalDigit1);
555  EXPECT_EQ(record->event->logical, kLogicalExclamation);
556  EXPECT_STREQ(record->event->character, "!");
557  EXPECT_EQ(record->event->synthesized, false);
558 
560  g_ptr_array_clear(g_call_records);
561 
562  // Release shift
563  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(
564  103, kRelease, kKeyCodeShiftLeft, GDK_KEY_Shift_L, state, 0);
566  &user_data);
567 
568  EXPECT_EQ(g_call_records->len, 1u);
569  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
570  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
571  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
572  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
573  EXPECT_STREQ(record->event->character, nullptr);
574  EXPECT_EQ(record->event->synthesized, false);
575 
577  g_ptr_array_clear(g_call_records);
578 
579  state = static_cast<GdkModifierType>(0);
580 
581  // Release digit 1, which is "1" because shift has been released.
582  g_autoptr(FlKeyEvent) event4 =
583  fl_key_event_new(104, kRelease, kKeyCodeDigit1, GDK_KEY_1, state, 0);
585  &user_data);
586 
587  EXPECT_EQ(g_call_records->len, 1u);
588  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
589  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
590  EXPECT_EQ(record->event->physical, kPhysicalDigit1);
591  EXPECT_EQ(record->event->logical, kLogicalExclamation); // Important
592  EXPECT_STREQ(record->event->character, nullptr);
593  EXPECT_EQ(record->event->synthesized, false);
594 
596  g_ptr_array_clear(g_call_records);
597 
599  g_object_unref(responder);
600 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_ptr_array_clear(), invoke_record_callback_and_verify(), record_calls(), state, TRUE, user_data, and verify_response_handled().

◆ TEST() [6/17]

TEST ( FlKeyEmbedderResponderTest  ,
SendKeyEvent   
)

Definition at line 138 of file fl_key_embedder_responder_test.cc.

138  {
139  EXPECT_EQ(g_call_records, nullptr);
140  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
141  FlKeyResponder* responder = FL_KEY_RESPONDER(
143  int user_data = 123; // Arbitrary user data
144 
145  FlKeyEmbedderCallRecord* record;
146 
147  // On a QWERTY keyboard, press key Q (physically key A), and release.
148  // Key down
149  g_autoptr(FlKeyEvent) event1 =
150  fl_key_event_new(12345, kPress, kKeyCodeKeyA, GDK_KEY_a,
151  static_cast<GdkModifierType>(0), 0);
153  &user_data);
154 
155  EXPECT_EQ(g_call_records->len, 1u);
156  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
157  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
158  EXPECT_EQ(record->event->timestamp, 12345000);
159  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
160  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
161  EXPECT_EQ(record->event->logical, kLogicalKeyA);
162  EXPECT_STREQ(record->event->character, "a");
163  EXPECT_EQ(record->event->synthesized, false);
164 
166  g_ptr_array_clear(g_call_records);
167 
168  // Key up
169  g_autoptr(FlKeyEvent) event2 =
170  fl_key_event_new(12346, kRelease, kKeyCodeKeyA, GDK_KEY_a,
171  static_cast<GdkModifierType>(0), 0);
173  &user_data);
174 
175  EXPECT_EQ(g_call_records->len, 1u);
176  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
177  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
178  EXPECT_EQ(record->event->timestamp, 12346000);
179  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
180  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
181  EXPECT_EQ(record->event->logical, kLogicalKeyA);
182  EXPECT_STREQ(record->event->character, nullptr);
183  EXPECT_EQ(record->event->synthesized, false);
184 
186  g_ptr_array_clear(g_call_records);
187 
188  // On an AZERTY keyboard, press key Q (physically key A), and release.
189  // Key down
190  g_autoptr(FlKeyEvent) event3 =
191  fl_key_event_new(12347, kPress, kKeyCodeKeyA, GDK_KEY_q,
192  static_cast<GdkModifierType>(0), 0);
194  &user_data);
195 
196  EXPECT_EQ(g_call_records->len, 1u);
197  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
198  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
199  EXPECT_EQ(record->event->timestamp, 12347000);
200  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
201  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
202  EXPECT_EQ(record->event->logical, kLogicalKeyQ);
203  EXPECT_STREQ(record->event->character, "q");
204  EXPECT_EQ(record->event->synthesized, false);
205 
207  g_ptr_array_clear(g_call_records);
208 
209  // Key up
210  g_autoptr(FlKeyEvent) event4 =
211  fl_key_event_new(12348, kRelease, kKeyCodeKeyA, GDK_KEY_q,
212  static_cast<GdkModifierType>(0), 0);
214  &user_data);
215 
216  EXPECT_EQ(g_call_records->len, 1u);
217  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
218  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
219  EXPECT_EQ(record->event->timestamp, 12348000);
220  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
221  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
222  EXPECT_EQ(record->event->logical, kLogicalKeyQ);
223  EXPECT_STREQ(record->event->character, nullptr);
224  EXPECT_EQ(record->event->synthesized, false);
225 
227  g_ptr_array_clear(g_call_records);
228 
230  g_object_unref(responder);
231 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_ptr_array_clear(), invoke_record_callback_and_verify(), record_calls(), TRUE, user_data, and verify_response_handled().

◆ TEST() [7/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizationOccursOnIgnoredEvents   
)

Definition at line 1522 of file fl_key_embedder_responder_test.cc.

1522  {
1523  EXPECT_EQ(g_call_records, nullptr);
1524  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1525  FlKeyResponder* responder = FL_KEY_RESPONDER(
1526  fl_key_embedder_responder_new(record_calls, g_call_records));
1527  int user_data = 123; // Arbitrary user data
1528 
1529  FlKeyEmbedderCallRecord* record;
1530 
1531  // The NumLock is desynchronized by being enabled, and Control is pressed.
1532  GdkModifierType state =
1533  static_cast<GdkModifierType>(GDK_MOD2_MASK | GDK_CONTROL_MASK);
1534 
1535  // Send a KeyA up event, which will be ignored.
1536  g_expected_handled = true; // The ignored event is always handled.
1537  g_autoptr(FlKeyEvent) event =
1538  fl_key_event_new(101, kRelease, kKeyCodeKeyA, GDK_KEY_a, state, 0);
1540  &user_data);
1541 
1542  EXPECT_EQ(g_call_records->len, 2u);
1543  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1544  EXPECT_EQ(record->event->timestamp, 101000);
1545  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1546  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1547  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1548  EXPECT_STREQ(record->event->character, nullptr);
1549  EXPECT_EQ(record->event->synthesized, true);
1550 
1551  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1552  EXPECT_EQ(record->event->timestamp, 101000);
1553  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1554  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1555  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1556  EXPECT_STREQ(record->event->character, nullptr);
1557  EXPECT_EQ(record->event->synthesized, true);
1558 
1559  g_ptr_array_clear(g_call_records);
1560 
1562  g_object_unref(responder);
1563 }

References clear_g_call_records(), event, fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_expected_handled, g_ptr_array_clear(), record_calls(), state, user_data, and verify_response_handled().

◆ TEST() [8/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncLockModeOnNonSelfEvents   
)

Definition at line 1320 of file fl_key_embedder_responder_test.cc.

1320  {
1321  EXPECT_EQ(g_call_records, nullptr);
1322  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1323  FlKeyResponder* responder = FL_KEY_RESPONDER(
1324  fl_key_embedder_responder_new(record_calls, g_call_records));
1325  int user_data = 123; // Arbitrary user data
1326 
1327  FlKeyEmbedderCallRecord* record;
1328 
1329  // The NumLock is desynchronized by being enabled.
1330  GdkModifierType state = GDK_MOD2_MASK;
1331 
1332  // Send a normal event
1333  g_autoptr(FlKeyEvent) event1 =
1334  fl_key_event_new(101, kPress, kKeyCodeKeyA, GDK_KEY_a, state, 0);
1336  &user_data);
1337 
1338  EXPECT_EQ(g_call_records->len, 2u);
1339  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1340  EXPECT_EQ(record->event->timestamp, 101000);
1341  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1342  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1343  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1344  EXPECT_STREQ(record->event->character, nullptr);
1345  EXPECT_EQ(record->event->synthesized, true);
1346 
1347  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1348  EXPECT_EQ(record->event->timestamp, 101000);
1349  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1350  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1351  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1352  EXPECT_STREQ(record->event->character, "a");
1353  EXPECT_EQ(record->event->synthesized, false);
1354 
1356  g_ptr_array_clear(g_call_records);
1357 
1358  // The NumLock is desynchronized by being disabled.
1359  state = static_cast<GdkModifierType>(0);
1360 
1361  // Release key A
1362  g_autoptr(FlKeyEvent) event2 =
1363  fl_key_event_new(102, kRelease, kKeyCodeKeyA, GDK_KEY_A, state, 0);
1365  &user_data);
1366 
1367  EXPECT_EQ(g_call_records->len, 4u);
1368  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1369  EXPECT_EQ(record->event->timestamp, 102000);
1370  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1371  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1372  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1373  EXPECT_STREQ(record->event->character, nullptr);
1374  EXPECT_EQ(record->event->synthesized, true);
1375 
1376  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1377  EXPECT_EQ(record->event->timestamp, 102000);
1378  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1379  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1380  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1381  EXPECT_STREQ(record->event->character, nullptr);
1382  EXPECT_EQ(record->event->synthesized, true);
1383 
1384  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 2));
1385  EXPECT_EQ(record->event->timestamp, 102000);
1386  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1387  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1388  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1389  EXPECT_STREQ(record->event->character, nullptr);
1390  EXPECT_EQ(record->event->synthesized, true);
1391 
1392  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 3));
1393  EXPECT_EQ(record->event->timestamp, 102000);
1394  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1395  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1396  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1397  EXPECT_STREQ(record->event->character, nullptr);
1398  EXPECT_EQ(record->event->synthesized, false);
1399 
1401  g_ptr_array_clear(g_call_records);
1402 
1403  // Release NumLock. Since the previous event should have synthesized NumLock
1404  // to be released, this should result in only an empty event.
1405  g_expected_handled = true;
1406  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(
1407  103, kRelease, kKeyCodeNumLock, GDK_KEY_Num_Lock, state, 0);
1409  &user_data);
1410 
1411  EXPECT_EQ(g_call_records->len, 1u);
1412  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1413  EXPECT_EQ(record->event->physical, 0ull);
1414  EXPECT_EQ(record->event->logical, 0ull);
1415  EXPECT_STREQ(record->event->character, nullptr);
1416  EXPECT_EQ(record->event->synthesized, false);
1417  EXPECT_EQ(record->callback, nullptr);
1418 
1420  g_object_unref(responder);
1421 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_expected_handled, g_ptr_array_clear(), invoke_record_callback_and_verify(), record_calls(), state, TRUE, user_data, and verify_response_handled().

◆ TEST() [9/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncLockModeOnSelfEvents   
)

Definition at line 1425 of file fl_key_embedder_responder_test.cc.

1425  {
1426  EXPECT_EQ(g_call_records, nullptr);
1427  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1428  FlKeyResponder* responder = FL_KEY_RESPONDER(
1429  fl_key_embedder_responder_new(record_calls, g_call_records));
1430  int user_data = 123; // Arbitrary user data
1431 
1432  FlKeyEmbedderCallRecord* record;
1433 
1434  // The NumLock is desynchronized by being enabled.
1435  GdkModifierType state = GDK_MOD2_MASK;
1436 
1437  // NumLock down
1438  g_autoptr(FlKeyEvent) event1 = fl_key_event_new(101, kPress, kKeyCodeNumLock,
1439  GDK_KEY_Num_Lock, state, 0);
1441  &user_data);
1442 
1443  EXPECT_EQ(g_call_records->len, 3u);
1444  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1445  EXPECT_EQ(record->event->timestamp, 101000);
1446  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1447  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1448  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1449  EXPECT_STREQ(record->event->character, nullptr);
1450  EXPECT_EQ(record->event->synthesized, true);
1451 
1452  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1453  EXPECT_EQ(record->event->timestamp, 101000);
1454  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1455  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1456  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1457  EXPECT_STREQ(record->event->character, nullptr);
1458  EXPECT_EQ(record->event->synthesized, true);
1459 
1460  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 2));
1461  EXPECT_EQ(record->event->timestamp, 101000);
1462  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1463  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1464  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1465  EXPECT_STREQ(record->event->character, nullptr);
1466  EXPECT_EQ(record->event->synthesized, false);
1467 
1469  g_ptr_array_clear(g_call_records);
1470 
1471  // The NumLock is desynchronized by being enabled in a press event.
1472  state = GDK_MOD2_MASK;
1473 
1474  // NumLock up
1475  g_autoptr(FlKeyEvent) event2 = fl_key_event_new(102, kPress, kKeyCodeNumLock,
1476  GDK_KEY_Num_Lock, state, 0);
1478  &user_data);
1479 
1480  EXPECT_EQ(g_call_records->len, 4u);
1481  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1482  EXPECT_EQ(record->event->timestamp, 102000);
1483  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1484  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1485  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1486  EXPECT_STREQ(record->event->character, nullptr);
1487  EXPECT_EQ(record->event->synthesized, true);
1488 
1489  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1490  EXPECT_EQ(record->event->timestamp, 102000);
1491  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1492  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1493  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1494  EXPECT_STREQ(record->event->character, nullptr);
1495  EXPECT_EQ(record->event->synthesized, true);
1496 
1497  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 2));
1498  EXPECT_EQ(record->event->timestamp, 102000);
1499  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1500  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1501  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1502  EXPECT_STREQ(record->event->character, nullptr);
1503  EXPECT_EQ(record->event->synthesized, true);
1504 
1505  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 3));
1506  EXPECT_EQ(record->event->timestamp, 102000);
1507  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1508  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1509  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1510  EXPECT_STREQ(record->event->character, nullptr);
1511  EXPECT_EQ(record->event->synthesized, false);
1512 
1514  g_ptr_array_clear(g_call_records);
1515 
1517  g_object_unref(responder);
1518 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_ptr_array_clear(), invoke_record_callback_and_verify(), record_calls(), state, TRUE, user_data, and verify_response_handled().

◆ TEST() [10/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncPressingStateOnNonSelfEvents   
)

Definition at line 1126 of file fl_key_embedder_responder_test.cc.

1127  {
1128  EXPECT_EQ(g_call_records, nullptr);
1129  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1130  FlKeyResponder* responder = FL_KEY_RESPONDER(
1131  fl_key_embedder_responder_new(record_calls, g_call_records));
1132  int user_data = 123; // Arbitrary user data
1133 
1134  FlKeyEmbedderCallRecord* record;
1135 
1136  // A key down of control left is missed.
1137  GdkModifierType state = GDK_CONTROL_MASK;
1138 
1139  // Send a normal event (KeyA down)
1140  g_autoptr(FlKeyEvent) event1 =
1141  fl_key_event_new(101, kPress, kKeyCodeKeyA, GDK_KEY_a, state, 0);
1143  &user_data);
1144 
1145  EXPECT_EQ(g_call_records->len, 2u);
1146  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1147  EXPECT_EQ(record->event->timestamp, 101000);
1148  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1149  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1150  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1151  EXPECT_STREQ(record->event->character, nullptr);
1152  EXPECT_EQ(record->event->synthesized, true);
1153 
1154  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1155  EXPECT_EQ(record->event->timestamp, 101000);
1156  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1157  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1158  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1159  EXPECT_STREQ(record->event->character, "a");
1160  EXPECT_EQ(record->event->synthesized, false);
1161 
1163  g_ptr_array_clear(g_call_records);
1164 
1165  // A key up of control left is missed.
1166  state = static_cast<GdkModifierType>(0);
1167 
1168  // Send a normal event (KeyA up)
1169  g_autoptr(FlKeyEvent) event2 =
1170  fl_key_event_new(102, kRelease, kKeyCodeKeyA, GDK_KEY_A, state, 0);
1172  &user_data);
1173 
1174  EXPECT_EQ(g_call_records->len, 2u);
1175  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1176  EXPECT_EQ(record->event->timestamp, 102000);
1177  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1178  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1179  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1180  EXPECT_STREQ(record->event->character, nullptr);
1181  EXPECT_EQ(record->event->synthesized, true);
1182 
1183  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1184  EXPECT_EQ(record->event->timestamp, 102000);
1185  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1186  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1187  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1188  EXPECT_STREQ(record->event->character, nullptr);
1189  EXPECT_EQ(record->event->synthesized, false);
1190 
1192  g_ptr_array_clear(g_call_records);
1193 
1194  // Test non-default key mapping.
1195 
1196  // Press a key with physical CapsLock and logical ControlLeft.
1197  state = static_cast<GdkModifierType>(0);
1198 
1199  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(101, kPress, kKeyCodeCapsLock,
1200  GDK_KEY_Control_L, state, 0);
1202  &user_data);
1203 
1204  EXPECT_EQ(g_call_records->len, 1u);
1205  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1206  EXPECT_EQ(record->event->timestamp, 101000);
1207  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1208  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1209  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1210  EXPECT_STREQ(record->event->character, nullptr);
1211  EXPECT_EQ(record->event->synthesized, false);
1212 
1214  g_ptr_array_clear(g_call_records);
1215 
1216  // The key up of the control left press is missed.
1217  state = static_cast<GdkModifierType>(0);
1218 
1219  // Send a normal event (KeyA down).
1220  g_autoptr(FlKeyEvent) event4 =
1221  fl_key_event_new(102, kPress, kKeyCodeKeyA, GDK_KEY_A, state, 0);
1223  &user_data);
1224 
1225  // The synthesized event should have physical CapsLock and logical
1226  // ControlLeft.
1227  EXPECT_EQ(g_call_records->len, 2u);
1228  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1229  EXPECT_EQ(record->event->timestamp, 102000);
1230  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1231  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1232  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1233  EXPECT_STREQ(record->event->character, nullptr);
1234  EXPECT_EQ(record->event->synthesized, true);
1235 
1236  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1237  EXPECT_EQ(record->event->timestamp, 102000);
1238  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1239  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1240  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1241  EXPECT_STREQ(record->event->character, "A");
1242  EXPECT_EQ(record->event->synthesized, false);
1243 
1245  g_ptr_array_clear(g_call_records);
1246 
1248  g_object_unref(responder);
1249 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_ptr_array_clear(), invoke_record_callback_and_verify(), record_calls(), state, TRUE, user_data, and verify_response_handled().

◆ TEST() [11/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncPressingStateOnRemappedEvents   
)

Definition at line 1253 of file fl_key_embedder_responder_test.cc.

1254  {
1255  EXPECT_EQ(g_call_records, nullptr);
1256  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1257  FlKeyResponder* responder = FL_KEY_RESPONDER(
1258  fl_key_embedder_responder_new(record_calls, g_call_records));
1259  int user_data = 123; // Arbitrary user data
1260 
1261  FlKeyEmbedderCallRecord* record;
1262 
1263  // Press a key with physical CapsLock and logical ControlLeft.
1264  GdkModifierType state = static_cast<GdkModifierType>(0);
1265 
1266  g_autoptr(FlKeyEvent) event1 = fl_key_event_new(101, kPress, kKeyCodeCapsLock,
1267  GDK_KEY_Control_L, state, 0);
1269  &user_data);
1270 
1271  EXPECT_EQ(g_call_records->len, 1u);
1272  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1273  EXPECT_EQ(record->event->timestamp, 101000);
1274  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1275  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1276  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1277  EXPECT_STREQ(record->event->character, nullptr);
1278  EXPECT_EQ(record->event->synthesized, false);
1279 
1281  g_ptr_array_clear(g_call_records);
1282 
1283  // The key up of the control left press is missed.
1284  state = static_cast<GdkModifierType>(0);
1285 
1286  // Send a normal event (KeyA down).
1287  g_autoptr(FlKeyEvent) event2 =
1288  fl_key_event_new(102, kPress, kKeyCodeKeyA, GDK_KEY_A, state, 0);
1290  &user_data);
1291 
1292  // The synthesized event should have physical CapsLock and logical
1293  // ControlLeft.
1294  EXPECT_EQ(g_call_records->len, 2u);
1295  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1296  EXPECT_EQ(record->event->timestamp, 102000);
1297  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1298  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1299  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1300  EXPECT_STREQ(record->event->character, nullptr);
1301  EXPECT_EQ(record->event->synthesized, true);
1302 
1303  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1304  EXPECT_EQ(record->event->timestamp, 102000);
1305  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1306  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1307  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1308  EXPECT_STREQ(record->event->character, "A");
1309  EXPECT_EQ(record->event->synthesized, false);
1310 
1312  g_ptr_array_clear(g_call_records);
1313 
1315  g_object_unref(responder);
1316 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_ptr_array_clear(), invoke_record_callback_and_verify(), record_calls(), state, TRUE, user_data, and verify_response_handled().

◆ TEST() [12/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncPressingStateOnSelfEvents   
)

Definition at line 1001 of file fl_key_embedder_responder_test.cc.

1001  {
1002  EXPECT_EQ(g_call_records, nullptr);
1003  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1004  FlKeyResponder* responder = FL_KEY_RESPONDER(
1005  fl_key_embedder_responder_new(record_calls, g_call_records));
1006  int user_data = 123; // Arbitrary user data
1007 
1008  FlKeyEmbedderCallRecord* record;
1009 
1010  // Test 1: synthesize key down.
1011 
1012  // A key down of control left is missed.
1013  GdkModifierType state = GDK_CONTROL_MASK;
1014 
1015  // Send a ControlLeft up
1016  g_autoptr(FlKeyEvent) event1 = fl_key_event_new(
1017  101, kRelease, kKeyCodeControlLeft, GDK_KEY_Control_L, state, 0);
1019  &user_data);
1020 
1021  EXPECT_EQ(g_call_records->len, 2u);
1022  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1023  EXPECT_EQ(record->event->timestamp, 101000);
1024  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1025  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1026  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1027  EXPECT_STREQ(record->event->character, nullptr);
1028  EXPECT_EQ(record->event->synthesized, true);
1029 
1030  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1031  EXPECT_EQ(record->event->timestamp, 101000);
1032  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1033  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1034  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1035  EXPECT_STREQ(record->event->character, nullptr);
1036  EXPECT_EQ(record->event->synthesized, false);
1037 
1039  g_ptr_array_clear(g_call_records);
1040 
1041  // Test 2: synthesize key up.
1042 
1043  // Send a ControlLeft down.
1044  state = static_cast<GdkModifierType>(0);
1045  g_autoptr(FlKeyEvent) event2 = fl_key_event_new(
1046  102, kPress, kKeyCodeControlLeft, GDK_KEY_Control_L, state, 0);
1048  &user_data);
1049  EXPECT_EQ(g_call_records->len, 1u);
1050  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1052  g_ptr_array_clear(g_call_records);
1053 
1054  // A key up of control left is missed.
1055  state = static_cast<GdkModifierType>(0);
1056 
1057  // Send another ControlLeft down
1058  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(
1059  103, kPress, kKeyCodeControlLeft, GDK_KEY_Control_L, state, 0);
1061  &user_data);
1062 
1063  EXPECT_EQ(g_call_records->len, 2u);
1064  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1065  EXPECT_EQ(record->event->timestamp, 103000);
1066  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1067  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1068  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1069  EXPECT_STREQ(record->event->character, nullptr);
1070  EXPECT_EQ(record->event->synthesized, true);
1071 
1072  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1073  EXPECT_EQ(record->event->timestamp, 103000);
1074  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1075  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1076  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1077  EXPECT_STREQ(record->event->character, nullptr);
1078  EXPECT_EQ(record->event->synthesized, false);
1079 
1081  g_ptr_array_clear(g_call_records);
1082 
1083  // Send a ControlLeft up to clear up state.
1084  state = GDK_CONTROL_MASK;
1085  g_autoptr(FlKeyEvent) event4 = fl_key_event_new(
1086  104, kRelease, kKeyCodeControlLeft, GDK_KEY_Control_L, state, 0);
1088  &user_data);
1089  EXPECT_EQ(g_call_records->len, 1u);
1090  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1092  g_ptr_array_clear(g_call_records);
1093 
1094  // Test 3: synthesize by right modifier.
1095 
1096  // A key down of control right is missed.
1097  state = GDK_CONTROL_MASK;
1098 
1099  // Send a ControlRight up.
1100  g_autoptr(FlKeyEvent) event5 = fl_key_event_new(
1101  105, kRelease, kKeyCodeControlRight, GDK_KEY_Control_R, state, 0);
1103  &user_data);
1104 
1105  // A ControlLeft down is synthesized, with an empty event.
1106  // Reason: The ControlLeft down is synthesized to synchronize the state
1107  // showing Control as pressed. The ControlRight event is ignored because
1108  // the event is considered a duplicate up event.
1109  EXPECT_EQ(g_call_records->len, 1u);
1110  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1111  EXPECT_EQ(record->event->timestamp, 105000);
1112  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1113  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1114  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1115  EXPECT_STREQ(record->event->character, nullptr);
1116  EXPECT_EQ(record->event->synthesized, true);
1117 
1118  g_ptr_array_clear(g_call_records);
1119 
1121  g_object_unref(responder);
1122 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_ptr_array_clear(), invoke_record_callback_and_verify(), record_calls(), state, TRUE, user_data, and verify_response_handled().

◆ TEST() [13/17]

TEST ( FlKeyEmbedderResponderTest  ,
TapLetterKeysBetweenCapsLockEvents   
)

Definition at line 606 of file fl_key_embedder_responder_test.cc.

606  {
607  EXPECT_EQ(g_call_records, nullptr);
608  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
609  FlKeyResponder* responder = FL_KEY_RESPONDER(
611  int user_data = 123; // Arbitrary user data
612 
613  FlKeyEmbedderCallRecord* record;
614 
615  // Press CapsLock (stage 0 -> 1)
616  g_autoptr(FlKeyEvent) event1 =
617  fl_key_event_new(101, kPress, kKeyCodeCapsLock, GDK_KEY_Caps_Lock,
618  static_cast<GdkModifierType>(0), 0);
620  &user_data);
621 
622  EXPECT_EQ(g_call_records->len, 1u);
623  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
624  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
625  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
626  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
627  EXPECT_STREQ(record->event->character, nullptr);
628  EXPECT_EQ(record->event->synthesized, false);
629 
631  g_ptr_array_clear(g_call_records);
632 
633  // Press key A (stage 1)
634  g_autoptr(FlKeyEvent) event2 =
635  fl_key_event_new(102, kPress, kKeyCodeKeyA, GDK_KEY_A, GDK_LOCK_MASK, 0);
637  &user_data);
638 
639  EXPECT_EQ(g_call_records->len, 1u);
640  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
641  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
642  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
643  EXPECT_EQ(record->event->logical, kLogicalKeyA);
644  EXPECT_STREQ(record->event->character, "A");
645  EXPECT_EQ(record->event->synthesized, false);
646 
648  g_ptr_array_clear(g_call_records);
649 
650  // Release CapsLock (stage 1 -> 2)
651  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(
652  103, kRelease, kKeyCodeCapsLock, GDK_KEY_Caps_Lock, GDK_LOCK_MASK, 0);
654  &user_data);
655 
656  EXPECT_EQ(g_call_records->len, 1u);
657  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
658  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
659  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
660  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
661  EXPECT_STREQ(record->event->character, nullptr);
662  EXPECT_EQ(record->event->synthesized, false);
663 
665  g_ptr_array_clear(g_call_records);
666 
667  // Release key A (stage 2)
668  g_autoptr(FlKeyEvent) event4 = fl_key_event_new(104, kRelease, kKeyCodeKeyA,
669  GDK_KEY_A, GDK_LOCK_MASK, 0);
671  &user_data);
672 
673  EXPECT_EQ(g_call_records->len, 1u);
674  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
675  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
676  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
677  EXPECT_EQ(record->event->logical, kLogicalKeyA);
678  EXPECT_STREQ(record->event->character, nullptr);
679  EXPECT_EQ(record->event->synthesized, false);
680 
682  g_ptr_array_clear(g_call_records);
683 
684  // Press CapsLock (stage 2 -> 3)
685  g_autoptr(FlKeyEvent) event5 = fl_key_event_new(
686  105, kPress, kKeyCodeCapsLock, GDK_KEY_Caps_Lock, GDK_LOCK_MASK, 0);
688  &user_data);
689 
690  EXPECT_EQ(g_call_records->len, 1u);
691  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
692  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
693  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
694  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
695  EXPECT_STREQ(record->event->character, nullptr);
696  EXPECT_EQ(record->event->synthesized, false);
697 
699  g_ptr_array_clear(g_call_records);
700 
701  // Press key A (stage 3)
702  g_autoptr(FlKeyEvent) event6 =
703  fl_key_event_new(106, kPress, kKeyCodeKeyA, GDK_KEY_A, GDK_LOCK_MASK, 0);
705  &user_data);
706 
707  EXPECT_EQ(g_call_records->len, 1u);
708  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
709  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
710  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
711  EXPECT_EQ(record->event->logical, kLogicalKeyA);
712  EXPECT_STREQ(record->event->character, "A");
713  EXPECT_EQ(record->event->synthesized, false);
714 
716  g_ptr_array_clear(g_call_records);
717 
718  // Release CapsLock (stage 3 -> 0)
719  g_autoptr(FlKeyEvent) event7 = fl_key_event_new(
720  107, kRelease, kKeyCodeCapsLock, GDK_KEY_Caps_Lock, GDK_LOCK_MASK, 0);
722  &user_data);
723 
724  EXPECT_EQ(g_call_records->len, 1u);
725  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
726  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
727  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
728  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
729  EXPECT_STREQ(record->event->character, nullptr);
730  EXPECT_EQ(record->event->synthesized, false);
731 
733  g_ptr_array_clear(g_call_records);
734 
735  // Release key A (stage 0)
736  g_autoptr(FlKeyEvent) event8 =
737  fl_key_event_new(108, kRelease, kKeyCodeKeyA, GDK_KEY_a,
738  static_cast<GdkModifierType>(0), 0);
740  &user_data);
741 
742  EXPECT_EQ(g_call_records->len, 1u);
743  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
744  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
745  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
746  EXPECT_EQ(record->event->logical, kLogicalKeyA);
747  EXPECT_STREQ(record->event->character, nullptr);
748  EXPECT_EQ(record->event->synthesized, false);
749 
751  g_ptr_array_clear(g_call_records);
752 
754  g_object_unref(responder);
755 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_ptr_array_clear(), invoke_record_callback_and_verify(), record_calls(), TRUE, user_data, and verify_response_handled().

◆ TEST() [14/17]

TEST ( FlKeyEmbedderResponderTest  ,
TapLetterKeysBetweenCapsLockEventsReversed   
)

Definition at line 761 of file fl_key_embedder_responder_test.cc.

761  {
762  EXPECT_EQ(g_call_records, nullptr);
763  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
764  FlKeyResponder* responder = FL_KEY_RESPONDER(
766  int user_data = 123; // Arbitrary user data
767 
768  FlKeyEmbedderCallRecord* record;
769 
770  // Press key A (stage 0)
771  g_autoptr(FlKeyEvent) event1 = fl_key_event_new(
772  101, kPress, kKeyCodeKeyA, GDK_KEY_a, static_cast<GdkModifierType>(0), 0);
774  &user_data);
775 
776  EXPECT_EQ(g_call_records->len, 1u);
777  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
778  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
779  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
780  EXPECT_EQ(record->event->logical, kLogicalKeyA);
781  EXPECT_STREQ(record->event->character, "a");
782  EXPECT_EQ(record->event->synthesized, false);
783 
785  g_ptr_array_clear(g_call_records);
786 
787  // Press CapsLock (stage 0 -> 1)
788  g_autoptr(FlKeyEvent) event2 = fl_key_event_new(
789  102, kPress, kKeyCodeCapsLock, GDK_KEY_Caps_Lock, GDK_LOCK_MASK, 0);
791  &user_data);
792 
793  EXPECT_EQ(g_call_records->len, 1u);
794  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
795  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
796  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
797  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
798  EXPECT_STREQ(record->event->character, nullptr);
799  EXPECT_EQ(record->event->synthesized, false);
800 
802  g_ptr_array_clear(g_call_records);
803 
804  // Release CapsLock (stage 1 -> 2)
805  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(
806  103, kRelease, kKeyCodeCapsLock, GDK_KEY_Caps_Lock, GDK_LOCK_MASK, 0);
808  &user_data);
809 
810  EXPECT_EQ(g_call_records->len, 1u);
811  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
812  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
813  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
814  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
815  EXPECT_STREQ(record->event->character, nullptr);
816  EXPECT_EQ(record->event->synthesized, false);
817 
819  g_ptr_array_clear(g_call_records);
820 
821  // Release key A (stage 2)
822  g_autoptr(FlKeyEvent) event4 = fl_key_event_new(104, kRelease, kKeyCodeKeyA,
823  GDK_KEY_A, GDK_LOCK_MASK, 0);
825  &user_data);
826 
827  EXPECT_EQ(g_call_records->len, 1u);
828  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
829  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
830  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
831  EXPECT_EQ(record->event->logical, kLogicalKeyA);
832  EXPECT_STREQ(record->event->character, nullptr);
833  EXPECT_EQ(record->event->synthesized, false);
834 
836  g_ptr_array_clear(g_call_records);
837 
838  // Press key A (stage 2)
839  g_autoptr(FlKeyEvent) event5 =
840  fl_key_event_new(105, kPress, kKeyCodeKeyA, GDK_KEY_A, GDK_LOCK_MASK, 0);
842  &user_data);
843 
844  EXPECT_EQ(g_call_records->len, 1u);
845  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
846  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
847  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
848  EXPECT_EQ(record->event->logical, kLogicalKeyA);
849  EXPECT_STREQ(record->event->character, "A");
850  EXPECT_EQ(record->event->synthesized, false);
851 
853  g_ptr_array_clear(g_call_records);
854 
855  // Press CapsLock (stage 2 -> 3)
856  g_autoptr(FlKeyEvent) event6 =
857  fl_key_event_new(106, kPress, kKeyCodeCapsLock, GDK_KEY_Caps_Lock,
858  static_cast<GdkModifierType>(0), 0);
860  &user_data);
861 
862  EXPECT_EQ(g_call_records->len, 1u);
863  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
864  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
865  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
866  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
867  EXPECT_STREQ(record->event->character, nullptr);
868  EXPECT_EQ(record->event->synthesized, false);
869 
871  g_ptr_array_clear(g_call_records);
872 
873  // Release CapsLock (stage 3 -> 0)
874  g_autoptr(FlKeyEvent) event7 = fl_key_event_new(
875  107, kRelease, kKeyCodeCapsLock, GDK_KEY_Caps_Lock, GDK_LOCK_MASK, 0);
877  &user_data);
878 
879  EXPECT_EQ(g_call_records->len, 1u);
880  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
881  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
882  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
883  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
884  EXPECT_STREQ(record->event->character, nullptr);
885  EXPECT_EQ(record->event->synthesized, false);
886 
888  g_ptr_array_clear(g_call_records);
889 
890  // Release key A (stage 0)
891  g_autoptr(FlKeyEvent) event8 =
892  fl_key_event_new(108, kRelease, kKeyCodeKeyA, GDK_KEY_a,
893  static_cast<GdkModifierType>(0), 0);
895  &user_data);
896 
897  EXPECT_EQ(g_call_records->len, 1u);
898  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
899  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
900  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
901  EXPECT_EQ(record->event->logical, kLogicalKeyA);
902  EXPECT_STREQ(record->event->character, nullptr);
903  EXPECT_EQ(record->event->synthesized, false);
904 
906  g_ptr_array_clear(g_call_records);
907 
909  g_object_unref(responder);
910 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_ptr_array_clear(), invoke_record_callback_and_verify(), record_calls(), TRUE, user_data, and verify_response_handled().

◆ TEST() [15/17]

TEST ( FlKeyEmbedderResponderTest  ,
TapNumPadKeysBetweenNumLockEvents   
)

Definition at line 360 of file fl_key_embedder_responder_test.cc.

360  {
361  EXPECT_EQ(g_call_records, nullptr);
362  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
363  FlKeyResponder* responder = FL_KEY_RESPONDER(
365  int user_data = 123; // Arbitrary user data
366 
367  FlKeyEmbedderCallRecord* record;
368 
369  // Press Numpad 1 (stage 0)
370  g_autoptr(FlKeyEvent) event1 =
371  fl_key_event_new(101, kPress, kKeyCodeNumpad1, GDK_KEY_KP_End,
372  static_cast<GdkModifierType>(0), 0);
374  &user_data);
375 
376  EXPECT_EQ(g_call_records->len, 1u);
377  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
378  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
379  EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
380  EXPECT_EQ(record->event->logical, kLogicalNumpad1);
381  EXPECT_STREQ(record->event->character, nullptr); // TODO(chrome-bot):
382  EXPECT_EQ(record->event->synthesized, false);
383 
385  g_ptr_array_clear(g_call_records);
386 
387  // Press NumLock (stage 0 -> 1)
388  g_autoptr(FlKeyEvent) event2 =
389  fl_key_event_new(102, kPress, kKeyCodeNumLock, GDK_KEY_Num_Lock,
390  static_cast<GdkModifierType>(0), 0);
392  &user_data);
393 
394  EXPECT_EQ(g_call_records->len, 1u);
395  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
396  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
397  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
398  EXPECT_EQ(record->event->logical, kLogicalNumLock);
399  EXPECT_STREQ(record->event->character, nullptr);
400  EXPECT_EQ(record->event->synthesized, false);
401 
403  g_ptr_array_clear(g_call_records);
404 
405  // Release numpad 1 (stage 1)
406  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(
407  104, kRelease, kKeyCodeNumpad1, GDK_KEY_KP_1, GDK_MOD2_MASK, 0);
409  &user_data);
410 
411  EXPECT_EQ(g_call_records->len, 1u);
412  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
413  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
414  EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
415  EXPECT_EQ(record->event->logical, kLogicalNumpad1);
416  EXPECT_STREQ(record->event->character, nullptr);
417  EXPECT_EQ(record->event->synthesized, false);
418 
420  g_ptr_array_clear(g_call_records);
421 
422  // Release NumLock (stage 1 -> 2)
423  g_autoptr(FlKeyEvent) event4 = fl_key_event_new(
424  103, kRelease, kKeyCodeNumLock, GDK_KEY_Num_Lock, GDK_MOD2_MASK, 0);
426  &user_data);
427 
428  EXPECT_EQ(g_call_records->len, 1u);
429  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
430  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
431  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
432  EXPECT_EQ(record->event->logical, kLogicalNumLock);
433  EXPECT_STREQ(record->event->character, nullptr);
434  EXPECT_EQ(record->event->synthesized, false);
435 
437  g_ptr_array_clear(g_call_records);
438 
439  // Press Numpad 1 (stage 2)
440  g_autoptr(FlKeyEvent) event5 = fl_key_event_new(
441  101, kPress, kKeyCodeNumpad1, GDK_KEY_KP_End, GDK_MOD2_MASK, 0);
443  &user_data);
444 
445  EXPECT_EQ(g_call_records->len, 1u);
446  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
447  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
448  EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
449  EXPECT_EQ(record->event->logical, kLogicalNumpad1);
450  EXPECT_STREQ(record->event->character, nullptr); // TODO(chrome-bot):
451  EXPECT_EQ(record->event->synthesized, false);
452 
454  g_ptr_array_clear(g_call_records);
455 
456  // Press NumLock (stage 2 -> 3)
457  g_autoptr(FlKeyEvent) event6 = fl_key_event_new(
458  102, kPress, kKeyCodeNumLock, GDK_KEY_Num_Lock, GDK_MOD2_MASK, 0);
460  &user_data);
461 
462  EXPECT_EQ(g_call_records->len, 1u);
463  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
464  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
465  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
466  EXPECT_EQ(record->event->logical, kLogicalNumLock);
467  EXPECT_STREQ(record->event->character, nullptr);
468  EXPECT_EQ(record->event->synthesized, false);
469 
471  g_ptr_array_clear(g_call_records);
472 
473  // Release numpad 1 (stage 3)
474  g_autoptr(FlKeyEvent) event7 = fl_key_event_new(
475  104, kRelease, kKeyCodeNumpad1, GDK_KEY_KP_1, GDK_MOD2_MASK, 0);
477  &user_data);
478 
479  EXPECT_EQ(g_call_records->len, 1u);
480  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
481  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
482  EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
483  EXPECT_EQ(record->event->logical, kLogicalNumpad1);
484  EXPECT_STREQ(record->event->character, nullptr);
485  EXPECT_EQ(record->event->synthesized, false);
486 
488  g_ptr_array_clear(g_call_records);
489 
490  // Release NumLock (stage 3 -> 0)
491  g_autoptr(FlKeyEvent) event8 = fl_key_event_new(
492  103, kRelease, kKeyCodeNumLock, GDK_KEY_Num_Lock, GDK_MOD2_MASK, 0);
494  &user_data);
495 
496  EXPECT_EQ(g_call_records->len, 1u);
497  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
498  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
499  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
500  EXPECT_EQ(record->event->logical, kLogicalNumLock);
501  EXPECT_STREQ(record->event->character, nullptr);
502  EXPECT_EQ(record->event->synthesized, false);
503 
505  g_ptr_array_clear(g_call_records);
506 
508  g_object_unref(responder);
509 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_ptr_array_clear(), invoke_record_callback_and_verify(), record_calls(), TRUE, user_data, and verify_response_handled().

◆ TEST() [16/17]

TEST ( FlKeyEmbedderResponderTest  ,
TurnDuplicateDownEventsToRepeats   
)

Definition at line 912 of file fl_key_embedder_responder_test.cc.

912  {
913  EXPECT_EQ(g_call_records, nullptr);
914  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
915  FlKeyResponder* responder = FL_KEY_RESPONDER(
917  int user_data = 123; // Arbitrary user data
918 
919  FlKeyEmbedderCallRecord* record;
920 
921  // Press KeyA
922  g_autoptr(FlKeyEvent) event1 = fl_key_event_new(
923  101, kPress, kKeyCodeKeyA, GDK_KEY_a, static_cast<GdkModifierType>(0), 0);
925  &user_data);
926 
927  EXPECT_EQ(g_call_records->len, 1u);
928 
929  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
931  g_ptr_array_clear(g_call_records);
932 
933  // Another KeyA down events, which usually means a repeated event.
934  g_expected_handled = false;
935  g_autoptr(FlKeyEvent) event2 = fl_key_event_new(
936  102, kPress, kKeyCodeKeyA, GDK_KEY_a, static_cast<GdkModifierType>(0), 0);
938  &user_data);
939 
940  EXPECT_EQ(g_call_records->len, 1u);
941 
942  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
943  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeRepeat);
944  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
945  EXPECT_EQ(record->event->logical, kLogicalKeyA);
946  EXPECT_STREQ(record->event->character, "a");
947  EXPECT_EQ(record->event->synthesized, false);
948  EXPECT_NE(record->callback, nullptr);
949 
951  g_ptr_array_clear(g_call_records);
952 
953  // Release KeyA
954  g_autoptr(FlKeyEvent) event3 =
955  fl_key_event_new(103, kRelease, kKeyCodeKeyA, GDK_KEY_q,
956  static_cast<GdkModifierType>(0), 0);
958  &user_data);
959 
960  EXPECT_EQ(g_call_records->len, 1u);
961  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
963  g_ptr_array_clear(g_call_records);
964 
966  g_object_unref(responder);
967 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_expected_handled, g_ptr_array_clear(), invoke_record_callback_and_verify(), record_calls(), TRUE, user_data, and verify_response_handled().

◆ TEST() [17/17]

TEST ( FlKeyEmbedderResponderTest  ,
UsesSpecifiedLogicalKey   
)

Definition at line 234 of file fl_key_embedder_responder_test.cc.

234  {
235  EXPECT_EQ(g_call_records, nullptr);
236  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
237  FlKeyResponder* responder = FL_KEY_RESPONDER(
239  int user_data = 123; // Arbitrary user data
240 
241  FlKeyEmbedderCallRecord* record;
242 
243  // On an AZERTY keyboard, press physical key 1, and release.
244  // Key down
245  g_autoptr(FlKeyEvent) event =
246  fl_key_event_new(12345, kPress, kKeyCodeDigit1, GDK_KEY_ampersand,
247  static_cast<GdkModifierType>(0), 0);
249  &user_data, kLogicalDigit1);
250 
251  EXPECT_EQ(g_call_records->len, 1u);
252  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
253  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
254  EXPECT_EQ(record->event->timestamp, 12345000);
255  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
256  EXPECT_EQ(record->event->physical, kPhysicalDigit1);
257  EXPECT_EQ(record->event->logical, kLogicalDigit1);
258  EXPECT_STREQ(record->event->character, "&");
259  EXPECT_EQ(record->event->synthesized, false);
260 
262  g_ptr_array_clear(g_call_records);
263 
265  g_object_unref(responder);
266 }

References clear_g_call_records(), event, fl_key_embedder_responder_new(), fl_key_event_new(), fl_key_responder_handle_event(), g_ptr_array_clear(), invoke_record_callback_and_verify(), record_calls(), TRUE, user_data, and verify_response_handled().

◆ verify_response_handled()

static void verify_response_handled ( bool  handled,
gpointer  user_data 
)
static

Definition at line 103 of file fl_key_embedder_responder_test.cc.

103  {
104  EXPECT_EQ(handled, g_expected_handled);
105 }

References g_expected_handled.

Referenced by TEST().

Variable Documentation

◆ g_expected_handled

gboolean g_expected_handled
static

◆ g_expected_user_data

gpointer g_expected_user_data
static
event
FlKeyEvent * event
Definition: fl_key_channel_responder.cc:118
clear_g_call_records
static void clear_g_call_records()
Definition: fl_key_embedder_responder_test.cc:132
user_data
FlKeyEvent uint64_t FlKeyResponderAsyncCallback gpointer user_data
Definition: fl_key_channel_responder.cc:121
state
AtkStateType state
Definition: fl_accessible_node.cc:10
record_calls
static void record_calls(const FlutterKeyEvent *event, FlutterKeyEventCallback callback, void *callback_user_data, void *send_key_event_user_data)
Definition: fl_key_embedder_responder_test.cc:120
fl_key_embedder_responder_new
FlKeyEmbedderResponder * fl_key_embedder_responder_new(EmbedderSendKeyEvent send_key_event, void *send_key_event_user_data)
Definition: fl_key_embedder_responder.cc:263
fl_key_responder_handle_event
void fl_key_responder_handle_event(FlKeyResponder *self, FlKeyEvent *event, FlKeyResponderAsyncCallback callback, gpointer user_data, uint64_t specified_logical_key)
Definition: fl_key_responder.cc:11
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_key_embedder_call_record_dispose
static void fl_key_embedder_call_record_dispose(GObject *object)
Definition: fl_key_embedder_responder_test.cc:59
fl_key_embedder_call_record_new
static FlKeyEmbedderCallRecord * fl_key_embedder_call_record_new(const FlutterKeyEvent *event, FlutterKeyEventCallback callback, gpointer user_data)
Definition: fl_key_embedder_responder_test.cc:76
send_key_event
static void send_key_event(FlTextInputHandler *handler, gint keyval, gint state=0)
Definition: fl_text_input_handler_test.cc:181
g_expected_handled
static gboolean g_expected_handled
Definition: fl_key_embedder_responder_test.cc:100
invoke_record_callback_and_verify
static void invoke_record_callback_and_verify(FlKeyEmbedderCallRecord *record, bool expected_handled, void *expected_user_data)
Definition: fl_key_embedder_responder_test.cc:107
g_ptr_array_clear
static void g_ptr_array_clear(GPtrArray *array)
Definition: fl_key_embedder_responder_test.cc:34
g_expected_user_data
static gpointer g_expected_user_data
Definition: fl_key_embedder_responder_test.cc:101
verify_response_handled
static void verify_response_handled(bool handled, gpointer user_data)
Definition: fl_key_embedder_responder_test.cc:103
callback
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
Definition: fl_key_channel_responder.cc:120
fl_key_event_new
FlKeyEvent * fl_key_event_new(guint32 time, gboolean is_press, guint16 keycode, guint keyval, GdkModifierType state, guint8 group)
Definition: fl_key_event.cc:34
expected_handled
static gboolean expected_handled
Definition: fl_key_channel_responder_test.cc:14