Skip to content

Commit

Permalink
a11y: expose max character count for text fields (flutter#12269)
Browse files Browse the repository at this point in the history
  • Loading branch information
goderbauer authored Sep 16, 2019
1 parent 3b6c08d commit ef7bcaf
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 2 deletions.
15 changes: 14 additions & 1 deletion lib/ui/semantics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -618,9 +618,16 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass2 {
/// string describes what result an action performed on this node has. The
/// reading direction of all these strings is given by `textDirection`.
///
/// The fields 'textSelectionBase' and 'textSelectionExtent' describe the
/// The fields `textSelectionBase` and `textSelectionExtent` describe the
/// currently selected text within `value`.
///
/// The field `maxValueLength` is used to indicate that an editable text field
/// has a limit on the number of characters entered. If it is -1 there is
/// no limit on the number of characters entered. The field
/// `currentValueLength` indicates how much of that limit has already been
/// used up. When `maxValueLength` is set, `currentValueLength` must also be
/// set.
///
/// The field `platformViewId` references the platform view, whose semantics
/// nodes will be added as children to this node. If a platform view is
/// specified, `childrenInHitTestOrder` and `childrenInTraversalOrder` must be
Expand Down Expand Up @@ -652,6 +659,8 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass2 {
int id,
int flags,
int actions,
int maxValueLength,
int currentValueLength,
int textSelectionBase,
int textSelectionExtent,
int platformViewId,
Expand Down Expand Up @@ -683,6 +692,8 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass2 {
id,
flags,
actions,
maxValueLength,
currentValueLength,
textSelectionBase,
textSelectionExtent,
platformViewId,
Expand Down Expand Up @@ -713,6 +724,8 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass2 {
int id,
int flags,
int actions,
int maxValueLength,
int currentValueLength,
int textSelectionBase,
int textSelectionExtent,
int platformViewId,
Expand Down
2 changes: 2 additions & 0 deletions lib/ui/semantics/semantics_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ struct SemanticsNode {
int32_t id = 0;
int32_t flags = 0;
int32_t actions = 0;
int32_t maxValueLength = -1;
int32_t currentValueLength = -1;
int32_t textSelectionBase = -1;
int32_t textSelectionExtent = -1;
int32_t platformViewId = -1;
Expand Down
4 changes: 4 additions & 0 deletions lib/ui/semantics/semantics_update_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ void SemanticsUpdateBuilder::updateNode(
int id,
int flags,
int actions,
int maxValueLength,
int currentValueLength,
int textSelectionBase,
int textSelectionExtent,
int platformViewId,
Expand Down Expand Up @@ -74,6 +76,8 @@ void SemanticsUpdateBuilder::updateNode(
node.id = id;
node.flags = flags;
node.actions = actions;
node.maxValueLength = maxValueLength;
node.currentValueLength = currentValueLength;
node.textSelectionBase = textSelectionBase;
node.textSelectionExtent = textSelectionExtent;
node.platformViewId = platformViewId;
Expand Down
2 changes: 2 additions & 0 deletions lib/ui/semantics/semantics_update_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class SemanticsUpdateBuilder
void updateNode(int id,
int flags,
int actions,
int maxValueLength,
int currentValueLength,
int textSelectionBase,
int textSelectionExtent,
int platformViewId,
Expand Down
8 changes: 8 additions & 0 deletions lib/web_ui/lib/src/engine/semantics/semantics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class SemanticsNodeUpdate {
this.id,
this.flags,
this.actions,
this.maxValueLength,
this.currentValueLength,
this.textSelectionBase,
this.textSelectionExtent,
this.platformViewId,
Expand Down Expand Up @@ -67,6 +69,12 @@ class SemanticsNodeUpdate {
/// See [ui.SemanticsUpdateBuilder.updateNode].
final int actions;

/// See [ui.SemanticsUpdateBuilder.updateNode].
final int maxValueLength;

/// See [ui.SemanticsUpdateBuilder.updateNode].
final int currentValueLength;

/// See [ui.SemanticsUpdateBuilder.updateNode].
final int textSelectionBase;

Expand Down
4 changes: 4 additions & 0 deletions lib/web_ui/lib/src/ui/semantics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,8 @@ class SemanticsUpdateBuilder {
int id,
int flags,
int actions,
int maxValueLength,
int currentValueLength,
int textSelectionBase,
int textSelectionExtent,
int platformViewId,
Expand Down Expand Up @@ -676,6 +678,8 @@ class SemanticsUpdateBuilder {
id: id,
flags: flags,
actions: actions,
maxValueLength: maxValueLength,
currentValueLength: currentValueLength,
textSelectionBase: textSelectionBase,
textSelectionExtent: textSelectionExtent,
scrollChildren: scrollChildren,
Expand Down
12 changes: 12 additions & 0 deletions shell/platform/android/io/flutter/view/AccessibilityBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,14 @@ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) {
granularities |= AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD;
}
result.setMovementGranularities(granularities);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && semanticsNode.maxValueLength >= 0) {
// Account for the fact that Flutter is counting Unicode scalar values and Android
// is counting UTF16 words.
final int length = semanticsNode.value == null ? 0 : semanticsNode.value.length();
int a = length - semanticsNode.currentValueLength + semanticsNode.maxValueLength;
result.setMaxTextLength(length - semanticsNode.currentValueLength + semanticsNode.maxValueLength);
}

}

// These are non-ops on older devices. Attempting to interact with the text will cause Talkback to read the
Expand Down Expand Up @@ -1719,6 +1727,8 @@ private static boolean nullableHasAncestor(SemanticsNode target, Predicate<Seman

private int flags;
private int actions;
private int maxValueLength;
private int currentValueLength;
private int textSelectionBase;
private int textSelectionExtent;
private int platformViewId;
Expand Down Expand Up @@ -1858,6 +1868,8 @@ private void updateWith(@NonNull ByteBuffer buffer, @NonNull String[] strings) {

flags = buffer.getInt();
actions = buffer.getInt();
maxValueLength = buffer.getInt();
currentValueLength = buffer.getInt();
textSelectionBase = buffer.getInt();
textSelectionExtent = buffer.getInt();
platformViewId = buffer.getInt();
Expand Down
4 changes: 3 additions & 1 deletion shell/platform/android/platform_view_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ void PlatformViewAndroid::DispatchSemanticsAction(JNIEnv* env,
void PlatformViewAndroid::UpdateSemantics(
flutter::SemanticsNodeUpdates update,
flutter::CustomAccessibilityActionUpdates actions) {
constexpr size_t kBytesPerNode = 39 * sizeof(int32_t);
constexpr size_t kBytesPerNode = 41 * sizeof(int32_t);
constexpr size_t kBytesPerChild = sizeof(int32_t);
constexpr size_t kBytesPerAction = 4 * sizeof(int32_t);

Expand Down Expand Up @@ -261,6 +261,8 @@ void PlatformViewAndroid::UpdateSemantics(
buffer_int32[position++] = node.id;
buffer_int32[position++] = node.flags;
buffer_int32[position++] = node.actions;
buffer_int32[position++] = node.maxValueLength;
buffer_int32[position++] = node.currentValueLength;
buffer_int32[position++] = node.textSelectionBase;
buffer_int32[position++] = node.textSelectionExtent;
buffer_int32[position++] = node.platformViewId;
Expand Down

0 comments on commit ef7bcaf

Please sign in to comment.