Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
platform_view_android_delegate.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <utility>
8
9namespace flutter {
10namespace {
11void putStringAttributesIntoBuffer(
12 const StringAttributes& attributes,
13 int32_t* buffer,
14 size_t* position,
15 std::vector<std::vector<uint8_t>>& string_attribute_args) {
16 if (attributes.empty()) {
18 return;
19 }
20 buffer[(*position)++] = attributes.size();
21 for (const auto& attribute : attributes) {
22 buffer[(*position)++] = attribute->start;
23 buffer[(*position)++] = attribute->end;
24 buffer[(*position)++] = static_cast<int32_t>(attribute->type);
25 switch (attribute->type) {
28 break;
30 buffer[(*position)++] = string_attribute_args.size();
31 std::shared_ptr<LocaleStringAttribute> locale_attribute =
32 std::static_pointer_cast<LocaleStringAttribute>(attribute);
33 string_attribute_args.push_back(
34 {locale_attribute->locale.begin(), locale_attribute->locale.end()});
35 break;
36 }
37 }
38}
39
40void putStringIntoBuffer(const std::string& string,
41 int32_t* buffer,
42 size_t* position,
43 std::vector<std::string>& strings) {
44 if (string.empty()) {
46 } else {
47 buffer[(*position)++] = strings.size();
48 strings.push_back(string);
49 }
50}
51
52int64_t flagsToInt64(flutter::SemanticsFlags flags) {
53 int64_t result = 0;
55 result |= (INT64_C(1) << 0);
56 }
58 result |= (INT64_C(1) << 1);
59 }
61 result |= (INT64_C(1) << 2);
62 }
63 if (flags.isButton) {
64 result |= (INT64_C(1) << 3);
65 }
66 if (flags.isTextField) {
67 result |= (INT64_C(1) << 4);
68 }
70 result |= (INT64_C(1) << 5);
71 }
73 result |= (INT64_C(1) << 6);
74 }
76 result |= (INT64_C(1) << 7);
77 }
79 result |= (INT64_C(1) << 8);
80 }
81 if (flags.isHeader) {
82 result |= (INT64_C(1) << 9);
83 }
84 if (flags.isObscured) {
85 result |= (INT64_C(1) << 10);
86 }
87 if (flags.scopesRoute) {
88 result |= (INT64_C(1) << 11);
89 }
90 if (flags.namesRoute) {
91 result |= (INT64_C(1) << 12);
92 }
93 if (flags.isHidden) {
94 result |= (INT64_C(1) << 13);
95 }
96 if (flags.isImage) {
97 result |= (INT64_C(1) << 14);
98 }
99 if (flags.isLiveRegion) {
100 result |= (INT64_C(1) << 15);
101 }
103 result |= (INT64_C(1) << 16);
104 }
106 result |= (INT64_C(1) << 17);
107 }
108 if (flags.hasImplicitScrolling) {
109 result |= (INT64_C(1) << 18);
110 }
111 if (flags.isMultiline) {
112 result |= (INT64_C(1) << 19);
113 }
114 if (flags.isReadOnly) {
115 result |= (INT64_C(1) << 20);
116 }
118 result |= (INT64_C(1) << 21);
119 }
120 if (flags.isLink) {
121 result |= (INT64_C(1) << 22);
122 }
123 if (flags.isSlider) {
124 result |= (INT64_C(1) << 23);
125 }
126 if (flags.isKeyboardKey) {
127 result |= (INT64_C(1) << 24);
128 }
130 result |= (INT64_C(1) << 25);
131 }
133 result |= (INT64_C(1) << 26);
134 }
136 result |= (INT64_C(1) << 27);
137 }
139 result |= (INT64_C(1) << 28);
140 }
142 result |= (INT64_C(1) << 29);
143 }
145 result |= (INT64_C(1) << 30);
146 }
147 if (flags.isAccessibilityFocusBlocked) {
148 result |= (INT64_C(1) << 31);
149 }
150 return result;
151}
152} // namespace
153
155 std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
156 : jni_facade_(std::move(jni_facade)) {};
157
159 const flutter::SemanticsNodeUpdates& update,
161 {
162 size_t num_bytes = 0;
163 for (const auto& value : update) {
164 num_bytes += kBytesPerNode;
165 num_bytes +=
166 value.second.childrenInTraversalOrder.size() * kBytesPerChild;
167 num_bytes += value.second.childrenInHitTestOrder.size() * kBytesPerChild;
168 num_bytes += value.second.customAccessibilityActions.size() *
170 num_bytes +=
171 value.second.labelAttributes.size() * kBytesPerStringAttribute;
172 num_bytes +=
173 value.second.valueAttributes.size() * kBytesPerStringAttribute;
174 num_bytes += value.second.increasedValueAttributes.size() *
176 num_bytes += value.second.decreasedValueAttributes.size() *
178 num_bytes +=
179 value.second.hintAttributes.size() * kBytesPerStringAttribute;
180 }
181 // The encoding defined here is used in:
182 //
183 // * AccessibilityBridge.java
184 // * AccessibilityBridgeTest.java
185 // * accessibility_bridge.mm
186 //
187 // If any of the encoding structure or length is changed, those locations
188 // must be updated (at a minimum).
189 std::vector<uint8_t> buffer(num_bytes);
190 std::vector<std::string> strings;
191 std::vector<std::vector<uint8_t>> string_attribute_args;
192
193 if (!buffer.empty()) {
194 int32_t* buffer_int32 = reinterpret_cast<int32_t*>(buffer.data());
195 float* buffer_float32 = reinterpret_cast<float*>(buffer.data());
196
197 size_t position = 0;
198 for (const auto& value : update) {
199 // If you edit this code, make sure you update kBytesPerNode
200 // and/or kBytesPerChild above to match the number of values you are
201 // sending.
202 const flutter::SemanticsNode& node = value.second;
203 buffer_int32[position++] = node.id;
204 int64_t flags = flagsToInt64(node.flags);
205 std::memcpy(&buffer_int32[position], &flags, 8);
206 position += 2;
207 buffer_int32[position++] = node.actions;
208 buffer_int32[position++] = node.maxValueLength;
209 buffer_int32[position++] = node.currentValueLength;
210 buffer_int32[position++] = node.textSelectionBase;
211 buffer_int32[position++] = node.textSelectionExtent;
212 buffer_int32[position++] = node.platformViewId;
213 buffer_int32[position++] = node.scrollChildren;
214 buffer_int32[position++] = node.scrollIndex;
215 buffer_int32[position++] = node.traversalParent;
216 buffer_float32[position++] = static_cast<float>(node.scrollPosition);
217 buffer_float32[position++] = static_cast<float>(node.scrollExtentMax);
218 buffer_float32[position++] = static_cast<float>(node.scrollExtentMin);
219 buffer_int32[position++] = static_cast<int32_t>(node.role);
220
221 putStringIntoBuffer(node.identifier, buffer_int32, &position, strings);
222
223 putStringIntoBuffer(node.label, buffer_int32, &position, strings);
224 putStringAttributesIntoBuffer(node.labelAttributes, buffer_int32,
225 &position, string_attribute_args);
226
227 putStringIntoBuffer(node.value, buffer_int32, &position, strings);
228 putStringAttributesIntoBuffer(node.valueAttributes, buffer_int32,
229 &position, string_attribute_args);
230
231 putStringIntoBuffer(node.increasedValue, buffer_int32, &position,
232 strings);
233 putStringAttributesIntoBuffer(node.increasedValueAttributes,
234 buffer_int32, &position,
235 string_attribute_args);
236
237 putStringIntoBuffer(node.decreasedValue, buffer_int32, &position,
238 strings);
239 putStringAttributesIntoBuffer(node.decreasedValueAttributes,
240 buffer_int32, &position,
241 string_attribute_args);
242
243 putStringIntoBuffer(node.hint, buffer_int32, &position, strings);
244 putStringAttributesIntoBuffer(node.hintAttributes, buffer_int32,
245 &position, string_attribute_args);
246
247 putStringIntoBuffer(node.tooltip, buffer_int32, &position, strings);
248 putStringIntoBuffer(node.linkUrl, buffer_int32, &position, strings);
249 putStringIntoBuffer(node.locale, buffer_int32, &position, strings);
250 putStringIntoBuffer(node.minValue, buffer_int32, &position, strings);
251 putStringIntoBuffer(node.maxValue, buffer_int32, &position, strings);
252
253 buffer_int32[position++] = node.headingLevel;
254 buffer_int32[position++] = node.textDirection;
255 buffer_float32[position++] = node.rect.left();
256 buffer_float32[position++] = node.rect.top();
257 buffer_float32[position++] = node.rect.right();
258 buffer_float32[position++] = node.rect.bottom();
259 node.transform.getColMajor(&buffer_float32[position]);
260 position += 16;
261 node.hitTestTransform.getColMajor(&buffer_float32[position]);
262 position += 16;
263 buffer_int32[position++] = node.childrenInTraversalOrder.size();
264 for (int32_t child : node.childrenInTraversalOrder) {
265 buffer_int32[position++] = child;
266 }
267
268 buffer_int32[position++] = node.childrenInHitTestOrder.size();
269 for (int32_t child : node.childrenInHitTestOrder) {
270 buffer_int32[position++] = child;
271 }
272
273 buffer_int32[position++] = node.customAccessibilityActions.size();
274 for (int32_t child : node.customAccessibilityActions) {
275 buffer_int32[position++] = child;
276 }
277 }
278 }
279
280 // custom accessibility actions.
281 size_t num_action_bytes = actions.size() * kBytesPerAction;
282 std::vector<uint8_t> actions_buffer(num_action_bytes);
283
284 if (!actions_buffer.empty()) {
285 int32_t* actions_buffer_int32 =
286 reinterpret_cast<int32_t*>(actions_buffer.data());
287
288 std::vector<std::string> action_strings;
289 size_t actions_position = 0;
290 for (const auto& value : actions) {
291 // If you edit this code, make sure you update kBytesPerAction
292 // to match the number of values you are
293 // sending.
295 actions_buffer_int32[actions_position++] = action.id;
296 actions_buffer_int32[actions_position++] = action.overrideId;
297 putStringIntoBuffer(action.label, actions_buffer_int32,
298 &actions_position, action_strings);
299 putStringIntoBuffer(action.hint, actions_buffer_int32,
300 &actions_position, action_strings);
301 }
302 // Calling NewDirectByteBuffer in API level 22 and below with a size of
303 // zero will cause a JNI crash.
304 jni_facade_->FlutterViewUpdateCustomAccessibilityActions(actions_buffer,
305 action_strings);
306 }
307
308 if (!buffer.empty()) {
309 jni_facade_->FlutterViewUpdateSemantics(buffer, strings,
310 string_attribute_args);
311 }
312 }
313}
314
315} // namespace flutter
void UpdateSemantics(const flutter::SemanticsNodeUpdates &update, const flutter::CustomAccessibilityActionUpdates &actions)
PlatformViewAndroidDelegate(std::shared_ptr< PlatformViewAndroidJNI > jni_facade)
int32_t value
std::unordered_map< int32_t, SemanticsNode > SemanticsNodeUpdates
std::unordered_map< int32_t, CustomAccessibilityAction > CustomAccessibilityActionUpdates
std::vector< StringAttributePtr > StringAttributes
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set profile Make the profiler discard new samples once the profiler sample buffer is full When this flag is not the profiler sample buffer is used as a ring buffer
Definition switch_defs.h:98
Definition ref_ptr.h:261
SemanticsTristate isExpanded
SemanticsCheckState isChecked
SemanticsTristate isRequired
SemanticsTristate isFocused
SemanticsTristate isSelected
SemanticsTristate isToggled
SemanticsTristate isEnabled
StringAttributes decreasedValueAttributes
StringAttributes hintAttributes
StringAttributes increasedValueAttributes
StringAttributes valueAttributes
StringAttributes labelAttributes
std::vector< int32_t > childrenInHitTestOrder
std::vector< int32_t > customAccessibilityActions
std::vector< int32_t > childrenInTraversalOrder