Flutter Engine
The Flutter Engine
Classes | Functions
FLUTTER_ASSERT_ARC Namespace Reference

Classes

class  MachThreads
 
class  MockPlatformMessageResponse
 

Functions

typedef NS_OPTIONS (NSInteger, kKeyboardModifier)
 
static NSString * getEventCharacters (NSString *characters, UIKeyboardHIDUsage keyCode) API_AVAILABLE(ios(13.4))
 
static NSUInteger lowestSetBit (NSUInteger bitmask)
 
static bool IsControlCharacter (NSUInteger length, NSString *label)
 
static bool IsUnprintableKey (NSUInteger length, NSString *label)
 
static uint64_t KeyOfPlane (uint64_t baseKey, uint64_t plane)
 
static uint64_t GetPhysicalKeyForKeyCode (UInt32 keyCode)
 
static uint64_t GetLogicalKeyForModifier (UInt32 keyCode, uint64_t hidCode)
 
static uint64_t toLower (uint64_t n)
 
static const char * getEventCharacters (NSString *characters, UIKeyboardHIDUsage keyCode) API_AVAILABLE(ios(13.4))
 
static uint64_t GetLogicalKeyForEvent (FlutterUIPressProxy *press, NSNumber *maybeSpecialKey) API_AVAILABLE(ios(13.4))
 
static double GetFlutterTimestampFrom (NSTimeInterval timestamp)
 
static NSUInteger computeModifierFlagOfInterestMask ()
 
static bool isKeyDown (FlutterUIPressProxy *press) API_AVAILABLE(ios(13.4))
 
void HandleResponse (bool handled, void *user_data)
 
flutter::SemanticsAction GetSemanticsActionForScrollDirection (UIAccessibilityScrollDirection direction)
 
SkM44 GetGlobalTransform (SemanticsObject *reference)
 
SkPoint ApplyTransform (SkPoint &point, const SkM44 &transform)
 
CGPoint ConvertPointToGlobal (SemanticsObject *reference, CGPoint local_point)
 
CGRect ConvertRectToGlobal (SemanticsObject *reference, CGRect local_rect)
 
fml::RefPtr< fml::TaskRunnerCreateNewThread (const std::string &name)
 
fml::RefPtr< fml::TaskRunnerGetCurrentTaskRunner ()
 

Function Documentation

◆ ApplyTransform()

SkPoint FLUTTER_ASSERT_ARC::ApplyTransform ( SkPoint point,
const SkM44 transform 
)

Definition at line 47 of file SemanticsObject.mm.

47 {
48 SkV4 vector = transform.map(point.x(), point.y(), 0, 1);
49 return SkPoint::Make(vector.x / vector.w, vector.y / vector.w);
50}
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition: p3.cpp:47
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173
constexpr float y() const
Definition: SkPoint_impl.h:187
constexpr float x() const
Definition: SkPoint_impl.h:181
Definition: SkM44.h:98
float w
Definition: SkM44.h:99
float y
Definition: SkM44.h:99
float x
Definition: SkM44.h:99

◆ computeModifierFlagOfInterestMask()

static NSUInteger FLUTTER_ASSERT_ARC::computeModifierFlagOfInterestMask ( )
static

Compute |modifierFlagOfInterestMask| out of |keyCodeToModifierFlag|.

This is equal to the bitwise-or of all values of |keyCodeToModifierFlag|.

Definition at line 211 of file FlutterEmbedderKeyResponder.mm.

211 {
212 NSUInteger modifierFlagOfInterestMask = kModifierFlagCapsLock | kModifierFlagShiftAny |
215 for (std::pair<UInt32, ModifierFlag> entry : keyCodeToModifierFlag) {
216 modifierFlagOfInterestMask = modifierFlagOfInterestMask | entry.second;
217 }
218 return modifierFlagOfInterestMask;
219}
const std::map< uint32_t, ModifierFlag > keyCodeToModifierFlag
@ kModifierFlagCapsLock
@ kModifierFlagShiftAny
@ kModifierFlagMetaAny
@ kModifierFlagControlAny
@ kModifierFlagAltAny

◆ ConvertPointToGlobal()

CGPoint FLUTTER_ASSERT_ARC::ConvertPointToGlobal ( SemanticsObject reference,
CGPoint  local_point 
)

Definition at line 52 of file SemanticsObject.mm.

52 {
53 SkM44 globalTransform = GetGlobalTransform(reference);
54 SkPoint point = SkPoint::Make(local_point.x, local_point.y);
55 point = ApplyTransform(point, globalTransform);
56 // `rect` is in the physical pixel coordinate system. iOS expects the accessibility frame in
57 // the logical pixel coordinate system. Therefore, we divide by the `scale` (pixel ratio) to
58 // convert.
59 UIScreen* screen = reference.bridge->view().window.screen;
60 // Screen can be nil if the FlutterView is covered by another native view.
61 CGFloat scale = (screen ?: UIScreen.mainScreen).scale;
62 auto result = CGPointMake(point.x() / scale, point.y() / scale);
63 return [reference.bridge->view() convertPoint:result toView:nil];
64}
Definition: SkM44.h:150
virtual UIView * view() const =0
GAsyncResult * result
fml::WeakPtr< flutter::AccessibilityBridgeIos > bridge
SkM44 GetGlobalTransform(SemanticsObject *reference)
SkPoint ApplyTransform(SkPoint &point, const SkM44 &transform)
const Scalar scale

◆ ConvertRectToGlobal()

CGRect FLUTTER_ASSERT_ARC::ConvertRectToGlobal ( SemanticsObject reference,
CGRect  local_rect 
)

Definition at line 66 of file SemanticsObject.mm.

66 {
67 SkM44 globalTransform = GetGlobalTransform(reference);
68
69 SkPoint quad[4] = {
70 SkPoint::Make(local_rect.origin.x, local_rect.origin.y), // top left
71 SkPoint::Make(local_rect.origin.x + local_rect.size.width, local_rect.origin.y), // top right
72 SkPoint::Make(local_rect.origin.x + local_rect.size.width,
73 local_rect.origin.y + local_rect.size.height), // bottom right
74 SkPoint::Make(local_rect.origin.x,
75 local_rect.origin.y + local_rect.size.height) // bottom left
76 };
77 for (auto& point : quad) {
78 point = ApplyTransform(point, globalTransform);
79 }
81 NSCAssert(rect.setBoundsCheck(quad, 4), @"Transformed points can't form a rect");
82 rect.setBounds(quad, 4);
83
84 // `rect` is in the physical pixel coordinate system. iOS expects the accessibility frame in
85 // the logical pixel coordinate system. Therefore, we divide by the `scale` (pixel ratio) to
86 // convert.
87 UIScreen* screen = reference.bridge->view().window.screen;
88 // Screen can be nil if the FlutterView is covered by another native view.
89 CGFloat scale = (screen ?: UIScreen.mainScreen).scale;
90 auto result =
91 CGRectMake(rect.x() / scale, rect.y() / scale, rect.width() / scale, rect.height() / scale);
92 return UIAccessibilityConvertFrameToScreenCoordinates(result, reference.bridge->view());
93}
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350

◆ CreateNewThread()

fml::RefPtr< fml::TaskRunner > FLUTTER_ASSERT_ARC::CreateNewThread ( const std::string &  name)

Definition at line 16 of file VsyncWaiterIosTest.mm.

16 {
17 auto thread = std::make_unique<fml::Thread>(name);
18 auto runner = thread->GetTaskRunner();
19 return runner;
20}
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32

◆ GetCurrentTaskRunner()

fml::RefPtr< fml::TaskRunner > FLUTTER_ASSERT_ARC::GetCurrentTaskRunner ( )

Definition at line 27 of file platform_message_handler_ios_test.mm.

27 {
30}
static void EnsureInitializedForCurrentThread()
Definition: message_loop.cc:27
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
Definition: message_loop.cc:56
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
Definition: message_loop.cc:19

◆ getEventCharacters() [1/2]

static NSString * FLUTTER_ASSERT_ARC::getEventCharacters ( NSString *  characters,
UIKeyboardHIDUsage  keyCode 
)
static

Filters out some special cases in the characters field on UIKey.

Definition at line 53 of file FlutterChannelKeyResponder.mm.

54 {
55 if (characters == nil) {
56 return nil;
57 }
58 if ([characters length] == 0) {
59 return nil;
60 }
61 if (@available(iOS 13.4, *)) {
62 // On iOS, function keys return the UTF8 string "\^P" (with a literal '/',
63 // '^' and a 'P', not escaped ctrl-P) as their "characters" field. This
64 // isn't a valid (single) UTF8 character. Looking at the only UTF16
65 // character for a function key yields a value of "16", which is a Unicode
66 // "SHIFT IN" character, which is just odd. UTF8 conversion of that string
67 // is what generates the three characters "\^P".
68 //
69 // Anyhow, we strip them all out and replace them with empty strings, since
70 // function keys shouldn't be printable.
71 if (functionKeyCodes.find(keyCode) != functionKeyCodes.end()) {
72 return nil;
73 }
74 }
75 return characters;
76}
const std::set< uint32_t > functionKeyCodes
size_t length

◆ getEventCharacters() [2/2]

static const char * FLUTTER_ASSERT_ARC::getEventCharacters ( NSString *  characters,
UIKeyboardHIDUsage  keyCode 
)
static

Filters out some special cases in the characters field on UIKey.

Definition at line 124 of file FlutterEmbedderKeyResponder.mm.

125 {
126 if (characters == nil) {
127 return nullptr;
128 }
129 if ([characters length] == 0) {
130 return nullptr;
131 }
132 if (@available(iOS 13.4, *)) {
133 // On iOS, function keys return the UTF8 string "\^P" (with a literal '/',
134 // '^' and a 'P', not escaped ctrl-P) as their "characters" field. This
135 // isn't a valid (single) UTF8 character. Looking at the only UTF16
136 // character for a function key yields a value of "16", which is a Unicode
137 // "SHIFT IN" character, which is just odd. UTF8 conversion of that string
138 // is what generates the three characters "\^P".
139 //
140 // Anyhow, we strip them all out and replace them with empty strings, since
141 // function keys shouldn't be printable.
142 if (functionKeyCodes.find(keyCode) != functionKeyCodes.end()) {
143 return nullptr;
144 }
145 }
146 return [characters UTF8String];
147}

◆ GetFlutterTimestampFrom()

static double FLUTTER_ASSERT_ARC::GetFlutterTimestampFrom ( NSTimeInterval  timestamp)
static

Converts NSEvent.timestamp to the timestamp for Flutter.

Definition at line 201 of file FlutterEmbedderKeyResponder.mm.

201 {
202 // Timestamp in microseconds. The event.timestamp is in seconds with sub-ms precision.
203 return timestamp * 1000000.0;
204}

◆ GetGlobalTransform()

SkM44 FLUTTER_ASSERT_ARC::GetGlobalTransform ( SemanticsObject reference)

Definition at line 39 of file SemanticsObject.mm.

39 {
40 SkM44 globalTransform = [reference node].transform;
41 for (SemanticsObject* parent = [reference parent]; parent; parent = parent.parent) {
42 globalTransform = parent.node.transform * globalTransform;
43 }
44 return globalTransform;
45}
SemanticsObject * parent

◆ GetLogicalKeyForEvent()

static uint64_t FLUTTER_ASSERT_ARC::GetLogicalKeyForEvent ( FlutterUIPressProxy press,
NSNumber *  maybeSpecialKey 
)
static

Returns the logical key of a KeyUp or KeyDown event.

The maybeSpecialKey is a nullable integer, and if not nil, indicates that the event key is a special key as defined by specialKeyMapping, and is the corresponding logical key.

For modifier keys, use GetLogicalKeyForModifier.

Definition at line 158 of file FlutterEmbedderKeyResponder.mm.

159 {
160 if (maybeSpecialKey != nil) {
161 return [maybeSpecialKey unsignedLongLongValue];
162 }
163 // Look to see if the keyCode can be mapped from keycode.
164 auto fromKeyCode = keyCodeToLogicalKey.find(press.key.keyCode);
165 if (fromKeyCode != keyCodeToLogicalKey.end()) {
166 return fromKeyCode->second;
167 }
168 const char* characters =
169 getEventCharacters(press.key.charactersIgnoringModifiers, press.key.keyCode);
170 NSString* keyLabel =
171 characters == nullptr ? nil : [[NSString alloc] initWithUTF8String:characters];
172 NSUInteger keyLabelLength = [keyLabel length];
173 // If this key is printable, generate the logical key from its Unicode
174 // value. Control keys such as ESC, CTRL, and SHIFT are not printable. HOME,
175 // DEL, arrow keys, and function keys are considered modifier function keys,
176 // which generate invalid Unicode scalar values.
177 if (keyLabelLength != 0 && !IsControlCharacter(keyLabelLength, keyLabel) &&
178 !IsUnprintableKey(keyLabelLength, keyLabel)) {
179 // Given that charactersIgnoringModifiers can contain a string of arbitrary
180 // length, limit to a maximum of two Unicode scalar values. It is unlikely
181 // that a keyboard would produce a code point bigger than 32 bits, but it is
182 // still worth defending against this case.
183 NSCAssert((keyLabelLength < 2), @"Unexpected long key label: |%@|.", keyLabel);
184
185 uint64_t codeUnit = (uint64_t)[keyLabel characterAtIndex:0];
186 if (keyLabelLength == 2) {
187 uint64_t secondCode = (uint64_t)[keyLabel characterAtIndex:1];
188 codeUnit = (codeUnit << 16) | secondCode;
189 }
190 return KeyOfPlane(toLower(codeUnit), kUnicodePlane);
191 }
192
193 // This is a non-printable key that is unrecognized, so a new code is minted
194 // with the autogenerated bit set.
195 return KeyOfPlane(press.key.keyCode, kIosPlane);
196}
const uint64_t kUnicodePlane
Definition: KeyCodeMap.g.mm:27
const std::map< uint32_t, uint64_t > keyCodeToLogicalKey
const uint64_t kIosPlane
Definition: KeyCodeMap.g.mm:32
static uint64_t KeyOfPlane(uint64_t baseKey, uint64_t plane)
static uint64_t toLower(uint64_t n)
static const char * getEventCharacters(NSString *characters, UIKeyboardHIDUsage keyCode) API_AVAILABLE(ios(13.4))
static bool IsControlCharacter(NSUInteger length, NSString *label)
static bool IsUnprintableKey(NSUInteger length, NSString *label)

◆ GetLogicalKeyForModifier()

static uint64_t FLUTTER_ASSERT_ARC::GetLogicalKeyForModifier ( UInt32  keyCode,
uint64_t  hidCode 
)
static

Returns the logical key for a modifier physical key.

Definition at line 84 of file FlutterEmbedderKeyResponder.mm.

84 {
85 auto fromKeyCode = keyCodeToLogicalKey.find(keyCode);
86 if (fromKeyCode != keyCodeToLogicalKey.end()) {
87 return fromKeyCode->second;
88 }
89 return KeyOfPlane(hidCode, kIosPlane);
90}

◆ GetPhysicalKeyForKeyCode()

static uint64_t FLUTTER_ASSERT_ARC::GetPhysicalKeyForKeyCode ( UInt32  keyCode)
static

Returns the physical key for a key code.

Definition at line 73 of file FlutterEmbedderKeyResponder.mm.

73 {
74 auto physicalKey = keyCodeToPhysicalKey.find(keyCode);
75 if (physicalKey == keyCodeToPhysicalKey.end()) {
76 return KeyOfPlane(keyCode, kIosPlane);
77 }
78 return physicalKey->second;
79}
const std::map< uint32_t, uint64_t > keyCodeToPhysicalKey
Definition: KeyCodeMap.g.mm:37

◆ GetSemanticsActionForScrollDirection()

flutter::SemanticsAction FLUTTER_ASSERT_ARC::GetSemanticsActionForScrollDirection ( UIAccessibilityScrollDirection  direction)

Definition at line 14 of file SemanticsObject.mm.

15 {
16 // To describe the vertical scroll direction, UIAccessibilityScrollDirection uses the
17 // direction the scroll bar moves in and SemanticsAction uses the direction the finger
18 // moves in. However, the horizontal scroll direction matches the SemanticsAction direction.
19 // That is way the following maps vertical opposite of the SemanticsAction, but the horizontal
20 // maps directly.
21 switch (direction) {
22 case UIAccessibilityScrollDirectionRight:
23 case UIAccessibilityScrollDirectionPrevious: // TODO(abarth): Support RTL using
24 // _node.textDirection.
26 case UIAccessibilityScrollDirectionLeft:
27 case UIAccessibilityScrollDirectionNext: // TODO(abarth): Support RTL using
28 // _node.textDirection.
30 case UIAccessibilityScrollDirectionUp:
32 case UIAccessibilityScrollDirectionDown:
34 }
35 FML_DCHECK(false); // Unreachable
37}
#define FML_DCHECK(condition)
Definition: logging.h:103

◆ HandleResponse()

void FLUTTER_ASSERT_ARC::HandleResponse ( bool  handled,
void *  user_data 
)

The C-function sent to the engine's |sendKeyEvent|, wrapping |FlutterEmbedderKeyResponder.handleResponse|.

For the reason of this wrap, see |FlutterKeyPendingResponse|.

◆ IsControlCharacter()

static bool FLUTTER_ASSERT_ARC::IsControlCharacter ( NSUInteger  length,
NSString *  label 
)
static

Whether a string represents a control character.

Definition at line 37 of file FlutterEmbedderKeyResponder.mm.

37 {
38 if (length > 1) {
39 return false;
40 }
41 unichar codeUnit = [label characterAtIndex:0];
42 return (codeUnit <= 0x1f && codeUnit >= 0x00) || (codeUnit >= 0x7f && codeUnit <= 0x9f);
43}

◆ isKeyDown()

static bool FLUTTER_ASSERT_ARC::isKeyDown ( FlutterUIPressProxy press)
static

Definition at line 221 of file FlutterEmbedderKeyResponder.mm.

221 {
222 switch (press.phase) {
223 case UIPressPhaseStationary:
224 case UIPressPhaseChanged:
225 // Not sure if this is the right thing to do for these two, but true seems
226 // more correct than false.
227 return true;
228 case UIPressPhaseBegan:
229 return true;
230 case UIPressPhaseCancelled:
231 case UIPressPhaseEnded:
232 return false;
233 }
234 return false;
235}

◆ IsUnprintableKey()

static bool FLUTTER_ASSERT_ARC::IsUnprintableKey ( NSUInteger  length,
NSString *  label 
)
static

Whether a string represents an unprintable key.

Definition at line 48 of file FlutterEmbedderKeyResponder.mm.

48 {
49 if (length > 1) {
50 return false;
51 }
52 unichar codeUnit = [label characterAtIndex:0];
53 return codeUnit >= 0xF700 && codeUnit <= 0xF8FF;
54}

◆ KeyOfPlane()

static uint64_t FLUTTER_ASSERT_ARC::KeyOfPlane ( uint64_t  baseKey,
uint64_t  plane 
)
static

Returns a key code composed with a base key and a plane.

Examples of unprintable keys are "NSUpArrowFunctionKey = 0xF700" or "NSHomeFunctionKey = 0xF729".

See https://developer.apple.com/documentation/appkit/1535851-function-key_unicodes?language=objc for more information.

Definition at line 66 of file FlutterEmbedderKeyResponder.mm.

66 {
67 return plane | (baseKey & kValueMask);
68}
const uint64_t kValueMask
Definition: KeyCodeMap.g.mm:22

◆ lowestSetBit()

static NSUInteger FLUTTER_ASSERT_ARC::lowestSetBit ( NSUInteger  bitmask)
static

Isolate the least significant 1-bit.

For example,

  • lowestSetBit(0x1010) returns 0x10.
  • lowestSetBit(0) returns 0.

Definition at line 28 of file FlutterEmbedderKeyResponder.mm.

28 {
29 // This utilizes property of two's complement (negation), which propagates a
30 // carry bit from LSB to the lowest set bit.
31 return bitmask & -bitmask;
32}

◆ NS_OPTIONS()

typedef FLUTTER_ASSERT_ARC::NS_OPTIONS ( NSInteger  ,
kKeyboardModifier   
)

Definition at line 19 of file FlutterChannelKeyResponder.mm.

19 {
20 kKeyboardModifierAlphaShift = 0x10000,
21 kKeyboardModifierShift = 0x20000,
22 kKeyboardModifierLeftShift = 0x02,
23 kKeyboardModifierRightShift = 0x04,
24 kKeyboardModifierControl = 0x40000,
25 kKeyboardModifierLeftControl = 0x01,
26 kKeyboardModifierRightControl = 0x2000,
27 kKeyboardModifierOption = 0x80000,
28 kKeyboardModifierLeftOption = 0x20,
29 kKeyboardModifierRightOption = 0x40,
30 kKeyboardModifierCommand = 0x100000,
31 kKeyboardModifierLeftCommand = 0x08,
32 kKeyboardModifierRightCommand = 0x10,
33 kKeyboardModifierNumericPad = 0x200000,
34 kKeyboardModifierMask = kKeyboardModifierAlphaShift | //
35 kKeyboardModifierShift | //
36 kKeyboardModifierLeftShift | //
37 kKeyboardModifierRightShift | //
38 kKeyboardModifierControl | //
39 kKeyboardModifierLeftControl | //
40 kKeyboardModifierRightControl | //
41 kKeyboardModifierOption | //
42 kKeyboardModifierLeftOption | //
43 kKeyboardModifierRightOption | //
44 kKeyboardModifierCommand | //
45 kKeyboardModifierLeftCommand | //
46 kKeyboardModifierRightCommand | //
47 kKeyboardModifierNumericPad,
48};

◆ toLower()

static uint64_t FLUTTER_ASSERT_ARC::toLower ( uint64_t  n)
static

Converts upper letters to lower letters in ASCII and extended ASCII, and returns as-is otherwise.

Independent of locale.

Definition at line 98 of file FlutterEmbedderKeyResponder.mm.

98 {
99 constexpr uint64_t lower_a = 0x61;
100 constexpr uint64_t upper_a = 0x41;
101 constexpr uint64_t upper_z = 0x5a;
102
103 constexpr uint64_t lower_a_grave = 0xe0;
104 constexpr uint64_t upper_a_grave = 0xc0;
105 constexpr uint64_t upper_thorn = 0xde;
106 constexpr uint64_t division = 0xf7;
107
108 // ASCII range.
109 if (n >= upper_a && n <= upper_z) {
110 return n - upper_a + lower_a;
111 }
112
113 // EASCII range.
114 if (n >= upper_a_grave && n <= upper_thorn && n != division) {
115 return n - upper_a_grave + lower_a_grave;
116 }
117
118 return n;
119}