in stetho/src/main/java/com/facebook/stetho/inspector/elements/android/AccessibilityNodeInfoWrapper.java [258:311]
public static CharSequence getDescription(View view) {
AccessibilityNodeInfoCompat node = createNodeInfoFromView(view);
try {
CharSequence contentDescription = node.getContentDescription();
CharSequence nodeText = node.getText();
boolean hasNodeText = !TextUtils.isEmpty(nodeText);
boolean isEditText = view instanceof EditText;
// EditText's prioritize their own text content over a contentDescription
if (!TextUtils.isEmpty(contentDescription) && (!isEditText || !hasNodeText)) {
return contentDescription;
}
if (hasNodeText) {
return nodeText;
}
// If there are child views and no contentDescription the text of all non-focusable children,
// comma separated, becomes the description.
if (view instanceof ViewGroup) {
final StringBuilder concatChildDescription = new StringBuilder();
final String separator = ", ";
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0, count = viewGroup.getChildCount(); i < count; i++) {
final View child = viewGroup.getChildAt(i);
AccessibilityNodeInfoCompat childNodeInfo = AccessibilityNodeInfoCompat.obtain();
ViewCompat.onInitializeAccessibilityNodeInfo(child, childNodeInfo);
CharSequence childNodeDescription = null;
if (AccessibilityUtil.isSpeakingNode(childNodeInfo, child) &&
!AccessibilityUtil.isAccessibilityFocusable(childNodeInfo, child)) {
childNodeDescription = getDescription(child);
}
if (!TextUtils.isEmpty(childNodeDescription)) {
if (concatChildDescription.length() > 0) {
concatChildDescription.append(separator);
}
concatChildDescription.append(childNodeDescription);
}
childNodeInfo.recycle();
}
return concatChildDescription.length() > 0 ? concatChildDescription.toString() : null;
}
return null;
} finally {
node.recycle();
}
}