summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt4
-rw-r--r--core/java/android/view/View.java37
-rw-r--r--core/java/android/view/ViewGroup.java8
-rw-r--r--core/java/android/view/ViewRootImpl.java3
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java1
-rw-r--r--core/java/android/widget/TextView.java21
-rw-r--r--core/tests/coretests/res/layout/interrogation_activity.xml1
-rw-r--r--core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java23
-rw-r--r--services/java/com/android/server/accessibility/AccessibilityManagerService.java10
9 files changed, 84 insertions, 24 deletions
diff --git a/api/current.txt b/api/current.txt
index 0b6c245..ce78f9e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22920,7 +22920,7 @@ package android.view {
method public android.view.View findFocus();
method public final android.view.View findViewById(int);
method public final android.view.View findViewWithTag(java.lang.Object);
- method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence);
+ method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence, int);
method protected boolean fitSystemWindows(android.graphics.Rect);
method public boolean fitsSystemWindows();
method public android.view.View focusSearch(int);
@@ -23249,6 +23249,8 @@ package android.view {
field protected static final int[] ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET;
field protected static final int[] ENABLED_STATE_SET;
field protected static final int[] ENABLED_WINDOW_FOCUSED_STATE_SET;
+ field public static final int FIND_VIEWS_WITH_CONTENT_DESCRIPTION = 2; // 0x2
+ field public static final int FIND_VIEWS_WITH_TEXT = 1; // 0x1
field public static final int FOCUSABLES_ALL = 0; // 0x0
field public static final int FOCUSABLES_TOUCH_MODE = 1; // 0x1
field protected static final int[] FOCUSED_SELECTED_STATE_SET;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 65e9857..ca06b9c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -45,6 +45,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.LocaleUtil;
@@ -1928,6 +1929,20 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF;
/**
+ * Find views that render the specified text.
+ *
+ * @see #findViewsWithText(ArrayList, CharSequence, int)
+ */
+ public static final int FIND_VIEWS_WITH_TEXT = 0x00000001;
+
+ /**
+ * Find find views that contain the specified content description.
+ *
+ * @see #findViewsWithText(ArrayList, CharSequence, int)
+ */
+ public static final int FIND_VIEWS_WITH_CONTENT_DESCRIPTION = 0x00000002;
+
+ /**
* Controls the over-scroll mode for this view.
* See {@link #overScrollBy(int, int, int, int, int, int, int, int, boolean)},
* {@link #OVER_SCROLL_ALWAYS}, {@link #OVER_SCROLL_IF_CONTENT_SCROLLS},
@@ -5132,12 +5147,28 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
/**
* Finds the Views that contain given text. The containment is case insensitive.
- * As View's text is considered any text content that View renders.
+ * The search is performed by either the text that the View renders or the content
+ * description that describes the view for accessibility purposes and the view does
+ * not render or both. Clients can specify how the search is to be performed via
+ * passing the {@link #FIND_VIEWS_WITH_TEXT} and
+ * {@link #FIND_VIEWS_WITH_CONTENT_DESCRIPTION} flags.
*
* @param outViews The output list of matching Views.
- * @param text The text to match against.
+ * @param searched The text to match against.
+ *
+ * @see #FIND_VIEWS_WITH_TEXT
+ * @see #FIND_VIEWS_WITH_CONTENT_DESCRIPTION
+ * @see #setContentDescription(CharSequence)
*/
- public void findViewsWithText(ArrayList<View> outViews, CharSequence text) {
+ public void findViewsWithText(ArrayList<View> outViews, CharSequence searched, int flags) {
+ if ((flags & FIND_VIEWS_WITH_CONTENT_DESCRIPTION) != 0 && !TextUtils.isEmpty(searched)
+ && !TextUtils.isEmpty(mContentDescription)) {
+ String searchedLowerCase = searched.toString().toLowerCase();
+ String contentDescriptionLowerCase = mContentDescription.toString().toLowerCase();
+ if (contentDescriptionLowerCase.contains(searchedLowerCase)) {
+ outViews.add(this);
+ }
+ }
}
/**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 1bd0782..c7b59b8 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -802,13 +802,15 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
@Override
- public void findViewsWithText(ArrayList<View> outViews, CharSequence text) {
+ public void findViewsWithText(ArrayList<View> outViews, CharSequence text, int flags) {
+ super.findViewsWithText(outViews, text, flags);
final int childrenCount = mChildrenCount;
final View[] children = mChildren;
for (int i = 0; i < childrenCount; i++) {
View child = children[i];
- if ((child.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) {
- child.findViewsWithText(outViews, text);
+ if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE
+ && (child.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) {
+ child.findViewsWithText(outViews, text, flags);
}
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 81f9d78..4611984 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -4661,7 +4661,8 @@ public final class ViewRootImpl extends Handler implements ViewParent,
return;
}
- root.findViewsWithText(foundViews, text);
+ root.findViewsWithText(foundViews, text, View.FIND_VIEWS_WITH_TEXT
+ | View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if (foundViews.isEmpty()) {
return;
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index f0e8005..7671312 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -261,6 +261,7 @@ public class AccessibilityNodeInfo implements Parcelable {
* Finds {@link AccessibilityNodeInfo}s by text. The match is case
* insensitive containment. The search is relative to this info i.e.
* this info is the root of the traversed tree.
+ *
* <p>
* <strong>Note:</strong> It is a client responsibility to recycle the
* received info by calling {@link AccessibilityNodeInfo#recycle()}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index edb1bfc..d78a7a3 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8677,18 +8677,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
@Override
- public void findViewsWithText(ArrayList<View> outViews, CharSequence searched) {
- if (TextUtils.isEmpty(searched)) {
- return;
- }
- CharSequence thisText = getText();
- if (TextUtils.isEmpty(thisText)) {
- return;
- }
- String searchedLowerCase = searched.toString().toLowerCase();
- String thisTextLowerCase = thisText.toString().toLowerCase();
- if (thisTextLowerCase.contains(searchedLowerCase)) {
- outViews.add(this);
+ public void findViewsWithText(ArrayList<View> outViews, CharSequence searched, int flags) {
+ super.findViewsWithText(outViews, searched, flags);
+ if (!outViews.contains(this) && (flags & FIND_VIEWS_WITH_TEXT) != 0
+ && !TextUtils.isEmpty(searched) && !TextUtils.isEmpty(mText)) {
+ String searchedLowerCase = searched.toString().toLowerCase();
+ String textLowerCase = mText.toString().toLowerCase();
+ if (textLowerCase.contains(searchedLowerCase)) {
+ outViews.add(this);
+ }
}
}
diff --git a/core/tests/coretests/res/layout/interrogation_activity.xml b/core/tests/coretests/res/layout/interrogation_activity.xml
index 44ed75c..64af321 100644
--- a/core/tests/coretests/res/layout/interrogation_activity.xml
+++ b/core/tests/coretests/res/layout/interrogation_activity.xml
@@ -70,6 +70,7 @@
android:layout_width="160px"
android:layout_height="100px"
android:text="@string/button6"
+ android:contentDescription="contentDescription"
/>
</LinearLayout>
diff --git a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
index a542a1b..cd8dcb9 100644
--- a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
+++ b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
@@ -148,6 +148,29 @@ public class InterrogationActivityTest
}
@LargeTest
+ public void testFindAccessibilityNodeInfoByViewTextContentDescription() throws Exception {
+ beforeClassIfNeeded();
+ final long startTimeMillis = SystemClock.uptimeMillis();
+ try {
+ // bring up the activity
+ getActivity();
+
+ // find a view by text
+ List<AccessibilityNodeInfo> buttons = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfosByViewTextInActiveWindow(getConnection(),
+ "contentDescription");
+ assertEquals(1, buttons.size());
+ } finally {
+ afterClassIfNeeded();
+ if (DEBUG) {
+ final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
+ Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewTextContentDescription: "
+ + elapsedTimeMillis + "ms");
+ }
+ }
+ }
+
+ @LargeTest
public void testTraverseAllViews() throws Exception {
beforeClassIfNeeded();
final long startTimeMillis = SystemClock.uptimeMillis();
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 10d384b..6830055 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -489,14 +489,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
if (oldService != null) {
tryRemoveServiceLocked(oldService);
}
+ // Now this service is enabled.
+ mEnabledServices.add(componentName);
+ // Also make sure this service is the only one.
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ componentName.flattenToString());
// This API is intended for testing so enable accessibility to make
// sure clients can start poking with the window content.
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 1);
- // Also disable all accessibility services to avoid interference
- // with the tests.
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "");
}
AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
accessibilityServiceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;