diff options
| author | Dianne Hackborn <hackbod@google.com> | 2015-04-01 16:45:03 -0700 |
|---|---|---|
| committer | Dianne Hackborn <hackbod@google.com> | 2015-04-01 17:08:27 -0700 |
| commit | 6251f0d42be7da54d7f1bc8f570a44883b7d9052 (patch) | |
| tree | d7e928e1d55745a3ff4771c546678e4b27fc6d1b /core/java/android/view | |
| parent | 6cedefa2e4a10724982a72e22abc349c7578902d (diff) | |
| download | frameworks_base-6251f0d42be7da54d7f1bc8f570a44883b7d9052.zip frameworks_base-6251f0d42be7da54d7f1bc8f570a44883b7d9052.tar.gz frameworks_base-6251f0d42be7da54d7f1bc8f570a44883b7d9052.tar.bz2 | |
Rework assist to walk down the view hierarchy.
Instead of collecting all of the data directly in AssistStructure,
we now have a dispatch mechanism down the hierarchy to do so.
While doing this, also added the ability to automatically collect
assist data from AccessibilityNodeProviders attached to views
(so now we see all of the data in for example Calendar).
This is a first step needed towards being able to asynchronously
populate assist data.
Change-Id: I59ee1ea104ca8207bad8df7a38195d93da1adea7
Diffstat (limited to 'core/java/android/view')
| -rw-r--r-- | core/java/android/view/View.java | 140 | ||||
| -rw-r--r-- | core/java/android/view/ViewAssistStructure.java | 43 | ||||
| -rw-r--r-- | core/java/android/view/ViewGroup.java | 27 |
3 files changed, 207 insertions, 3 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index a69384a..c0e253b 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -91,6 +91,7 @@ import android.view.animation.Transformation; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; +import android.widget.Checkable; import android.widget.ScrollBarDrawable; import static android.os.Build.VERSION_CODES.*; @@ -5676,10 +5677,143 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Called when assist structure is being retrieved from a view as part of * {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData}. - * @param structure Additional standard structured view structure to supply. - * @param extras Non-standard extensions. + * @param structure Fill in with structured view data. The default implementation + * fills in all data that can be inferred from the view itself. + */ + public void onProvideAssistStructure(ViewAssistStructure structure) { + final int id = mID; + if (id > 0 && (id&0xff000000) != 0 && (id&0x00ff0000) != 0 + && (id&0x0000ffff) != 0) { + String pkg, type, entry; + try { + final Resources res = getResources(); + entry = res.getResourceEntryName(id); + type = res.getResourceTypeName(id); + pkg = res.getResourcePackageName(id); + } catch (Resources.NotFoundException e) { + entry = type = pkg = null; + } + structure.setId(id, pkg, type, entry); + } else { + structure.setId(id, null, null, null); + } + structure.setDimens(mLeft, mTop, mScrollX, mScrollY, mRight-mLeft, mBottom-mTop); + structure.setVisibility(getVisibility()); + structure.setEnabled(isEnabled()); + if (isClickable()) { + structure.setClickable(true); + } + if (isFocusable()) { + structure.setFocusable(true); + } + if (isFocused()) { + structure.setFocused(true); + } + if (isAccessibilityFocused()) { + structure.setAccessibilityFocused(true); + } + if (isSelected()) { + structure.setSelected(true); + } + if (isActivated()) { + structure.setActivated(true); + } + if (isLongClickable()) { + structure.setLongClickable(true); + } + if (this instanceof Checkable) { + structure.setCheckable(true); + if (((Checkable)this).isChecked()) { + structure.setChecked(true); + } + } + structure.setClassName(getAccessibilityClassName().toString()); + structure.setContentDescription(getContentDescription()); + } + + /** + * Called when assist structure is being retrieved from a view as part of + * {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData} to + * generate additional virtual structure under this view. The defaullt implementation + * uses {@link #getAccessibilityNodeProvider()} to try to generate this from the + * view's virtual accessibility nodes, if any. You can override this for a more + * optimal implementation providing this data. + */ + public void onProvideVirtualAssistStructure(ViewAssistStructure structure) { + AccessibilityNodeProvider provider = getAccessibilityNodeProvider(); + if (provider != null) { + AccessibilityNodeInfo info = createAccessibilityNodeInfo(); + Log.i("View", "Provider of " + this + ": children=" + info.getChildCount()); + structure.setChildCount(1); + ViewAssistStructure root = structure.newChild(0); + populateVirtualAssistStructure(root, provider, info); + info.recycle(); + } + } + + private void populateVirtualAssistStructure(ViewAssistStructure structure, + AccessibilityNodeProvider provider, AccessibilityNodeInfo info) { + structure.setId(AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()), + null, null, null); + Rect rect = structure.getTempRect(); + info.getBoundsInParent(rect); + structure.setDimens(rect.left, rect.top, 0, 0, rect.width(), rect.height()); + structure.setVisibility(VISIBLE); + structure.setEnabled(info.isEnabled()); + if (info.isClickable()) { + structure.setClickable(true); + } + if (info.isFocusable()) { + structure.setFocusable(true); + } + if (info.isFocused()) { + structure.setFocused(true); + } + if (info.isAccessibilityFocused()) { + structure.setAccessibilityFocused(true); + } + if (info.isSelected()) { + structure.setSelected(true); + } + if (info.isLongClickable()) { + structure.setLongClickable(true); + } + if (info.isCheckable()) { + structure.setCheckable(true); + if (info.isChecked()) { + structure.setChecked(true); + } + } + CharSequence cname = info.getClassName(); + structure.setClassName(cname != null ? cname.toString() : null); + structure.setContentDescription(info.getContentDescription()); + Log.i("View", "vassist " + cname + " @ " + rect.toShortString() + + " text=" + info.getText() + " cd=" + info.getContentDescription()); + if (info.getText() != null || info.getError() != null) { + structure.setText(info.getText(), info.getTextSelectionStart(), + info.getTextSelectionEnd()); + } + final int NCHILDREN = info.getChildCount(); + if (NCHILDREN > 0) { + structure.setChildCount(NCHILDREN); + for (int i=0; i<NCHILDREN; i++) { + AccessibilityNodeInfo cinfo = provider.createAccessibilityNodeInfo( + AccessibilityNodeInfo.getVirtualDescendantId(info.getChildId(i))); + ViewAssistStructure child = structure.newChild(i); + populateVirtualAssistStructure(child, provider, cinfo); + cinfo.recycle(); + } + } + } + + /** + * Dispatch creation of {@link ViewAssistStructure} down the hierarchy. The default + * implementation calls {@link #onProvideAssistStructure} and + * {@link #onProvideVirtualAssistStructure}. */ - public void onProvideAssistStructure(ViewAssistStructure structure, Bundle extras) { + public void dispatchProvideAssistStructure(ViewAssistStructure structure) { + onProvideAssistStructure(structure); + onProvideVirtualAssistStructure(structure); } /** diff --git a/core/java/android/view/ViewAssistStructure.java b/core/java/android/view/ViewAssistStructure.java index 5132bb9..c05ed6f 100644 --- a/core/java/android/view/ViewAssistStructure.java +++ b/core/java/android/view/ViewAssistStructure.java @@ -16,6 +16,8 @@ package android.view; +import android.graphics.Rect; +import android.os.Bundle; import android.text.TextPaint; /** @@ -23,6 +25,37 @@ import android.text.TextPaint; * View.onProvideAssistStructure}. */ public abstract class ViewAssistStructure { + public abstract void setId(int id, String packageName, String typeName, String entryName); + + public abstract void setDimens(int left, int top, int scrollX, int scrollY, int width, + int height); + + public abstract void setVisibility(int visibility); + + public abstract void setEnabled(boolean state); + + public abstract void setClickable(boolean state); + + public abstract void setLongClickable(boolean state); + + public abstract void setFocusable(boolean state); + + public abstract void setFocused(boolean state); + + public abstract void setAccessibilityFocused(boolean state); + + public abstract void setCheckable(boolean state); + + public abstract void setChecked(boolean state); + + public abstract void setSelected(boolean state); + + public abstract void setActivated(boolean state); + + public abstract void setClassName(String className); + + public abstract void setContentDescription(CharSequence contentDescription); + public abstract void setText(CharSequence text); public abstract void setText(CharSequence text, int selectionStart, int selectionEnd); public abstract void setTextPaint(TextPaint paint); @@ -32,4 +65,14 @@ public abstract class ViewAssistStructure { public abstract int getTextSelectionStart(); public abstract int getTextSelectionEnd(); public abstract CharSequence getHint(); + + public abstract Bundle editExtras(); + public abstract void clearExtras(); + + public abstract void setChildCount(int num); + public abstract int getChildCount(); + public abstract ViewAssistStructure newChild(int index); + + /** @hide */ + public abstract Rect getTempRect(); } diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 87f3e94..7a84bb0 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -2852,6 +2852,33 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return false; } + /** + * Dispatch creation of {@link ViewAssistStructure} down the hierarchy. This implementation + * adds in all child views of the view group, in addition to calling the default View + * implementation. + */ + public void dispatchProvideAssistStructure(ViewAssistStructure structure) { + super.dispatchProvideAssistStructure(structure); + if (structure.getChildCount() == 0) { + final int childrenCount = getChildCount(); + if (childrenCount > 0) { + structure.setChildCount(childrenCount); + final ArrayList<View> preorderedList = buildOrderedChildList(); + final boolean customOrder = preorderedList == null + && isChildrenDrawingOrderEnabled(); + final View[] children = mChildren; + for (int i=0; i<childrenCount; i++) { + final int childIndex = customOrder + ? getChildDrawingOrder(childrenCount, i) : i; + final View child = (preorderedList == null) + ? children[childIndex] : preorderedList.get(childIndex); + ViewAssistStructure cstructure = structure.newChild(i); + child.dispatchProvideAssistStructure(cstructure); + } + } + } + } + /** @hide */ @Override public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { |
