5#include <Carbon/Carbon.h>
6#import <Foundation/Foundation.h>
7#import <OCMock/OCMock.h>
9#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h"
10#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterKeyPrimaryResponder.h"
11#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterKeyboardManager.h"
12#include "flutter/shell/platform/embedder/test_utils/key_codes.g.h"
13#import "flutter/testing/testing.h"
14#include "third_party/googletest/googletest/include/gtest/gtest.h"
29typedef BOOL (^BoolGetter)();
33typedef BOOL (^TextInputCallback)(NSEvent*);
39constexpr uint16_t kKeyCodeEmpty = 0x00;
42constexpr uint32_t kEmbedderCall = 0x1;
43constexpr uint32_t kChannelCall = 0x2;
44constexpr uint32_t kTextCall = 0x4;
54typedef const std::array<uint32_t, 256> MockLayoutData;
58MockLayoutData kUsLayout = {
60 0x00061, 0x00041, 0x00073, 0x00053, 0x00064, 0x00044, 0x00066, 0x00046,
61 0x00068, 0x00048, 0x00067, 0x00047, 0x0007a, 0x0005a, 0x00078, 0x00058,
62 0x00063, 0x00043, 0x00076, 0x00056, 0x000a7, 0x000b1, 0x00062, 0x00042,
63 0x00071, 0x00051, 0x00077, 0x00057, 0x00065, 0x00045, 0x00072, 0x00052,
64 0x00079, 0x00059, 0x00074, 0x00054, 0x00031, 0x00021, 0x00032, 0x00040,
65 0x00033, 0x00023, 0x00034, 0x00024, 0x00036, 0x0005e, 0x00035, 0x00025,
66 0x0003d, 0x0002b, 0x00039, 0x00028, 0x00037, 0x00026, 0x0002d, 0x0005f,
67 0x00038, 0x0002a, 0x00030, 0x00029, 0x0005d, 0x0007d, 0x0006f, 0x0004f,
68 0x00075, 0x00055, 0x0005b, 0x0007b, 0x00069, 0x00049, 0x00070, 0x00050,
69 0x00000, 0x00000, 0x0006c, 0x0004c, 0x0006a, 0x0004a, 0x00027, 0x00022,
70 0x0006b, 0x0004b, 0x0003b, 0x0003a, 0x0005c, 0x0007c, 0x0002c, 0x0003c,
71 0x0002f, 0x0003f, 0x0006e, 0x0004e, 0x0006d, 0x0004d, 0x0002e, 0x0003e,
72 0x00000, 0x00000, 0x00020, 0x00020, 0x00060, 0x0007e,
75MockLayoutData kFrenchLayout = {
77 0x00071, 0x00051, 0x00073, 0x00053, 0x00064, 0x00044, 0x00066, 0x00046,
78 0x00068, 0x00048, 0x00067, 0x00047, 0x00077, 0x00057, 0x00078, 0x00058,
79 0x00063, 0x00043, 0x00076, 0x00056, 0x00040, 0x00023, 0x00062, 0x00042,
80 0x00061, 0x00041, 0x0007a, 0x0005a, 0x00065, 0x00045, 0x00072, 0x00052,
81 0x00079, 0x00059, 0x00074, 0x00054, 0x00026, 0x00031, 0x000e9, 0x00032,
82 0x00022, 0x00033, 0x00027, 0x00034, 0x000a7, 0x00036, 0x00028, 0x00035,
83 0x0002d, 0x0005f, 0x000e7, 0x00039, 0x000e8, 0x00037, 0x00029, 0x000b0,
84 0x00021, 0x00038, 0x000e0, 0x00030, 0x00024, 0x0002a, 0x0006f, 0x0004f,
85 0x00075, 0x00055, 0x1005e, 0x100a8, 0x00069, 0x00049, 0x00070, 0x00050,
86 0x00000, 0x00000, 0x0006c, 0x0004c, 0x0006a, 0x0004a, 0x000f9, 0x00025,
87 0x0006b, 0x0004b, 0x0006d, 0x0004d, 0x10060, 0x000a3, 0x0003b, 0x0002e,
88 0x0003d, 0x0002b, 0x0006e, 0x0004e, 0x0002c, 0x0003f, 0x0003a, 0x0002f,
89 0x00000, 0x00000, 0x00020, 0x00020, 0x0003c, 0x0003e,
92MockLayoutData kRussianLayout = {
94 0x00444, 0x00424, 0x0044b, 0x0042b, 0x00432, 0x00412, 0x00430, 0x00410,
95 0x00440, 0x00420, 0x0043f, 0x0041f, 0x0044f, 0x0042f, 0x00447, 0x00427,
96 0x00441, 0x00421, 0x0043c, 0x0041c, 0x0003e, 0x0003c, 0x00438, 0x00418,
97 0x00439, 0x00419, 0x00446, 0x00426, 0x00443, 0x00423, 0x0043a, 0x0041a,
98 0x0043d, 0x0041d, 0x00435, 0x00415, 0x00031, 0x00021, 0x00032, 0x00022,
99 0x00033, 0x02116, 0x00034, 0x00025, 0x00036, 0x0002c, 0x00035, 0x0003a,
100 0x0003d, 0x0002b, 0x00039, 0x00028, 0x00037, 0x0002e, 0x0002d, 0x0005f,
101 0x00038, 0x0003b, 0x00030, 0x00029, 0x0044a, 0x0042a, 0x00449, 0x00429,
102 0x00433, 0x00413, 0x00445, 0x00425, 0x00448, 0x00428, 0x00437, 0x00417,
103 0x00000, 0x00000, 0x00434, 0x00414, 0x0043e, 0x0041e, 0x0044d, 0x0042d,
104 0x0043b, 0x0041b, 0x00436, 0x00416, 0x00451, 0x00401, 0x00431, 0x00411,
105 0x0002f, 0x0003f, 0x00442, 0x00422, 0x0044c, 0x0042c, 0x0044e, 0x0042e,
106 0x00000, 0x00000, 0x00020, 0x00020, 0x0005d, 0x0005b,
109MockLayoutData kKhmerLayout = {
111 0x017b6, 0x017ab, 0x0179f, 0x017c3, 0x0178a, 0x0178c, 0x01790, 0x01792,
112 0x017a0, 0x017c7, 0x01784, 0x017a2, 0x0178b, 0x0178d, 0x01781, 0x01783,
113 0x01785, 0x01787, 0x0179c, 0x017c8, 0x00000, 0x00000, 0x01794, 0x01796,
114 0x01786, 0x01788, 0x017b9, 0x017ba, 0x017c1, 0x017c2, 0x0179a, 0x017ac,
115 0x01799, 0x017bd, 0x0178f, 0x01791, 0x017e1, 0x00021, 0x017e2, 0x017d7,
116 0x017e3, 0x00022, 0x017e4, 0x017db, 0x017e6, 0x017cd, 0x017e5, 0x00025,
117 0x017b2, 0x017ce, 0x017e9, 0x017b0, 0x017e7, 0x017d0, 0x017a5, 0x017cc,
118 0x017e8, 0x017cf, 0x017e0, 0x017b3, 0x017aa, 0x017a7, 0x017c4, 0x017c5,
119 0x017bb, 0x017bc, 0x017c0, 0x017bf, 0x017b7, 0x017b8, 0x01795, 0x01797,
120 0x00000, 0x00000, 0x0179b, 0x017a1, 0x017d2, 0x01789, 0x017cb, 0x017c9,
121 0x01780, 0x01782, 0x017be, 0x017d6, 0x017ad, 0x017ae, 0x017a6, 0x017b1,
122 0x017ca, 0x017af, 0x01793, 0x0178e, 0x01798, 0x017c6, 0x017d4, 0x017d5,
123 0x00000, 0x00000, 0x00020, 0x0200b, 0x000ab, 0x000bb,
126NSEvent*
keyDownEvent(
unsigned short keyCode, NSString* chars =
@"", NSString* charsUnmod =
@"") {
127 return [NSEvent keyEventWithType:NSEventTypeKeyDown
134 charactersIgnoringModifiers:charsUnmod
140 return [NSEvent keyEventWithType:NSEventTypeKeyUp
147 charactersIgnoringModifiers:
@""
152id checkKeyDownEvent(
unsigned short keyCode) {
153 return [OCMArg checkWithBlock:^
BOOL(
id value) {
154 if (![
value isKindOfClass:[NSEvent
class]]) {
157 NSEvent*
event =
value;
158 return event.keyCode == keyCode;
163void clearEvents(std::vector<FlutterKeyEvent>& events) {
165 if (
event.character !=
nullptr) {
166 delete[]
event.character;
172#define VERIFY_DOWN(OUT_LOGICAL, OUT_CHAR) \
173 EXPECT_EQ(events[0].type, kFlutterKeyEventTypeDown); \
174 EXPECT_EQ(events[0].logical, static_cast<uint64_t>(OUT_LOGICAL)); \
175 EXPECT_STREQ(events[0].character, (OUT_CHAR)); \
181- (nonnull instancetype)
init;
184- (void)respondEmbedderCallsWith:(
BOOL)response;
192 returning:(
bool)handled;
195- (void)respondChannelCallsWith:(
BOOL)response;
203- (void)respondTextInputWith:(
BOOL)response;
212- (void)recordCallTypesTo:(nonnull NSMutableArray<NSNumber*>*)typeStorage
213 forTypes:(uint32_t)typeMask;
217- (void)sendKeyboardChannelMessage:(NSData* _Nullable)message;
222#pragma mark - Private
226 userData:(nullable
void*)userData;
228- (void)handleChannelMessage:(NSString*)channel
229 message:(NSData* _Nullable)message
232- (
BOOL)handleTextInputKeyEvent:(NSEvent*)event;
236 AsyncEmbedderCallbackHandler _embedderHandler;
251- (nonnull instancetype)
init {
257 _nextResponder = OCMClassMock([NSResponder
class]);
258 [
self respondChannelCallsWith:FALSE];
259 [
self respondEmbedderCallsWith:FALSE];
260 [
self respondTextInputWith:FALSE];
267 binaryReply:[OCMArg
any]])
268 .andCall(
self,
@selector(handleChannelMessage:
message:binaryReply:));
269 OCMStub([
_messengerMock setMessageHandlerOnChannel:
@"flutter/keyboard"
270 binaryMessageHandler:[OCMArg
any]])
271 .andCall(
self,
@selector(setKeyboardChannelHandler:handler:));
273 .andCall(
self,
@selector(handleKeyboardChannelMessage:
message:));
275 OCMStub([viewDelegateMock nextResponder]).andReturn(_nextResponder);
276 OCMStub([viewDelegateMock onTextInputKeyEvent:[OCMArg
any]])
277 .andCall(
self,
@selector(handleTextInputKeyEvent:));
278 OCMStub([viewDelegateMock getBinaryMessenger]).andReturn(
_messengerMock);
279 OCMStub([viewDelegateMock sendKeyEvent:*(
const FlutterKeyEvent*)[OCMArg anyPointer]
282 .ignoringNonObjectArgs()
283 .andCall(
self,
@selector(handleEmbedderEvent:
callback:userData:));
284 OCMStub([viewDelegateMock subscribeToKeyboardLayoutChange:[OCMArg
any]])
285 .andCall(
self,
@selector(onSetKeyboardLayoutNotifier:));
286 OCMStub([viewDelegateMock lookUpLayoutForKeyCode:0 shift:
false])
287 .ignoringNonObjectArgs()
288 .andCall(
self,
@selector(lookUpLayoutForKeyCode:shift:));
294- (
id)lastKeyboardChannelResult {
298- (void)respondEmbedderCallsWith:(
BOOL)response {
306 [storage addObject:callback];
311 returning:(
bool)handled {
314 if (
event->character !=
nullptr) {
315 size_t charLen = strlen(
event->character);
316 char* newCharacter =
new char[charLen + 1];
317 strlcpy(newCharacter,
event->character, charLen + 1);
320 storage->push_back(newEvent);
325- (void)respondChannelCallsWith:(
BOOL)response {
333 [storage addObject:callback];
337- (void)respondTextInputWith:(
BOOL)response {
343- (void)recordCallTypesTo:(nonnull NSMutableArray<NSNumber*>*)typeStorage
344 forTypes:(uint32_t)typeMask {
349- (void)sendKeyboardChannelMessage:(NSData* _Nullable)message {
350 [_messengerMock sendOnChannel:@"flutter/keyboard" message:message];
353- (void)setLayout:(const MockLayoutData&)layout {
360#pragma mark - Private
364 userData:(nullable
void*)userData {
366 [_typeStorage addObject:@(kEmbedderCall)];
369 _embedderHandler(&
event, ^(
BOOL handled) {
375- (void)handleChannelMessage:(NSString*)channel
376 message:(NSData* _Nullable)message
379 [_typeStorage addObject:@(kChannelCall)];
383 @"handled" : @(handled),
390- (void)handleKeyboardChannelMessage:(NSString*)channel message:(NSData* _Nullable)message {
396- (
BOOL)handleTextInputKeyEvent:(NSEvent*)event {
398 [_typeStorage addObject:@(kTextCall)];
407- (LayoutClue)lookUpLayoutForKeyCode:(uint16_t)keyCode shift:(
BOOL)shift {
408 uint32_t cluePair = (*_currentLayout)[(keyCode * 2) + (shift ? 1 : 0)];
409 const uint32_t kCharMask = 0xffff;
410 const uint32_t kDeadKeyMask = 0x10000;
411 return LayoutClue{cluePair & kCharMask, (cluePair & kDeadKeyMask) != 0};
434TEST(FlutterKeyboardManagerUnittests, SinglePrimaryResponder) {
438TEST(FlutterKeyboardManagerUnittests, DoublePrimaryResponder) {
442TEST(FlutterKeyboardManagerUnittests, SingleFinalResponder) {
446TEST(FlutterKeyboardManagerUnittests, EmptyNextResponder) {
450TEST(FlutterKeyboardManagerUnittests, GetPressedState) {
454TEST(FlutterKeyboardManagerUnittests, KeyboardChannelGetPressedState) {
458TEST(FlutterKeyboardManagerUnittests, RacingConditionBetweenKeyAndText) {
462TEST(FlutterKeyboardManagerUnittests, CorrectLogicalKeyForLayouts) {
466TEST(FlutterKeyboardManagerUnittests, ShouldNotHoldStrongReferenceToViewDelegate) {
477 NSMutableArray<FlutterAsyncKeyCallback>* embedderCallbacks =
478 [NSMutableArray<FlutterAsyncKeyCallback> array];
482 [tester.manager handleEvent:keyDownEvent(0x50)];
483 EXPECT_EQ([embedderCallbacks
count], 1u);
484 embedderCallbacks[0](
FALSE);
485 OCMVerify([
tester.nextResponder keyDown:checkKeyDownEvent(0x50)]);
486 [embedderCallbacks removeAllObjects];
489 [tester.manager handleEvent:keyUpEvent(0x50)];
490 EXPECT_EQ([embedderCallbacks
count], 1u);
491 embedderCallbacks[0](
TRUE);
503 [tester.manager handleEvent:keyDownEvent(0x50)];
505 NSMutableArray<FlutterAsyncKeyCallback>* embedderCallbacks =
506 [NSMutableArray<FlutterAsyncKeyCallback> array];
507 NSMutableArray<FlutterAsyncKeyCallback>* channelCallbacks =
508 [NSMutableArray<FlutterAsyncKeyCallback> array];
513 [tester.manager handleEvent:keyUpEvent(0x50)];
514 EXPECT_EQ([embedderCallbacks
count], 1u);
515 EXPECT_EQ([channelCallbacks
count], 1u);
516 embedderCallbacks[0](
TRUE);
517 channelCallbacks[0](
TRUE);
518 EXPECT_EQ([embedderCallbacks
count], 1u);
519 EXPECT_EQ([channelCallbacks
count], 1u);
521 [embedderCallbacks removeAllObjects];
522 [channelCallbacks removeAllObjects];
527 [tester.manager handleEvent:keyDownEvent(0x50)];
531 [tester.manager handleEvent:keyUpEvent(0x50)];
532 EXPECT_EQ([embedderCallbacks
count], 1u);
533 EXPECT_EQ([channelCallbacks
count], 1u);
534 embedderCallbacks[0](
FALSE);
535 channelCallbacks[0](
TRUE);
536 EXPECT_EQ([embedderCallbacks
count], 1u);
537 EXPECT_EQ([channelCallbacks
count], 1u);
539 [embedderCallbacks removeAllObjects];
540 [channelCallbacks removeAllObjects];
543 [tester.manager handleEvent:keyDownEvent(0x53)];
544 EXPECT_EQ([embedderCallbacks
count], 1u);
545 EXPECT_EQ([channelCallbacks
count], 1u);
546 embedderCallbacks[0](
FALSE);
547 channelCallbacks[0](
FALSE);
548 EXPECT_EQ([embedderCallbacks
count], 1u);
549 EXPECT_EQ([channelCallbacks
count], 1u);
550 OCMVerify([
tester.nextResponder keyDown:checkKeyDownEvent(0x53)]);
551 [embedderCallbacks removeAllObjects];
552 [channelCallbacks removeAllObjects];
563 [tester.manager handleEvent:keyDownEvent(0x50)];
565 NSMutableArray<FlutterAsyncKeyCallback>* callbacks =
566 [NSMutableArray<FlutterAsyncKeyCallback> array];
572 [tester.manager handleEvent:keyUpEvent(0x50)];
573 EXPECT_EQ([callbacks
count], 1u);
576 [callbacks removeAllObjects];
580 [tester.manager handleEvent:keyDownEvent(0x50)];
586 [tester.manager handleEvent:keyUpEvent(0x50)];
587 EXPECT_EQ([callbacks
count], 1u);
590 [callbacks removeAllObjects];
594 [tester.manager handleEvent:keyDownEvent(0x50)];
595 EXPECT_EQ([callbacks
count], 1u);
597 OCMVerify([
tester.nextResponder keyDown:checkKeyDownEvent(0x50)]);
598 [callbacks removeAllObjects];
605 tester.nextResponder = nil;
610 [tester.manager handleEvent:keyDownEvent(0x50)];
622 [tester.manager handleEvent:keyDownEvent(kVK_ANSI_A)];
624 NSDictionary* pressingRecords = [tester.manager getPressedState];
625 EXPECT_EQ([pressingRecords
count], 1u);
637 [tester.manager handleEvent:keyDownEvent(kVK_ANSI_A)];
641 NSData* getKeyboardStateMessage =
648 EXPECT_EQ([decoded
count], 1u);
662 NSMutableArray<FlutterAsyncKeyCallback>* keyCallbacks =
663 [NSMutableArray<FlutterAsyncKeyCallback> array];
666 NSMutableArray<NSNumber*>* allCalls = [NSMutableArray<NSNumber*> array];
671 [tester.manager handleEvent:keyDownEvent(kKeyCodeEmpty, @"ư", @"ư")];
672 EXPECT_EQ([keyCallbacks
count], 1u);
673 EXPECT_EQ([allCalls
count], 1u);
674 EXPECT_EQ(allCalls[0], @(kEmbedderCall));
675 keyCallbacks[0](
false);
676 EXPECT_EQ([keyCallbacks
count], 1u);
677 EXPECT_EQ([allCalls
count], 2u);
678 EXPECT_EQ(allCalls[1], @(kTextCall));
679 [keyCallbacks removeAllObjects];
680 [allCalls removeAllObjects];
682 [tester.manager handleEvent:keyUpEvent(kKeyCodeEmpty)];
683 EXPECT_EQ([keyCallbacks
count], 1u);
684 keyCallbacks[0](
false);
685 EXPECT_EQ([keyCallbacks
count], 1u);
686 EXPECT_EQ([allCalls
count], 2u);
687 [keyCallbacks removeAllObjects];
688 [allCalls removeAllObjects];
693 [tester.manager handleEvent:keyDownEvent(kVK_ANSI_O, @"o", @"o")];
694 [tester.manager handleEvent:keyUpEvent(kVK_ANSI_O)];
695 EXPECT_EQ([keyCallbacks
count], 1u);
696 EXPECT_EQ([allCalls
count], 1u);
697 EXPECT_EQ(allCalls[0], @(kEmbedderCall));
702 [tester.manager handleEvent:keyDownEvent(kVK_Delete)];
703 [tester.manager handleEvent:keyUpEvent(kVK_Delete)];
704 EXPECT_EQ([keyCallbacks
count], 1u);
705 EXPECT_EQ([allCalls
count], 1u);
709 keyCallbacks[0](
false);
710 EXPECT_EQ([keyCallbacks
count], 2u);
711 EXPECT_EQ([allCalls
count], 3u);
712 EXPECT_EQ(allCalls[1], @(kTextCall));
713 EXPECT_EQ(allCalls[2], @(kEmbedderCall));
717 keyCallbacks[1](
false);
718 EXPECT_EQ([keyCallbacks
count], 3u);
719 EXPECT_EQ([allCalls
count], 5u);
720 EXPECT_EQ(allCalls[3], @(kTextCall));
721 EXPECT_EQ(allCalls[4], @(kEmbedderCall));
724 keyCallbacks[2](
false);
725 keyCallbacks[3](
false);
732 tester.nextResponder = nil;
734 std::vector<FlutterKeyEvent> events;
739 auto sendTap = [&](uint16_t keyCode, NSString* chars, NSString* charsUnmod) {
740 [tester.manager handleEvent:keyDownEvent(keyCode, chars, charsUnmod)];
741 [tester.manager handleEvent:keyUpEvent(keyCode)];
746 sendTap(kVK_ANSI_A,
@"a",
@"a");
749 sendTap(kVK_ANSI_A,
@"A",
@"A");
752 sendTap(kVK_ANSI_A,
@"å",
@"a");
755 sendTap(kVK_ANSI_T,
@"t",
@"t");
758 sendTap(kVK_ANSI_1,
@"1",
@"1");
761 sendTap(kVK_ANSI_1,
@"!",
@"!");
764 sendTap(kVK_ANSI_Minus,
@"-",
@"-");
767 sendTap(kVK_ANSI_Minus,
@"=",
@"=");
773 sendTap(kVK_ANSI_A,
@"q",
@"q");
776 sendTap(kVK_ANSI_A,
@"Q",
@"Q");
779 sendTap(kVK_ANSI_Semicolon,
@"m",
@"m");
782 sendTap(kVK_ANSI_M,
@",",
@",");
785 sendTap(kVK_ANSI_1,
@"&",
@"&");
788 sendTap(kVK_ANSI_1,
@"1",
@"1");
791 sendTap(kVK_ANSI_Minus,
@")",
@")");
794 sendTap(kVK_ANSI_Minus,
@"°",
@"°");
800 sendTap(kVK_ANSI_A,
@"ф",
@"ф");
803 sendTap(kVK_ANSI_1,
@"1",
@"1");
806 sendTap(kVK_ANSI_LeftBracket,
@"х",
@"х");
813 sendTap(kVK_ANSI_2,
@"២",
@"២");
821 __weak
id weakViewDelegate;
825 OCMStub([binaryMessengerMock setMessageHandlerOnChannel:[OCMArg
any]
826 binaryMessageHandler:[OCMArg
any]]);
829 OCMStub([viewDelegateMock getBinaryMessenger]).andReturn(binaryMessengerMock);
830 OCMStub([viewDelegateMock subscribeToKeyboardLayoutChange:[OCMArg
any]]);
832 LayoutClue layoutClue;
833 OCMStub([viewDelegateMock lookUpLayoutForKeyCode:0 shift:NO])
834 .ignoringNonObjectArgs()
835 .andReturn(layoutClue);
838 strongKeyboardManager = keyboardManager;
839 weakViewDelegate = viewDelegateMock;
842 return weakViewDelegate == nil;
NS_ASSUME_NONNULL_BEGIN typedef void(^ FlutterBinaryReply)(NSData *_Nullable reply)
void(^ FlutterBinaryMessageHandler)(NSData *_Nullable message, FlutterBinaryReply reply)
void(* FlutterKeyEventCallback)(bool, void *)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
std::function< void()> KeyboardLayoutNotifier
instancetype sharedInstance()
bool doublePrimaryResponder()
bool racingConditionBetweenKeyAndText()
bool keyboardChannelGetPressedState()
bool emptyNextResponder()
bool correctLogicalKeyForLayouts()
bool shouldNotHoldStrongReferenceToViewDelegate()
bool singlePrimaryResponder()
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)
instancetype sharedInstance()
void respondChannelCallsWith:(BOOL response)
void recordChannelCallsTo:(nonnull NSMutableArray< FlutterAsyncKeyCallback > *storage)
id lastKeyboardChannelResult()
void setLayout:(const MockLayoutData &layout)
void recordEmbedderEventsTo:returning:(nonnull std::vector< FlutterKeyEvent > *storage,[returning] bool handled)
NSResponder * nextResponder
void sendKeyboardChannelMessage:(NSData *_Nullable message)
void respondEmbedderCallsWith:(BOOL response)
void respondTextInputWith:(BOOL response)
void recordCallTypesTo:forTypes:(nonnull NSMutableArray< NSNumber * > *typeStorage,[forTypes] uint32_t typeMask)
void recordEmbedderCallsTo:(nonnull NSMutableArray< FlutterAsyncKeyCallback > *storage)
void(^ FlutterAsyncKeyCallback)(BOOL handled)
FlutterTextInputPlugin * textInputPlugin
FlutterBinaryMessageHandler _keyboardHandler
uint32_t _typeStorageMask
id _keyboardChannelResult
AsyncKeyCallbackHandler _channelHandler
TextInputCallback _textCallback
#define VERIFY_DOWN(OUT_LOGICAL, OUT_CHAR)
NSMutableArray< NSNumber * > * _typeStorage
const MockLayoutData * _currentLayout
NSObject< FlutterBinaryMessenger > * _messengerMock
flutter::KeyboardLayoutNotifier _keyboardLayoutNotifier
constexpr uint64_t kLogicalBracketLeft
constexpr uint64_t kLogicalKeyM
constexpr uint64_t kLogicalDigit1
constexpr uint64_t kPhysicalKeyA
constexpr uint64_t kLogicalKeyT
constexpr uint64_t kLogicalKeyQ
constexpr uint64_t kLogicalDigit2
constexpr uint64_t kLogicalKeyA
FlutterUIPressProxy * keyUpEvent(UIKeyboardHIDUsage keyCode, UIKeyModifierFlags modifierFlags=0x0, NSTimeInterval timestamp=0.0f, const char *characters="", const char *charactersIgnoringModifiers="") API_AVAILABLE(ios(13.4))
FlutterUIPressProxy * keyDownEvent(UIKeyboardHIDUsage keyCode, UIKeyModifierFlags modifierFlags=0x0, NSTimeInterval timestamp=0.0f, const char *characters="", const char *charactersIgnoringModifiers="") API_AVAILABLE(ios(13.4))
TEST(DisplayListComplexity, EmptyDisplayList)
void(^ KeyboardLayoutNotifier)()
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font manager
SIT bool any(const Vec< 1, T > &x)