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 FlKeyEventfl_key_event_new_by_mock (guint32 time_in_milliseconds, bool is_press, guint keyval, guint16 keycode, GdkModifierType state, gboolean is_modifier)
 
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 162 of file fl_key_embedder_responder_test.cc.

162  {
163  g_ptr_array_free(g_call_records, TRUE);
164  g_call_records = nullptr;
165 }

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 74 of file fl_key_embedder_responder_test.cc.

75  {
76  G_OBJECT_CLASS(klass)->dispose = fl_key_embedder_call_record_dispose;
77 }

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 62 of file fl_key_embedder_responder_test.cc.

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

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 79 of file fl_key_embedder_responder_test.cc.

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

References callback, event, and user_data.

Referenced by record_calls().

◆ fl_key_event_new_by_mock()

static FlKeyEvent* fl_key_event_new_by_mock ( guint32  time_in_milliseconds,
bool  is_press,
guint  keyval,
guint16  keycode,
GdkModifierType  state,
gboolean  is_modifier 
)
static

Definition at line 115 of file fl_key_embedder_responder_test.cc.

120  {
121  _g_key_event.is_press = is_press;
122  _g_key_event.time = time_in_milliseconds;
123  _g_key_event.state = state;
124  _g_key_event.keyval = keyval;
125  _g_key_event.keycode = keycode;
126  _g_key_event.origin = nullptr;
127  return &_g_key_event;
128 }

References _FlKeyEvent::is_press, and state.

Referenced by TEST().

◆ 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 55 of file fl_key_embedder_responder_test.cc.

59  {}

◆ g_ptr_array_clear()

static void g_ptr_array_clear ( GPtrArray *  array)
static

Definition at line 37 of file fl_key_embedder_responder_test.cc.

37  {
38  g_ptr_array_remove_range(array, 0, array->len);
39 }

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 137 of file fl_key_embedder_responder_test.cc.

139  {
140  g_return_if_fail(record->callback != nullptr);
142  g_expected_user_data = expected_user_data;
143  record->callback(expected_handled, record->user_data);
144 }

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 150 of file fl_key_embedder_responder_test.cc.

153  {
154  GPtrArray* records_array =
155  reinterpret_cast<GPtrArray*>(send_key_event_user_data);
156  if (records_array != nullptr) {
157  g_ptr_array_add(records_array, fl_key_embedder_call_record_new(
158  event, callback, callback_user_data));
159  }
160 }

References callback, event, and fl_key_embedder_call_record_new().

Referenced by TEST().

◆ TEST() [1/17]

TEST ( FlKeyEmbedderResponderTest  ,
HandlesShiftAltLeftIsMetaLeft   
)

Definition at line 1757 of file fl_key_embedder_responder_test.cc.

1757  {
1758  EXPECT_EQ(g_call_records, nullptr);
1759  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1760  FlKeyResponder* responder = FL_KEY_RESPONDER(
1761  fl_key_embedder_responder_new(record_calls, g_call_records));
1762 
1763  g_expected_handled = true;
1764  guint32 now_time = 1;
1765  // A convenient shorthand to simulate events.
1766  auto send_key_event = [responder, &now_time](bool is_press, guint keyval,
1767  guint16 keycode,
1768  GdkModifierType state) {
1769  now_time += 1;
1770  int user_data = 123; // Arbitrary user data
1772  responder,
1773  fl_key_event_new_by_mock(now_time, is_press, keyval, keycode, state,
1774  kIsModifier),
1776  };
1777 
1778  FlKeyEmbedderCallRecord* record;
1779 
1780  // ShiftLeft + AltLeft
1781  send_key_event(kPress, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1782  GDK_MODIFIER_RESERVED_25_MASK);
1783  EXPECT_EQ(g_call_records->len, 1u);
1784  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1785  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1786  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1787  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
1788  EXPECT_EQ(record->event->synthesized, false);
1789 
1790  send_key_event(kPress, GDK_KEY_Meta_L, kKeyCodeAltLeft,
1791  static_cast<GdkModifierType>(GDK_SHIFT_MASK |
1792  GDK_MODIFIER_RESERVED_25_MASK));
1793  EXPECT_EQ(g_call_records->len, 2u);
1794  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1795  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1796  EXPECT_EQ(record->event->physical, kPhysicalMetaLeft);
1797  EXPECT_EQ(record->event->logical, kLogicalMetaLeft);
1798  EXPECT_EQ(record->event->synthesized, false);
1799 
1800  send_key_event(kRelease, GDK_KEY_Meta_L, kKeyCodeAltLeft,
1801  static_cast<GdkModifierType>(GDK_MODIFIER_RESERVED_13_MASK |
1802  GDK_MODIFIER_RESERVED_25_MASK));
1803  send_key_event(kRelease, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1804  GDK_MODIFIER_RESERVED_25_MASK);
1805  g_ptr_array_clear(g_call_records);
1806 
1807  // ShiftRight + AltLeft
1808  send_key_event(kPress, GDK_KEY_Shift_R, kKeyCodeShiftRight,
1809  GDK_MODIFIER_RESERVED_25_MASK);
1810  EXPECT_EQ(g_call_records->len, 1u);
1811  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1812  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1813  EXPECT_EQ(record->event->physical, kPhysicalShiftRight);
1814  EXPECT_EQ(record->event->logical, kLogicalShiftRight);
1815  EXPECT_EQ(record->event->synthesized, false);
1816 
1817  send_key_event(kPress, GDK_KEY_Meta_L, kKeyCodeAltLeft,
1818  static_cast<GdkModifierType>(GDK_SHIFT_MASK |
1819  GDK_MODIFIER_RESERVED_25_MASK));
1820  EXPECT_EQ(g_call_records->len, 2u);
1821  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1822  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1823  EXPECT_EQ(record->event->physical, kPhysicalMetaLeft);
1824  EXPECT_EQ(record->event->logical, kLogicalMetaLeft);
1825  EXPECT_EQ(record->event->synthesized, false);
1826 
1828  g_object_unref(responder);
1829 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 1648 of file fl_key_embedder_responder_test.cc.

1648  {
1649  EXPECT_EQ(g_call_records, nullptr);
1650  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1651  FlKeyResponder* responder = FL_KEY_RESPONDER(
1652  fl_key_embedder_responder_new(record_calls, g_call_records));
1653 
1654  g_expected_handled = true;
1655  guint32 now_time = 1;
1656  // A convenient shorthand to simulate events.
1657  auto send_key_event = [responder, &now_time](bool is_press, guint keyval,
1658  guint16 keycode,
1659  GdkModifierType state) {
1660  now_time += 1;
1661  int user_data = 123; // Arbitrary user data
1663  responder,
1664  fl_key_event_new_by_mock(now_time, is_press, keyval, keycode, state,
1665  kIsModifier),
1667  };
1668 
1669  FlKeyEmbedderCallRecord* record;
1670 
1671  send_key_event(kPress, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1672  GDK_MODIFIER_RESERVED_25_MASK);
1673  EXPECT_EQ(g_call_records->len, 1u);
1674  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1675  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1676  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1677  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
1678  EXPECT_EQ(record->event->synthesized, false);
1679 
1680  send_key_event(kPress, GDK_KEY_Meta_R, kKeyCodeAltRight,
1681  static_cast<GdkModifierType>(GDK_SHIFT_MASK |
1682  GDK_MODIFIER_RESERVED_25_MASK));
1683  EXPECT_EQ(g_call_records->len, 2u);
1684  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1685  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1686  EXPECT_EQ(record->event->physical, kPhysicalAltRight);
1687  EXPECT_EQ(record->event->logical, kLogicalMetaRight);
1688  EXPECT_EQ(record->event->synthesized, false);
1689 
1690  send_key_event(kRelease, GDK_KEY_ISO_Next_Group, kKeyCodeShiftLeft,
1691  static_cast<GdkModifierType>(GDK_SHIFT_MASK | GDK_MOD1_MASK |
1692  GDK_MODIFIER_RESERVED_25_MASK));
1693  EXPECT_EQ(g_call_records->len, 5u);
1694  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 2));
1695  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1696  EXPECT_EQ(record->event->physical, kPhysicalAltLeft);
1697  EXPECT_EQ(record->event->logical, kLogicalAltLeft);
1698  EXPECT_EQ(record->event->synthesized, true);
1699 
1700  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 3));
1701  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1702  EXPECT_EQ(record->event->physical, kPhysicalAltRight);
1703  EXPECT_EQ(record->event->logical, kLogicalMetaRight);
1704  EXPECT_EQ(record->event->synthesized, true);
1705 
1706  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 4));
1707  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1708  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1709  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
1710  EXPECT_EQ(record->event->synthesized, false);
1711 
1712  send_key_event(kPress, GDK_KEY_ISO_Next_Group, kKeyCodeShiftLeft,
1713  static_cast<GdkModifierType>(GDK_MOD1_MASK |
1714  GDK_MODIFIER_RESERVED_25_MASK));
1715  EXPECT_EQ(g_call_records->len, 6u);
1716  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 5));
1717  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1718  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1719  EXPECT_EQ(record->event->logical, kLogicalGroupNext);
1720  EXPECT_EQ(record->event->synthesized, false);
1721 
1722  send_key_event(kRelease, GDK_KEY_ISO_Level3_Shift, kKeyCodeAltRight,
1723  static_cast<GdkModifierType>(GDK_MOD1_MASK |
1724  GDK_MODIFIER_RESERVED_13_MASK |
1725  GDK_MODIFIER_RESERVED_25_MASK));
1726  EXPECT_EQ(g_call_records->len, 7u);
1727  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 6));
1728  EXPECT_EQ(record->event->physical, 0u);
1729  EXPECT_EQ(record->event->logical, 0u);
1730 
1731  send_key_event(kRelease, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1732  static_cast<GdkModifierType>(GDK_MODIFIER_RESERVED_13_MASK |
1733  GDK_MODIFIER_RESERVED_25_MASK));
1734  EXPECT_EQ(g_call_records->len, 9u);
1735  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 7));
1736  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1737  EXPECT_EQ(record->event->physical, kPhysicalAltLeft);
1738  EXPECT_EQ(record->event->logical, kLogicalAltLeft);
1739  EXPECT_EQ(record->event->synthesized, true);
1740 
1741  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 8));
1742  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1743  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1744  EXPECT_EQ(record->event->logical, kLogicalGroupNext);
1745  EXPECT_EQ(record->event->synthesized, false);
1746 
1748  g_object_unref(responder);
1749 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 1025 of file fl_key_embedder_responder_test.cc.

1025  {
1026  FlKeyEmbedderCallRecord* record;
1027 
1028  EXPECT_EQ(g_call_records, nullptr);
1029  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1030  FlKeyResponder* responder = FL_KEY_RESPONDER(
1031  fl_key_embedder_responder_new(record_calls, g_call_records));
1032  int user_data = 123; // Arbitrary user data
1033 
1034  // Release KeyA before it was even pressed.
1035  g_expected_handled = true; // The empty event is always handled.
1037  responder,
1038  fl_key_event_new_by_mock(103, kRelease, GDK_KEY_q, kKeyCodeKeyA,
1039  static_cast<GdkModifierType>(0), kIsNotModifier),
1041 
1042  EXPECT_EQ(g_call_records->len, 1u);
1043 
1044  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1045  EXPECT_EQ(record->event->physical, 0ull);
1046  EXPECT_EQ(record->event->logical, 0ull);
1047  EXPECT_STREQ(record->event->character, nullptr);
1048  EXPECT_EQ(record->event->synthesized, false);
1049  EXPECT_EQ(record->callback, nullptr);
1050 
1052  g_object_unref(responder);
1053 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 299 of file fl_key_embedder_responder_test.cc.

299  {
300  EXPECT_EQ(g_call_records, nullptr);
301  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
302  FlKeyResponder* responder = FL_KEY_RESPONDER(
304  int user_data = 123; // Arbitrary user data
305 
306  FlKeyEmbedderCallRecord* record;
307 
308  // Press shift right
310  responder,
311  fl_key_event_new_by_mock(101, kPress, GDK_KEY_Shift_R, kKeyCodeShiftRight,
312  static_cast<GdkModifierType>(0), kIsModifier),
314 
315  EXPECT_EQ(g_call_records->len, 1u);
316  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
317  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
318  EXPECT_EQ(record->event->physical, kPhysicalShiftRight);
319  EXPECT_EQ(record->event->logical, kLogicalShiftRight);
320  EXPECT_STREQ(record->event->character, nullptr);
321  EXPECT_EQ(record->event->synthesized, false);
322 
324  g_ptr_array_clear(g_call_records);
325 
326  // Press key A
328  responder,
329  fl_key_event_new_by_mock(102, kPress, GDK_KEY_A, kKeyCodeKeyA,
330  GDK_SHIFT_MASK, kIsNotModifier),
332 
333  EXPECT_EQ(g_call_records->len, 1u);
334  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
335  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
336  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
337  EXPECT_EQ(record->event->logical, kLogicalKeyA);
338  EXPECT_STREQ(record->event->character, "A");
339  EXPECT_EQ(record->event->synthesized, false);
340 
342  g_ptr_array_clear(g_call_records);
343 
344  // Release shift right
346  responder,
347  fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Shift_R,
348  kKeyCodeShiftRight, GDK_SHIFT_MASK, kIsModifier),
350 
351  EXPECT_EQ(g_call_records->len, 1u);
352  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
353  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
354  EXPECT_EQ(record->event->physical, kPhysicalShiftRight);
355  EXPECT_EQ(record->event->logical, kLogicalShiftRight);
356  EXPECT_STREQ(record->event->character, nullptr);
357  EXPECT_EQ(record->event->synthesized, false);
358 
360  g_ptr_array_clear(g_call_records);
361 
362  // Release key A
364  responder,
365  fl_key_event_new_by_mock(104, kRelease, GDK_KEY_A, kKeyCodeKeyA,
366  static_cast<GdkModifierType>(0), kIsNotModifier),
368 
369  EXPECT_EQ(g_call_records->len, 1u);
370  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
371  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
372  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
373  EXPECT_EQ(record->event->logical, kLogicalKeyA);
374  EXPECT_STREQ(record->event->character, nullptr);
375  EXPECT_EQ(record->event->synthesized, false);
376 
378  g_ptr_array_clear(g_call_records);
379 
381  g_object_unref(responder);
382 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 553 of file fl_key_embedder_responder_test.cc.

553  {
554  EXPECT_EQ(g_call_records, nullptr);
555  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
556  FlKeyResponder* responder = FL_KEY_RESPONDER(
558  int user_data = 123; // Arbitrary user data
559 
560  FlKeyEmbedderCallRecord* record;
561 
562  GdkModifierType state = static_cast<GdkModifierType>(0);
563 
564  // Press shift left
566  responder,
567  fl_key_event_new_by_mock(101, kPress, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
568  state, kIsModifier),
570 
571  EXPECT_EQ(g_call_records->len, 1u);
572  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
573  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
574  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
575  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
576  EXPECT_STREQ(record->event->character, nullptr);
577  EXPECT_EQ(record->event->synthesized, false);
578 
580  g_ptr_array_clear(g_call_records);
581 
582  state = GDK_SHIFT_MASK;
583 
584  // Press digit 1, which is '!' on a US keyboard
586  responder,
587  fl_key_event_new_by_mock(102, kPress, GDK_KEY_exclam, kKeyCodeDigit1,
588  state, kIsNotModifier),
590 
591  EXPECT_EQ(g_call_records->len, 1u);
592  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
593  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
594  EXPECT_EQ(record->event->physical, kPhysicalDigit1);
595  EXPECT_EQ(record->event->logical, kLogicalExclamation);
596  EXPECT_STREQ(record->event->character, "!");
597  EXPECT_EQ(record->event->synthesized, false);
598 
600  g_ptr_array_clear(g_call_records);
601 
602  // Release shift
604  responder,
605  fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Shift_L,
606  kKeyCodeShiftLeft, state, kIsModifier),
608 
609  EXPECT_EQ(g_call_records->len, 1u);
610  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
611  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
612  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
613  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
614  EXPECT_STREQ(record->event->character, nullptr);
615  EXPECT_EQ(record->event->synthesized, false);
616 
618  g_ptr_array_clear(g_call_records);
619 
620  state = static_cast<GdkModifierType>(0);
621 
622  // Release digit 1, which is "1" because shift has been released.
624  responder,
625  fl_key_event_new_by_mock(104, kRelease, GDK_KEY_1, kKeyCodeDigit1, state,
626  kIsNotModifier),
628 
629  EXPECT_EQ(g_call_records->len, 1u);
630  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
631  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
632  EXPECT_EQ(record->event->physical, kPhysicalDigit1);
633  EXPECT_EQ(record->event->logical, kLogicalExclamation); // Important
634  EXPECT_STREQ(record->event->character, nullptr);
635  EXPECT_EQ(record->event->synthesized, false);
636 
638  g_ptr_array_clear(g_call_records);
639 
641  g_object_unref(responder);
642 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 168 of file fl_key_embedder_responder_test.cc.

168  {
169  EXPECT_EQ(g_call_records, nullptr);
170  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
171  FlKeyResponder* responder = FL_KEY_RESPONDER(
173  int user_data = 123; // Arbitrary user data
174 
175  FlKeyEmbedderCallRecord* record;
176 
177  // On a QWERTY keyboard, press key Q (physically key A), and release.
178  // Key down
180  responder,
181  fl_key_event_new_by_mock(12345, kPress, GDK_KEY_a, kKeyCodeKeyA,
182  static_cast<GdkModifierType>(0), kIsNotModifier),
184 
185  EXPECT_EQ(g_call_records->len, 1u);
186  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
187  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
188  EXPECT_EQ(record->event->timestamp, 12345000);
189  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
190  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
191  EXPECT_EQ(record->event->logical, kLogicalKeyA);
192  EXPECT_STREQ(record->event->character, "a");
193  EXPECT_EQ(record->event->synthesized, false);
194 
196  g_ptr_array_clear(g_call_records);
197 
198  // Key up
200  responder,
201  fl_key_event_new_by_mock(12346, kRelease, GDK_KEY_a, kKeyCodeKeyA,
202  static_cast<GdkModifierType>(0), kIsNotModifier),
204 
205  EXPECT_EQ(g_call_records->len, 1u);
206  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
207  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
208  EXPECT_EQ(record->event->timestamp, 12346000);
209  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
210  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
211  EXPECT_EQ(record->event->logical, kLogicalKeyA);
212  EXPECT_STREQ(record->event->character, nullptr);
213  EXPECT_EQ(record->event->synthesized, false);
214 
216  g_ptr_array_clear(g_call_records);
217 
218  // On an AZERTY keyboard, press key Q (physically key A), and release.
219  // Key down
221  responder,
222  fl_key_event_new_by_mock(12347, kPress, GDK_KEY_q, kKeyCodeKeyA,
223  static_cast<GdkModifierType>(0), kIsNotModifier),
225 
226  EXPECT_EQ(g_call_records->len, 1u);
227  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
228  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
229  EXPECT_EQ(record->event->timestamp, 12347000);
230  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
231  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
232  EXPECT_EQ(record->event->logical, kLogicalKeyQ);
233  EXPECT_STREQ(record->event->character, "q");
234  EXPECT_EQ(record->event->synthesized, false);
235 
237  g_ptr_array_clear(g_call_records);
238 
239  // Key up
241  responder,
242  fl_key_event_new_by_mock(12348, kRelease, GDK_KEY_q, kKeyCodeKeyA,
243  static_cast<GdkModifierType>(0), kIsNotModifier),
245 
246  EXPECT_EQ(g_call_records->len, 1u);
247  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
248  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
249  EXPECT_EQ(record->event->timestamp, 12348000);
250  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
251  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
252  EXPECT_EQ(record->event->logical, kLogicalKeyQ);
253  EXPECT_STREQ(record->event->character, nullptr);
254  EXPECT_EQ(record->event->synthesized, false);
255 
257  g_ptr_array_clear(g_call_records);
258 
260  g_object_unref(responder);
261 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 1594 of file fl_key_embedder_responder_test.cc.

1594  {
1595  EXPECT_EQ(g_call_records, nullptr);
1596  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1597  FlKeyResponder* responder = FL_KEY_RESPONDER(
1598  fl_key_embedder_responder_new(record_calls, g_call_records));
1599  int user_data = 123; // Arbitrary user data
1600 
1601  FlKeyEmbedderCallRecord* record;
1602 
1603  // The NumLock is desynchronized by being enabled, and Control is pressed.
1604  GdkModifierType state =
1605  static_cast<GdkModifierType>(GDK_MOD2_MASK | GDK_CONTROL_MASK);
1606 
1607  // Send a KeyA up event, which will be ignored.
1608  g_expected_handled = true; // The ignored event is always handled.
1610  responder,
1611  fl_key_event_new_by_mock(101, kRelease, GDK_KEY_a, kKeyCodeKeyA, state,
1612  kIsNotModifier),
1614 
1615  EXPECT_EQ(g_call_records->len, 2u);
1616  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1617  EXPECT_EQ(record->event->timestamp, 101000);
1618  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1619  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1620  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1621  EXPECT_STREQ(record->event->character, nullptr);
1622  EXPECT_EQ(record->event->synthesized, true);
1623 
1624  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1625  EXPECT_EQ(record->event->timestamp, 101000);
1626  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1627  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1628  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1629  EXPECT_STREQ(record->event->character, nullptr);
1630  EXPECT_EQ(record->event->synthesized, true);
1631 
1632  g_ptr_array_clear(g_call_records);
1633 
1635  g_object_unref(responder);
1636 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 1387 of file fl_key_embedder_responder_test.cc.

1387  {
1388  EXPECT_EQ(g_call_records, nullptr);
1389  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1390  FlKeyResponder* responder = FL_KEY_RESPONDER(
1391  fl_key_embedder_responder_new(record_calls, g_call_records));
1392  int user_data = 123; // Arbitrary user data
1393 
1394  FlKeyEmbedderCallRecord* record;
1395 
1396  // The NumLock is desynchronized by being enabled.
1397  GdkModifierType state = GDK_MOD2_MASK;
1398 
1399  // Send a normal event
1401  responder,
1402  fl_key_event_new_by_mock(101, kPress, GDK_KEY_a, kKeyCodeKeyA, state,
1403  kIsNotModifier),
1405 
1406  EXPECT_EQ(g_call_records->len, 2u);
1407  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1408  EXPECT_EQ(record->event->timestamp, 101000);
1409  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1410  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1411  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1412  EXPECT_STREQ(record->event->character, nullptr);
1413  EXPECT_EQ(record->event->synthesized, true);
1414 
1415  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1416  EXPECT_EQ(record->event->timestamp, 101000);
1417  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1418  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1419  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1420  EXPECT_STREQ(record->event->character, "a");
1421  EXPECT_EQ(record->event->synthesized, false);
1422 
1424  g_ptr_array_clear(g_call_records);
1425 
1426  // The NumLock is desynchronized by being disabled.
1427  state = static_cast<GdkModifierType>(0);
1428 
1429  // Release key A
1431  responder,
1432  fl_key_event_new_by_mock(102, kRelease, GDK_KEY_A, kKeyCodeKeyA, state,
1433  kIsNotModifier),
1435 
1436  EXPECT_EQ(g_call_records->len, 4u);
1437  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1438  EXPECT_EQ(record->event->timestamp, 102000);
1439  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1440  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1441  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1442  EXPECT_STREQ(record->event->character, nullptr);
1443  EXPECT_EQ(record->event->synthesized, true);
1444 
1445  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1446  EXPECT_EQ(record->event->timestamp, 102000);
1447  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1448  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1449  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1450  EXPECT_STREQ(record->event->character, nullptr);
1451  EXPECT_EQ(record->event->synthesized, true);
1452 
1453  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 2));
1454  EXPECT_EQ(record->event->timestamp, 102000);
1455  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1456  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1457  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1458  EXPECT_STREQ(record->event->character, nullptr);
1459  EXPECT_EQ(record->event->synthesized, true);
1460 
1461  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 3));
1462  EXPECT_EQ(record->event->timestamp, 102000);
1463  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1464  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1465  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1466  EXPECT_STREQ(record->event->character, nullptr);
1467  EXPECT_EQ(record->event->synthesized, false);
1468 
1470  g_ptr_array_clear(g_call_records);
1471 
1472  // Release NumLock. Since the previous event should have synthesized NumLock
1473  // to be released, this should result in only an empty event.
1474  g_expected_handled = true;
1476  responder,
1477  fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Num_Lock, kKeyCodeNumLock,
1478  state, kIsModifier),
1480 
1481  EXPECT_EQ(g_call_records->len, 1u);
1482  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1483  EXPECT_EQ(record->event->physical, 0ull);
1484  EXPECT_EQ(record->event->logical, 0ull);
1485  EXPECT_STREQ(record->event->character, nullptr);
1486  EXPECT_EQ(record->event->synthesized, false);
1487  EXPECT_EQ(record->callback, nullptr);
1488 
1490  g_object_unref(responder);
1491 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 1495 of file fl_key_embedder_responder_test.cc.

1495  {
1496  EXPECT_EQ(g_call_records, nullptr);
1497  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1498  FlKeyResponder* responder = FL_KEY_RESPONDER(
1499  fl_key_embedder_responder_new(record_calls, g_call_records));
1500  int user_data = 123; // Arbitrary user data
1501 
1502  FlKeyEmbedderCallRecord* record;
1503 
1504  // The NumLock is desynchronized by being enabled.
1505  GdkModifierType state = GDK_MOD2_MASK;
1506 
1507  // NumLock down
1509  responder,
1510  fl_key_event_new_by_mock(101, kPress, GDK_KEY_Num_Lock, kKeyCodeNumLock,
1511  state, kIsModifier),
1513 
1514  EXPECT_EQ(g_call_records->len, 3u);
1515  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1516  EXPECT_EQ(record->event->timestamp, 101000);
1517  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1518  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1519  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1520  EXPECT_STREQ(record->event->character, nullptr);
1521  EXPECT_EQ(record->event->synthesized, true);
1522 
1523  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1524  EXPECT_EQ(record->event->timestamp, 101000);
1525  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1526  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1527  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1528  EXPECT_STREQ(record->event->character, nullptr);
1529  EXPECT_EQ(record->event->synthesized, true);
1530 
1531  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 2));
1532  EXPECT_EQ(record->event->timestamp, 101000);
1533  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1534  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1535  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1536  EXPECT_STREQ(record->event->character, nullptr);
1537  EXPECT_EQ(record->event->synthesized, false);
1538 
1540  g_ptr_array_clear(g_call_records);
1541 
1542  // The NumLock is desynchronized by being enabled in a press event.
1543  state = GDK_MOD2_MASK;
1544 
1545  // NumLock up
1547  responder,
1548  fl_key_event_new_by_mock(102, kPress, GDK_KEY_Num_Lock, kKeyCodeNumLock,
1549  state, kIsModifier),
1551 
1552  EXPECT_EQ(g_call_records->len, 4u);
1553  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1554  EXPECT_EQ(record->event->timestamp, 102000);
1555  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1556  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1557  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1558  EXPECT_STREQ(record->event->character, nullptr);
1559  EXPECT_EQ(record->event->synthesized, true);
1560 
1561  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1562  EXPECT_EQ(record->event->timestamp, 102000);
1563  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1564  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1565  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1566  EXPECT_STREQ(record->event->character, nullptr);
1567  EXPECT_EQ(record->event->synthesized, true);
1568 
1569  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 2));
1570  EXPECT_EQ(record->event->timestamp, 102000);
1571  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1572  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1573  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1574  EXPECT_STREQ(record->event->character, nullptr);
1575  EXPECT_EQ(record->event->synthesized, true);
1576 
1577  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 3));
1578  EXPECT_EQ(record->event->timestamp, 102000);
1579  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1580  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1581  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1582  EXPECT_STREQ(record->event->character, nullptr);
1583  EXPECT_EQ(record->event->synthesized, false);
1584 
1586  g_ptr_array_clear(g_call_records);
1587 
1589  g_object_unref(responder);
1590 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 1187 of file fl_key_embedder_responder_test.cc.

1188  {
1189  EXPECT_EQ(g_call_records, nullptr);
1190  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1191  FlKeyResponder* responder = FL_KEY_RESPONDER(
1192  fl_key_embedder_responder_new(record_calls, g_call_records));
1193  int user_data = 123; // Arbitrary user data
1194 
1195  FlKeyEmbedderCallRecord* record;
1196 
1197  // A key down of control left is missed.
1198  GdkModifierType state = GDK_CONTROL_MASK;
1199 
1200  // Send a normal event (KeyA down)
1202  responder,
1203  fl_key_event_new_by_mock(101, kPress, GDK_KEY_a, kKeyCodeKeyA, state,
1204  kIsNotModifier),
1206 
1207  EXPECT_EQ(g_call_records->len, 2u);
1208  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1209  EXPECT_EQ(record->event->timestamp, 101000);
1210  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1211  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1212  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1213  EXPECT_STREQ(record->event->character, nullptr);
1214  EXPECT_EQ(record->event->synthesized, true);
1215 
1216  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1217  EXPECT_EQ(record->event->timestamp, 101000);
1218  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1219  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1220  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1221  EXPECT_STREQ(record->event->character, "a");
1222  EXPECT_EQ(record->event->synthesized, false);
1223 
1225  g_ptr_array_clear(g_call_records);
1226 
1227  // A key up of control left is missed.
1228  state = static_cast<GdkModifierType>(0);
1229 
1230  // Send a normal event (KeyA up)
1232  responder,
1233  fl_key_event_new_by_mock(102, kRelease, GDK_KEY_A, kKeyCodeKeyA, state,
1234  kIsNotModifier),
1236 
1237  EXPECT_EQ(g_call_records->len, 2u);
1238  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1239  EXPECT_EQ(record->event->timestamp, 102000);
1240  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1241  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1242  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1243  EXPECT_STREQ(record->event->character, nullptr);
1244  EXPECT_EQ(record->event->synthesized, true);
1245 
1246  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1247  EXPECT_EQ(record->event->timestamp, 102000);
1248  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1249  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1250  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1251  EXPECT_STREQ(record->event->character, nullptr);
1252  EXPECT_EQ(record->event->synthesized, false);
1253 
1255  g_ptr_array_clear(g_call_records);
1256 
1257  // Test non-default key mapping.
1258 
1259  // Press a key with physical CapsLock and logical ControlLeft.
1260  state = static_cast<GdkModifierType>(0);
1261 
1263  responder,
1264  fl_key_event_new_by_mock(101, kPress, GDK_KEY_Control_L, kKeyCodeCapsLock,
1265  state, kIsModifier),
1267 
1268  EXPECT_EQ(g_call_records->len, 1u);
1269  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1270  EXPECT_EQ(record->event->timestamp, 101000);
1271  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1272  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1273  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1274  EXPECT_STREQ(record->event->character, nullptr);
1275  EXPECT_EQ(record->event->synthesized, false);
1276 
1278  g_ptr_array_clear(g_call_records);
1279 
1280  // The key up of the control left press is missed.
1281  state = static_cast<GdkModifierType>(0);
1282 
1283  // Send a normal event (KeyA down).
1285  responder,
1286  fl_key_event_new_by_mock(102, kPress, GDK_KEY_A, kKeyCodeKeyA, state,
1287  kIsNotModifier),
1289 
1290  // The synthesized event should have physical CapsLock and logical
1291  // ControlLeft.
1292  EXPECT_EQ(g_call_records->len, 2u);
1293  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1294  EXPECT_EQ(record->event->timestamp, 102000);
1295  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1296  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1297  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1298  EXPECT_STREQ(record->event->character, nullptr);
1299  EXPECT_EQ(record->event->synthesized, true);
1300 
1301  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1302  EXPECT_EQ(record->event->timestamp, 102000);
1303  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1304  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1305  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1306  EXPECT_STREQ(record->event->character, "A");
1307  EXPECT_EQ(record->event->synthesized, false);
1308 
1310  g_ptr_array_clear(g_call_records);
1311 
1313  g_object_unref(responder);
1314 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 1318 of file fl_key_embedder_responder_test.cc.

1319  {
1320  EXPECT_EQ(g_call_records, nullptr);
1321  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1322  FlKeyResponder* responder = FL_KEY_RESPONDER(
1323  fl_key_embedder_responder_new(record_calls, g_call_records));
1324  int user_data = 123; // Arbitrary user data
1325 
1326  FlKeyEmbedderCallRecord* record;
1327 
1328  // Press a key with physical CapsLock and logical ControlLeft.
1329  GdkModifierType state = static_cast<GdkModifierType>(0);
1330 
1332  responder,
1333  fl_key_event_new_by_mock(101, kPress, GDK_KEY_Control_L, kKeyCodeCapsLock,
1334  state, kIsModifier),
1336 
1337  EXPECT_EQ(g_call_records->len, 1u);
1338  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1339  EXPECT_EQ(record->event->timestamp, 101000);
1340  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1341  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1342  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1343  EXPECT_STREQ(record->event->character, nullptr);
1344  EXPECT_EQ(record->event->synthesized, false);
1345 
1347  g_ptr_array_clear(g_call_records);
1348 
1349  // The key up of the control left press is missed.
1350  state = static_cast<GdkModifierType>(0);
1351 
1352  // Send a normal event (KeyA down).
1354  responder,
1355  fl_key_event_new_by_mock(102, kPress, GDK_KEY_A, kKeyCodeKeyA, state,
1356  kIsNotModifier),
1358 
1359  // The synthesized event should have physical CapsLock and logical
1360  // ControlLeft.
1361  EXPECT_EQ(g_call_records->len, 2u);
1362  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1363  EXPECT_EQ(record->event->timestamp, 102000);
1364  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1365  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1366  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1367  EXPECT_STREQ(record->event->character, nullptr);
1368  EXPECT_EQ(record->event->synthesized, true);
1369 
1370  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1371  EXPECT_EQ(record->event->timestamp, 102000);
1372  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1373  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1374  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1375  EXPECT_STREQ(record->event->character, "A");
1376  EXPECT_EQ(record->event->synthesized, false);
1377 
1379  g_ptr_array_clear(g_call_records);
1380 
1382  g_object_unref(responder);
1383 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 1057 of file fl_key_embedder_responder_test.cc.

1057  {
1058  EXPECT_EQ(g_call_records, nullptr);
1059  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1060  FlKeyResponder* responder = FL_KEY_RESPONDER(
1061  fl_key_embedder_responder_new(record_calls, g_call_records));
1062  int user_data = 123; // Arbitrary user data
1063 
1064  FlKeyEmbedderCallRecord* record;
1065 
1066  // Test 1: synthesize key down.
1067 
1068  // A key down of control left is missed.
1069  GdkModifierType state = GDK_CONTROL_MASK;
1070 
1071  // Send a ControlLeft up
1073  responder,
1074  fl_key_event_new_by_mock(101, kRelease, GDK_KEY_Control_L,
1075  kKeyCodeControlLeft, state, kIsModifier),
1077 
1078  EXPECT_EQ(g_call_records->len, 2u);
1079  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1080  EXPECT_EQ(record->event->timestamp, 101000);
1081  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1082  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1083  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1084  EXPECT_STREQ(record->event->character, nullptr);
1085  EXPECT_EQ(record->event->synthesized, true);
1086 
1087  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1088  EXPECT_EQ(record->event->timestamp, 101000);
1089  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1090  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1091  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1092  EXPECT_STREQ(record->event->character, nullptr);
1093  EXPECT_EQ(record->event->synthesized, false);
1094 
1096  g_ptr_array_clear(g_call_records);
1097 
1098  // Test 2: synthesize key up.
1099 
1100  // Send a ControlLeft down.
1101  state = static_cast<GdkModifierType>(0);
1103  responder,
1104  fl_key_event_new_by_mock(102, kPress, GDK_KEY_Control_L,
1105  kKeyCodeControlLeft, state, kIsModifier),
1107  EXPECT_EQ(g_call_records->len, 1u);
1108  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1110  g_ptr_array_clear(g_call_records);
1111 
1112  // A key up of control left is missed.
1113  state = static_cast<GdkModifierType>(0);
1114 
1115  // Send another ControlLeft down
1117  responder,
1118  fl_key_event_new_by_mock(103, kPress, GDK_KEY_Control_L,
1119  kKeyCodeControlLeft, state, kIsModifier),
1121 
1122  EXPECT_EQ(g_call_records->len, 2u);
1123  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1124  EXPECT_EQ(record->event->timestamp, 103000);
1125  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1126  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1127  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1128  EXPECT_STREQ(record->event->character, nullptr);
1129  EXPECT_EQ(record->event->synthesized, true);
1130 
1131  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1132  EXPECT_EQ(record->event->timestamp, 103000);
1133  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1134  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1135  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1136  EXPECT_STREQ(record->event->character, nullptr);
1137  EXPECT_EQ(record->event->synthesized, false);
1138 
1140  g_ptr_array_clear(g_call_records);
1141 
1142  // Send a ControlLeft up to clear up state.
1143  state = GDK_CONTROL_MASK;
1145  responder,
1146  fl_key_event_new_by_mock(104, kRelease, GDK_KEY_Control_L,
1147  kKeyCodeControlLeft, state, kIsModifier),
1149  EXPECT_EQ(g_call_records->len, 1u);
1150  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1152  g_ptr_array_clear(g_call_records);
1153 
1154  // Test 3: synthesize by right modifier.
1155 
1156  // A key down of control right is missed.
1157  state = GDK_CONTROL_MASK;
1158 
1159  // Send a ControlRight up.
1161  responder,
1162  fl_key_event_new_by_mock(105, kRelease, GDK_KEY_Control_R,
1163  kKeyCodeControlRight, state, kIsModifier),
1165 
1166  // A ControlLeft down is synthesized, with an empty event.
1167  // Reason: The ControlLeft down is synthesized to synchronize the state
1168  // showing Control as pressed. The ControlRight event is ignored because
1169  // the event is considered a duplicate up event.
1170  EXPECT_EQ(g_call_records->len, 1u);
1171  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1172  EXPECT_EQ(record->event->timestamp, 105000);
1173  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1174  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1175  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1176  EXPECT_STREQ(record->event->character, nullptr);
1177  EXPECT_EQ(record->event->synthesized, true);
1178 
1179  g_ptr_array_clear(g_call_records);
1180 
1182  g_object_unref(responder);
1183 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 648 of file fl_key_embedder_responder_test.cc.

648  {
649  EXPECT_EQ(g_call_records, nullptr);
650  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
651  FlKeyResponder* responder = FL_KEY_RESPONDER(
653  int user_data = 123; // Arbitrary user data
654 
655  FlKeyEmbedderCallRecord* record;
656 
657  // Press CapsLock (stage 0 -> 1)
659  responder,
660  fl_key_event_new_by_mock(101, kPress, GDK_KEY_Caps_Lock, kKeyCodeCapsLock,
661  static_cast<GdkModifierType>(0), kIsModifier),
663 
664  EXPECT_EQ(g_call_records->len, 1u);
665  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
666  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
667  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
668  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
669  EXPECT_STREQ(record->event->character, nullptr);
670  EXPECT_EQ(record->event->synthesized, false);
671 
673  g_ptr_array_clear(g_call_records);
674 
675  // Press key A (stage 1)
677  responder,
678  fl_key_event_new_by_mock(102, kPress, GDK_KEY_A, kKeyCodeKeyA,
679  GDK_LOCK_MASK, kIsNotModifier),
681 
682  EXPECT_EQ(g_call_records->len, 1u);
683  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
684  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
685  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
686  EXPECT_EQ(record->event->logical, kLogicalKeyA);
687  EXPECT_STREQ(record->event->character, "A");
688  EXPECT_EQ(record->event->synthesized, false);
689 
691  g_ptr_array_clear(g_call_records);
692 
693  // Release CapsLock (stage 1 -> 2)
695  responder,
696  fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Caps_Lock,
697  kKeyCodeCapsLock, GDK_LOCK_MASK, kIsModifier),
699 
700  EXPECT_EQ(g_call_records->len, 1u);
701  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
702  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
703  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
704  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
705  EXPECT_STREQ(record->event->character, nullptr);
706  EXPECT_EQ(record->event->synthesized, false);
707 
709  g_ptr_array_clear(g_call_records);
710 
711  // Release key A (stage 2)
713  responder,
714  fl_key_event_new_by_mock(104, kRelease, GDK_KEY_A, kKeyCodeKeyA,
715  GDK_LOCK_MASK, kIsNotModifier),
717 
718  EXPECT_EQ(g_call_records->len, 1u);
719  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
720  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
721  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
722  EXPECT_EQ(record->event->logical, kLogicalKeyA);
723  EXPECT_STREQ(record->event->character, nullptr);
724  EXPECT_EQ(record->event->synthesized, false);
725 
727  g_ptr_array_clear(g_call_records);
728 
729  // Press CapsLock (stage 2 -> 3)
731  responder,
732  fl_key_event_new_by_mock(105, kPress, GDK_KEY_Caps_Lock, kKeyCodeCapsLock,
733  GDK_LOCK_MASK, kIsModifier),
735 
736  EXPECT_EQ(g_call_records->len, 1u);
737  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
738  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
739  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
740  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
741  EXPECT_STREQ(record->event->character, nullptr);
742  EXPECT_EQ(record->event->synthesized, false);
743 
745  g_ptr_array_clear(g_call_records);
746 
747  // Press key A (stage 3)
749  responder,
750  fl_key_event_new_by_mock(106, kPress, GDK_KEY_A, kKeyCodeKeyA,
751  GDK_LOCK_MASK, kIsNotModifier),
753 
754  EXPECT_EQ(g_call_records->len, 1u);
755  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
756  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
757  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
758  EXPECT_EQ(record->event->logical, kLogicalKeyA);
759  EXPECT_STREQ(record->event->character, "A");
760  EXPECT_EQ(record->event->synthesized, false);
761 
763  g_ptr_array_clear(g_call_records);
764 
765  // Release CapsLock (stage 3 -> 0)
767  responder,
768  fl_key_event_new_by_mock(107, kRelease, GDK_KEY_Caps_Lock,
769  kKeyCodeCapsLock, GDK_LOCK_MASK, kIsModifier),
771 
772  EXPECT_EQ(g_call_records->len, 1u);
773  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
774  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
775  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
776  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
777  EXPECT_STREQ(record->event->character, nullptr);
778  EXPECT_EQ(record->event->synthesized, false);
779 
781  g_ptr_array_clear(g_call_records);
782 
783  // Release key A (stage 0)
785  responder,
786  fl_key_event_new_by_mock(108, kRelease, GDK_KEY_a, kKeyCodeKeyA,
787  static_cast<GdkModifierType>(0), kIsNotModifier),
789 
790  EXPECT_EQ(g_call_records->len, 1u);
791  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
792  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
793  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
794  EXPECT_EQ(record->event->logical, kLogicalKeyA);
795  EXPECT_STREQ(record->event->character, nullptr);
796  EXPECT_EQ(record->event->synthesized, false);
797 
799  g_ptr_array_clear(g_call_records);
800 
802  g_object_unref(responder);
803 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 809 of file fl_key_embedder_responder_test.cc.

809  {
810  EXPECT_EQ(g_call_records, nullptr);
811  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
812  FlKeyResponder* responder = FL_KEY_RESPONDER(
814  int user_data = 123; // Arbitrary user data
815 
816  FlKeyEmbedderCallRecord* record;
817 
818  // Press key A (stage 0)
820  responder,
821  fl_key_event_new_by_mock(101, kPress, GDK_KEY_a, kKeyCodeKeyA,
822  static_cast<GdkModifierType>(0), kIsNotModifier),
824 
825  EXPECT_EQ(g_call_records->len, 1u);
826  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
827  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
828  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
829  EXPECT_EQ(record->event->logical, kLogicalKeyA);
830  EXPECT_STREQ(record->event->character, "a");
831  EXPECT_EQ(record->event->synthesized, false);
832 
834  g_ptr_array_clear(g_call_records);
835 
836  // Press CapsLock (stage 0 -> 1)
838  responder,
839  fl_key_event_new_by_mock(102, kPress, GDK_KEY_Caps_Lock, kKeyCodeCapsLock,
840  GDK_LOCK_MASK, kIsModifier),
842 
843  EXPECT_EQ(g_call_records->len, 1u);
844  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
845  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
846  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
847  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
848  EXPECT_STREQ(record->event->character, nullptr);
849  EXPECT_EQ(record->event->synthesized, false);
850 
852  g_ptr_array_clear(g_call_records);
853 
854  // Release CapsLock (stage 1 -> 2)
856  responder,
857  fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Caps_Lock,
858  kKeyCodeCapsLock, GDK_LOCK_MASK, kIsModifier),
860 
861  EXPECT_EQ(g_call_records->len, 1u);
862  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
863  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
864  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
865  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
866  EXPECT_STREQ(record->event->character, nullptr);
867  EXPECT_EQ(record->event->synthesized, false);
868 
870  g_ptr_array_clear(g_call_records);
871 
872  // Release key A (stage 2)
874  responder,
875  fl_key_event_new_by_mock(104, kRelease, GDK_KEY_A, kKeyCodeKeyA,
876  GDK_LOCK_MASK, kIsNotModifier),
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, kPhysicalKeyA);
883  EXPECT_EQ(record->event->logical, kLogicalKeyA);
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  // Press key A (stage 2)
892  responder,
893  fl_key_event_new_by_mock(105, kPress, GDK_KEY_A, kKeyCodeKeyA,
894  GDK_LOCK_MASK, kIsNotModifier),
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, kFlutterKeyEventTypeDown);
900  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
901  EXPECT_EQ(record->event->logical, kLogicalKeyA);
902  EXPECT_STREQ(record->event->character, "A");
903  EXPECT_EQ(record->event->synthesized, false);
904 
906  g_ptr_array_clear(g_call_records);
907 
908  // Press CapsLock (stage 2 -> 3)
910  responder,
911  fl_key_event_new_by_mock(106, kPress, GDK_KEY_Caps_Lock, kKeyCodeCapsLock,
912  static_cast<GdkModifierType>(0), kIsModifier),
914 
915  EXPECT_EQ(g_call_records->len, 1u);
916  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
917  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
918  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
919  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
920  EXPECT_STREQ(record->event->character, nullptr);
921  EXPECT_EQ(record->event->synthesized, false);
922 
924  g_ptr_array_clear(g_call_records);
925 
926  // Release CapsLock (stage 3 -> 0)
928  responder,
929  fl_key_event_new_by_mock(107, kRelease, GDK_KEY_Caps_Lock,
930  kKeyCodeCapsLock, GDK_LOCK_MASK, kIsModifier),
932 
933  EXPECT_EQ(g_call_records->len, 1u);
934  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
935  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
936  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
937  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
938  EXPECT_STREQ(record->event->character, nullptr);
939  EXPECT_EQ(record->event->synthesized, false);
940 
942  g_ptr_array_clear(g_call_records);
943 
944  // Release key A (stage 0)
946  responder,
947  fl_key_event_new_by_mock(108, kRelease, GDK_KEY_a, kKeyCodeKeyA,
948  static_cast<GdkModifierType>(0), kIsNotModifier),
950 
951  EXPECT_EQ(g_call_records->len, 1u);
952  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
953  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
954  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
955  EXPECT_EQ(record->event->logical, kLogicalKeyA);
956  EXPECT_STREQ(record->event->character, nullptr);
957  EXPECT_EQ(record->event->synthesized, false);
958 
960  g_ptr_array_clear(g_call_records);
961 
963  g_object_unref(responder);
964 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 392 of file fl_key_embedder_responder_test.cc.

392  {
393  EXPECT_EQ(g_call_records, nullptr);
394  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
395  FlKeyResponder* responder = FL_KEY_RESPONDER(
397  int user_data = 123; // Arbitrary user data
398 
399  FlKeyEmbedderCallRecord* record;
400 
401  // Press Numpad 1 (stage 0)
403  responder,
404  fl_key_event_new_by_mock(101, kPress, GDK_KEY_KP_End, kKeyCodeNumpad1,
405  static_cast<GdkModifierType>(0), kIsNotModifier),
407 
408  EXPECT_EQ(g_call_records->len, 1u);
409  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
410  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
411  EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
412  EXPECT_EQ(record->event->logical, kLogicalNumpad1);
413  EXPECT_STREQ(record->event->character, nullptr); // TODO(chrome-bot):
414  EXPECT_EQ(record->event->synthesized, false);
415 
417  g_ptr_array_clear(g_call_records);
418 
419  // Press NumLock (stage 0 -> 1)
421  responder,
422  fl_key_event_new_by_mock(102, kPress, GDK_KEY_Num_Lock, kKeyCodeNumLock,
423  static_cast<GdkModifierType>(0), kIsNotModifier),
425 
426  EXPECT_EQ(g_call_records->len, 1u);
427  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
428  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
429  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
430  EXPECT_EQ(record->event->logical, kLogicalNumLock);
431  EXPECT_STREQ(record->event->character, nullptr);
432  EXPECT_EQ(record->event->synthesized, false);
433 
435  g_ptr_array_clear(g_call_records);
436 
437  // Release numpad 1 (stage 1)
439  responder,
440  fl_key_event_new_by_mock(104, kRelease, GDK_KEY_KP_1, kKeyCodeNumpad1,
441  GDK_MOD2_MASK, kIsNotModifier),
443 
444  EXPECT_EQ(g_call_records->len, 1u);
445  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
446  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
447  EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
448  EXPECT_EQ(record->event->logical, kLogicalNumpad1);
449  EXPECT_STREQ(record->event->character, nullptr);
450  EXPECT_EQ(record->event->synthesized, false);
451 
453  g_ptr_array_clear(g_call_records);
454 
455  // Release NumLock (stage 1 -> 2)
457  responder,
458  fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Num_Lock, kKeyCodeNumLock,
459  GDK_MOD2_MASK, kIsModifier),
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, kFlutterKeyEventTypeUp);
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  // Press Numpad 1 (stage 2)
475  responder,
476  fl_key_event_new_by_mock(101, kPress, GDK_KEY_KP_End, kKeyCodeNumpad1,
477  GDK_MOD2_MASK, kIsNotModifier),
479 
480  EXPECT_EQ(g_call_records->len, 1u);
481  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
482  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
483  EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
484  EXPECT_EQ(record->event->logical, kLogicalNumpad1);
485  EXPECT_STREQ(record->event->character, nullptr); // TODO(chrome-bot):
486  EXPECT_EQ(record->event->synthesized, false);
487 
489  g_ptr_array_clear(g_call_records);
490 
491  // Press NumLock (stage 2 -> 3)
493  responder,
494  fl_key_event_new_by_mock(102, kPress, GDK_KEY_Num_Lock, kKeyCodeNumLock,
495  GDK_MOD2_MASK, kIsNotModifier),
497 
498  EXPECT_EQ(g_call_records->len, 1u);
499  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
500  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
501  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
502  EXPECT_EQ(record->event->logical, kLogicalNumLock);
503  EXPECT_STREQ(record->event->character, nullptr);
504  EXPECT_EQ(record->event->synthesized, false);
505 
507  g_ptr_array_clear(g_call_records);
508 
509  // Release numpad 1 (stage 3)
511  responder,
512  fl_key_event_new_by_mock(104, kRelease, GDK_KEY_KP_1, kKeyCodeNumpad1,
513  GDK_MOD2_MASK, kIsNotModifier),
515 
516  EXPECT_EQ(g_call_records->len, 1u);
517  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
518  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
519  EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
520  EXPECT_EQ(record->event->logical, kLogicalNumpad1);
521  EXPECT_STREQ(record->event->character, nullptr);
522  EXPECT_EQ(record->event->synthesized, false);
523 
525  g_ptr_array_clear(g_call_records);
526 
527  // Release NumLock (stage 3 -> 0)
529  responder,
530  fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Num_Lock, kKeyCodeNumLock,
531  GDK_MOD2_MASK, kIsModifier),
533 
534  EXPECT_EQ(g_call_records->len, 1u);
535  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
536  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
537  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
538  EXPECT_EQ(record->event->logical, kLogicalNumLock);
539  EXPECT_STREQ(record->event->character, nullptr);
540  EXPECT_EQ(record->event->synthesized, false);
541 
543  g_ptr_array_clear(g_call_records);
544 
546  g_object_unref(responder);
547 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 966 of file fl_key_embedder_responder_test.cc.

966  {
967  EXPECT_EQ(g_call_records, nullptr);
968  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
969  FlKeyResponder* responder = FL_KEY_RESPONDER(
971  int user_data = 123; // Arbitrary user data
972 
973  FlKeyEmbedderCallRecord* record;
974 
975  // Press KeyA
977  responder,
978  fl_key_event_new_by_mock(101, kPress, GDK_KEY_a, kKeyCodeKeyA,
979  static_cast<GdkModifierType>(0), kIsNotModifier),
981 
982  EXPECT_EQ(g_call_records->len, 1u);
983 
984  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
986  g_ptr_array_clear(g_call_records);
987 
988  // Another KeyA down events, which usually means a repeated event.
989  g_expected_handled = false;
991  responder,
992  fl_key_event_new_by_mock(102, kPress, GDK_KEY_a, kKeyCodeKeyA,
993  static_cast<GdkModifierType>(0), kIsNotModifier),
995 
996  EXPECT_EQ(g_call_records->len, 1u);
997 
998  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
999  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeRepeat);
1000  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1001  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1002  EXPECT_STREQ(record->event->character, "a");
1003  EXPECT_EQ(record->event->synthesized, false);
1004  EXPECT_NE(record->callback, nullptr);
1005 
1007  g_ptr_array_clear(g_call_records);
1008 
1009  // Release KeyA
1011  responder,
1012  fl_key_event_new_by_mock(103, kRelease, GDK_KEY_q, kKeyCodeKeyA,
1013  static_cast<GdkModifierType>(0), kIsNotModifier),
1015 
1016  EXPECT_EQ(g_call_records->len, 1u);
1017  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1019  g_ptr_array_clear(g_call_records);
1020 
1022  g_object_unref(responder);
1023 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 264 of file fl_key_embedder_responder_test.cc.

264  {
265  EXPECT_EQ(g_call_records, nullptr);
266  g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
267  FlKeyResponder* responder = FL_KEY_RESPONDER(
269  int user_data = 123; // Arbitrary user data
270 
271  FlKeyEmbedderCallRecord* record;
272 
273  // On an AZERTY keyboard, press physical key 1, and release.
274  // Key down
276  responder,
277  fl_key_event_new_by_mock(12345, kPress, GDK_KEY_ampersand, kKeyCodeDigit1,
278  static_cast<GdkModifierType>(0), kIsNotModifier),
279  verify_response_handled, &user_data, kLogicalDigit1);
280 
281  EXPECT_EQ(g_call_records->len, 1u);
282  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
283  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
284  EXPECT_EQ(record->event->timestamp, 12345000);
285  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
286  EXPECT_EQ(record->event->physical, kPhysicalDigit1);
287  EXPECT_EQ(record->event->logical, kLogicalDigit1);
288  EXPECT_STREQ(record->event->character, "&");
289  EXPECT_EQ(record->event->synthesized, false);
290 
292  g_ptr_array_clear(g_call_records);
293 
295  g_object_unref(responder);
296 }

References clear_g_call_records(), fl_key_embedder_responder_new(), fl_key_event_new_by_mock(), 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 133 of file fl_key_embedder_responder_test.cc.

133  {
134  EXPECT_EQ(handled, g_expected_handled);
135 }

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:162
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:150
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_event_new_by_mock
static FlKeyEvent * fl_key_event_new_by_mock(guint32 time_in_milliseconds, bool is_press, guint keyval, guint16 keycode, GdkModifierType state, gboolean is_modifier)
Definition: fl_key_embedder_responder_test.cc:115
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:62
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:79
g_expected_handled
static gboolean g_expected_handled
Definition: fl_key_embedder_responder_test.cc:130
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:137
g_ptr_array_clear
static void g_ptr_array_clear(GPtrArray *array)
Definition: fl_key_embedder_responder_test.cc:37
g_expected_user_data
static gpointer g_expected_user_data
Definition: fl_key_embedder_responder_test.cc:131
verify_response_handled
static void verify_response_handled(bool handled, gpointer user_data)
Definition: fl_key_embedder_responder_test.cc:133
send_key_event
static void send_key_event(FlTextInputPlugin *plugin, gint keyval, gint state=0)
Definition: fl_text_input_plugin_test.cc:181
callback
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
Definition: fl_key_channel_responder.cc:120
expected_handled
static gboolean expected_handled
Definition: fl_key_channel_responder_test.cc:14