From a1c002128b98e38dac232e79b405ebe49d740a96 Mon Sep 17 00:00:00 2001 From: chunhtai <47866232+chunhtai@users.noreply.github.com> Date: Fri, 28 Oct 2022 11:07:04 -0700 Subject: [PATCH] Reland fixes Android text field to use hint text for accessibility (flutter/engine#37093) --- .../io/flutter/view/AccessibilityBridge.java | 52 +++++++++++++++---- .../flutter/view/AccessibilityBridgeTest.java | 8 ++- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/engine/src/flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java b/engine/src/flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java index ba0d9045599..4840e1b72a5 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java @@ -885,7 +885,10 @@ public class AccessibilityBridge extends AccessibilityNodeProvider { // Scopes routes are not focusable, only need to set the content // for non-scopes-routes semantics nodes. if (semanticsNode.hasFlag(Flag.IS_TEXT_FIELD)) { - result.setText(semanticsNode.getValueLabelHint()); + result.setText(semanticsNode.getValue()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + result.setHintText(semanticsNode.getTextFieldHint()); + } } else if (!semanticsNode.hasFlag(Flag.SCOPES_ROUTE)) { CharSequence content = semanticsNode.getValueLabelHint(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { @@ -2773,18 +2776,47 @@ public class AccessibilityBridge extends AccessibilityNodeProvider { return Math.max(a, Math.max(b, Math.max(c, d))); } - private CharSequence getValueLabelHint() { - CharSequence[] array; + private CharSequence getValue() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - array = new CharSequence[] {value, label, hint}; + return value; } else { - array = - new CharSequence[] { - createSpannableString(value, valueAttributes), - createSpannableString(label, labelAttributes), - createSpannableString(hint, hintAttributes), - }; + return createSpannableString(value, valueAttributes); } + } + + private CharSequence getLabel() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + return label; + } else { + return createSpannableString(label, labelAttributes); + } + } + + private CharSequence getHint() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + return hint; + } else { + return createSpannableString(hint, hintAttributes); + } + } + + private CharSequence getValueLabelHint() { + CharSequence[] array = new CharSequence[] {getValue(), getLabel(), getHint()}; + CharSequence result = null; + for (CharSequence word : array) { + if (word != null && word.length() > 0) { + if (result == null || result.length() == 0) { + result = word; + } else { + result = TextUtils.concat(result, ", ", word); + } + } + } + return result; + } + + private CharSequence getTextFieldHint() { + CharSequence[] array = new CharSequence[] {getLabel(), getHint()}; CharSequence result = null; for (CharSequence word : array) { if (word != null && word.length() > 0) { diff --git a/engine/src/flutter/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java b/engine/src/flutter/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java index a88c0323a7b..d5e165bd016 100644 --- a/engine/src/flutter/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java +++ b/engine/src/flutter/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java @@ -76,12 +76,15 @@ public class AccessibilityBridgeTest { assertEquals(nodeInfo.getText(), null); } + @TargetApi(26) @Test - public void itDescribesTextFieldsWithText() { + public void itDescribesTextFieldsWithTextAndHint() { AccessibilityBridge accessibilityBridge = setUpBridge(); TestSemanticsNode testSemanticsNode = new TestSemanticsNode(); - testSemanticsNode.label = "Hello, World"; + testSemanticsNode.value = "Hello, World"; + testSemanticsNode.label = "some label"; + testSemanticsNode.hint = "some hint"; testSemanticsNode.addFlag(AccessibilityBridge.Flag.IS_TEXT_FIELD); TestSemanticsUpdate testSemanticsUpdate = testSemanticsNode.toUpdate(); testSemanticsUpdate.sendUpdateToBridge(accessibilityBridge); @@ -89,6 +92,7 @@ public class AccessibilityBridgeTest { assertEquals(nodeInfo.getContentDescription(), null); assertEquals(nodeInfo.getText().toString(), "Hello, World"); + assertEquals(nodeInfo.getHintText().toString(), "some label, some hint"); } @Test