From 8f72ffcbfa18087d24b01a9f74f6d85e1f9760af Mon Sep 17 00:00:00 2001 From: yingleiw Date: Wed, 25 Nov 2020 12:14:32 -0800 Subject: [PATCH] setAccessibilityFocused for NumberPicker NumberPicker uses AccessibilityNodeProvider. When creating AccessibilityNodeInfo, the accessibility focus boolean property should be set. Otherwise, talkback doesn't think it is accessibility focused and won't speak the usage hint. Fix: b/170267520 Test: tested manully with talkback on. Unit test added. Change-Id: Icd280bce4a394ccff2a60314518109c07808338d --- core/java/android/widget/NumberPicker.java | 3 + .../src/android/widget/NumberPickerTest.java | 91 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 core/tests/coretests/src/android/widget/NumberPickerTest.java diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index 7c20472df3570..4f1c40a8d1c2e 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -2773,6 +2773,7 @@ public class NumberPicker extends LinearLayout { int left, int top, int right, int bottom) { AccessibilityNodeInfo info = mInputText.createAccessibilityNodeInfo(); info.setSource(NumberPicker.this, VIRTUAL_VIEW_ID_INPUT); + info.setAccessibilityFocused(mAccessibilityFocusedView == VIRTUAL_VIEW_ID_INPUT); if (mAccessibilityFocusedView != VIRTUAL_VIEW_ID_INPUT) { info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); } @@ -2802,6 +2803,7 @@ public class NumberPicker extends LinearLayout { info.setClickable(true); info.setLongClickable(true); info.setEnabled(NumberPicker.this.isEnabled()); + info.setAccessibilityFocused(mAccessibilityFocusedView == virtualViewId); Rect boundsInParent = mTempRect; boundsInParent.set(left, top, right, bottom); info.setVisibleToUser(isVisibleToUser(boundsInParent)); @@ -2843,6 +2845,7 @@ public class NumberPicker extends LinearLayout { info.setParent((View) getParentForAccessibility()); info.setEnabled(NumberPicker.this.isEnabled()); info.setScrollable(true); + info.setAccessibilityFocused(mAccessibilityFocusedView == View.NO_ID); final float applicationScale = getContext().getResources().getCompatibilityInfo().applicationScale; diff --git a/core/tests/coretests/src/android/widget/NumberPickerTest.java b/core/tests/coretests/src/android/widget/NumberPickerTest.java new file mode 100644 index 0000000000000..cab7c89f4ca15 --- /dev/null +++ b/core/tests/coretests/src/android/widget/NumberPickerTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.widget; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.platform.test.annotations.Presubmit; +import android.view.View; +import android.view.accessibility.AccessibilityNodeInfo; +import android.view.accessibility.AccessibilityNodeProvider; + +import androidx.test.filters.SmallTest; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +@Presubmit +public class NumberPickerTest { + @Test + public void testAccessibilityFocusedProperty() { + final int virtualViewIdIncrement = 1; + final int VirtualViewIdInput = 2; + final int VirtualViewIdDecrement = 3; + final NumberPicker np = + new NumberPicker(InstrumentationRegistry.getInstrumentation().getContext()); + final AccessibilityNodeProvider provider = np.getAccessibilityNodeProvider(); + + AccessibilityNodeInfo info = provider.createAccessibilityNodeInfo(View.NO_ID); + assertFalse(info.isAccessibilityFocused()); + info.recycle(); + provider.performAction(View.NO_ID, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); + info = provider.createAccessibilityNodeInfo(View.NO_ID); + assertTrue(info.isAccessibilityFocused()); + info.recycle(); + + info = provider.createAccessibilityNodeInfo(virtualViewIdIncrement); + assertFalse(info.isAccessibilityFocused()); + info.recycle(); + provider.performAction( + virtualViewIdIncrement, + AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, + null + ); + info = provider.createAccessibilityNodeInfo(virtualViewIdIncrement); + assertTrue(info.isAccessibilityFocused()); + info.recycle(); + + info = provider.createAccessibilityNodeInfo(VirtualViewIdInput); + assertFalse(info.isAccessibilityFocused()); + info.recycle(); + provider.performAction( + VirtualViewIdInput, + AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, + null + ); + info = provider.createAccessibilityNodeInfo(VirtualViewIdInput); + assertTrue(info.isAccessibilityFocused()); + info.recycle(); + + info = provider.createAccessibilityNodeInfo(VirtualViewIdDecrement); + assertFalse(info.isAccessibilityFocused()); + info.recycle(); + provider.performAction( + VirtualViewIdDecrement, + AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, + null + ); + info = provider.createAccessibilityNodeInfo(VirtualViewIdDecrement); + assertTrue(info.isAccessibilityFocused()); + info.recycle(); + } +}