OSDN Git Service

Add semantics for accessibility headings
authorPhil Weaver <pweaver@google.com>
Tue, 9 Jan 2018 01:42:18 +0000 (17:42 -0800)
committerPhil Weaver <pweaver@google.com>
Thu, 18 Jan 2018 22:13:06 +0000 (14:13 -0800)
Adding the ability to mark TextView as a heading, and
to provide a heading depth. Plumbing that through to
accessibility services.

Bug: 34687453
Test: Adding CTS tests for new APIs.
Change-Id: I5262e32a2a11b2577802c68e701d2856e28abc21

api/current.txt
core/java/android/view/accessibility/AccessibilityNodeInfo.java
core/java/android/widget/TextView.java
core/res/res/values/attrs.xml
core/res/res/values/public.xml

index 5e8d144..1fadca5 100644 (file)
@@ -211,6 +211,7 @@ package android {
     field public static final int accessibilityEventTypes = 16843648; // 0x1010380
     field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
     field public static final int accessibilityFlags = 16843652; // 0x1010384
+    field public static final int accessibilityHeading = 16844160; // 0x1010580
     field public static final int accessibilityLiveRegion = 16843758; // 0x10103ee
     field public static final int accessibilityPaneTitle = 16844156; // 0x101057c
     field public static final int accessibilityTraversalAfter = 16843986; // 0x10104d2
@@ -48205,6 +48206,7 @@ package android.view.accessibility {
     method public boolean isEnabled();
     method public boolean isFocusable();
     method public boolean isFocused();
+    method public boolean isHeading();
     method public boolean isImportantForAccessibility();
     method public boolean isLongClickable();
     method public boolean isMultiLine();
@@ -48248,6 +48250,7 @@ package android.view.accessibility {
     method public void setError(java.lang.CharSequence);
     method public void setFocusable(boolean);
     method public void setFocused(boolean);
+    method public void setHeading(boolean);
     method public void setHintText(java.lang.CharSequence);
     method public void setImportantForAccessibility(boolean);
     method public void setInputType(int);
@@ -48381,7 +48384,7 @@ package android.view.accessibility {
     method public int getColumnSpan();
     method public int getRowIndex();
     method public int getRowSpan();
-    method public boolean isHeading();
+    method public deprecated boolean isHeading();
     method public boolean isSelected();
     method public static android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo obtain(int, int, int, int, boolean);
     method public static android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo obtain(int, int, int, int, boolean, boolean);
@@ -52606,6 +52609,7 @@ package android.widget {
     method public android.graphics.Typeface getTypeface();
     method public android.text.style.URLSpan[] getUrls();
     method public boolean hasSelection();
+    method public boolean isAccessibilityHeading();
     method public boolean isAllCaps();
     method public boolean isCursorVisible();
     method public boolean isElegantTextHeight();
@@ -52628,6 +52632,7 @@ package android.widget {
     method protected void onTextChanged(java.lang.CharSequence, int, int, int);
     method public boolean onTextContextMenuItem(int);
     method public void removeTextChangedListener(android.text.TextWatcher);
+    method public void setAccessibilityHeading(boolean);
     method public void setAllCaps(boolean);
     method public final void setAutoLinkMask(int);
     method public void setAutoSizeTextTypeUniformWithConfiguration(int, int, int, int);
index 311dd4b..3ee282e 100644 (file)
@@ -639,6 +639,8 @@ public class AccessibilityNodeInfo implements Parcelable {
 
     private static final int BOOLEAN_PROPERTY_IS_SHOWING_HINT = 0x0100000;
 
+    private static final int BOOLEAN_PROPERTY_IS_HEADING = 0x0200000;
+
     /**
      * Bits that provide the id of a virtual descendant of a view.
      */
@@ -2409,6 +2411,30 @@ public class AccessibilityNodeInfo implements Parcelable {
     }
 
     /**
+     * Returns whether node represents a heading.
+     *
+     * @return {@code true} if the node is a heading, {@code false} otherwise.
+     */
+    public boolean isHeading() {
+        return getBooleanProperty(BOOLEAN_PROPERTY_IS_HEADING);
+    }
+
+    /**
+     * Sets whether the node represents a heading.
+     *
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param isHeading {@code true} if the node is a heading, {@code false} otherwise.
+     */
+    public void setHeading(boolean isHeading) {
+        setBooleanProperty(BOOLEAN_PROPERTY_IS_HEADING, isHeading);
+    }
+
+    /**
      * Gets the package this node comes from.
      *
      * @return The package name.
@@ -4597,7 +4623,8 @@ public class AccessibilityNodeInfo implements Parcelable {
          * @param rowSpan The number of rows the item spans.
          * @param columnIndex The column index at which the item is located.
          * @param columnSpan The number of columns the item spans.
-         * @param heading Whether the item is a heading.
+         * @param heading Whether the item is a heading. (Prefer
+         *                {@link AccessibilityNodeInfo#setHeading(boolean)}).
          */
         public static CollectionItemInfo obtain(int rowIndex, int rowSpan,
                 int columnIndex, int columnSpan, boolean heading) {
@@ -4611,7 +4638,8 @@ public class AccessibilityNodeInfo implements Parcelable {
          * @param rowSpan The number of rows the item spans.
          * @param columnIndex The column index at which the item is located.
          * @param columnSpan The number of columns the item spans.
-         * @param heading Whether the item is a heading.
+         * @param heading Whether the item is a heading. (Prefer
+         *                {@link AccessibilityNodeInfo#setHeading(boolean)})
          * @param selected Whether the item is selected.
          */
         public static CollectionItemInfo obtain(int rowIndex, int rowSpan,
@@ -4698,6 +4726,7 @@ public class AccessibilityNodeInfo implements Parcelable {
          * heading, table header, etc.
          *
          * @return If the item is a heading.
+         * @deprecated Use {@link AccessibilityNodeInfo#isHeading()}
          */
         public boolean isHeading() {
             return mHeading;
index dac6c02..7d3fcf4 100644 (file)
@@ -309,6 +309,7 @@ import java.util.Locale;
  * @attr ref android.R.styleable#TextView_autoSizeMaxTextSize
  * @attr ref android.R.styleable#TextView_autoSizeStepGranularity
  * @attr ref android.R.styleable#TextView_autoSizePresetSizes
+ * @attr ref android.R.styleable#TextView_accessibilityHeading
  */
 @RemoteView
 public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {
@@ -403,6 +404,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
     private int mCurTextColor;
     private int mCurHintTextColor;
     private boolean mFreezesText;
+    private boolean mIsAccessibilityHeading;
 
     private Editable.Factory mEditableFactory = Editable.Factory.getInstance();
     private Spannable.Factory mSpannableFactory = Spannable.Factory.getInstance();
@@ -1267,6 +1269,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
                 case com.android.internal.R.styleable.TextView_lineHeight:
                     lineHeight = a.getDimensionPixelSize(attr, -1);
                     break;
+                case com.android.internal.R.styleable.TextView_accessibilityHeading:
+                    mIsAccessibilityHeading = a.getBoolean(attr, false);
             }
         }
 
@@ -5128,6 +5132,31 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
     }
 
     /**
+     * Gets whether this view is a heading for accessibility purposes.
+     *
+     * @return {@code true} if the view is a heading, {@code false} otherwise.
+     *
+     * @attr ref android.R.styleable#TextView_accessibilityHeading
+     */
+    public boolean isAccessibilityHeading() {
+        return mIsAccessibilityHeading;
+    }
+
+    /**
+     * Set if view is a heading for a section of content for accessibility purposes.
+     *
+     * @param isHeading {@code true} if the view is a heading, {@code false} otherwise.
+     *
+     * @attr ref android.R.styleable#TextView_accessibilityHeading
+     */
+    public void setAccessibilityHeading(boolean isHeading) {
+        if (isHeading != mIsAccessibilityHeading) {
+            mIsAccessibilityHeading = isHeading;
+            notifyAccessibilityStateChanged(AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
+        }
+    }
+
+    /**
      * Convenience method to append the specified text to the TextView's
      * display buffer, upgrading it to {@link android.widget.TextView.BufferType#EDITABLE}
      * if it was not already editable.
@@ -10677,6 +10706,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
         info.setText(getTextForAccessibility());
         info.setHintText(mHint);
         info.setShowingHintText(isShowingHint());
+        info.setHeading(mIsAccessibilityHeading);
 
         if (mBufferType == BufferType.EDITABLE) {
             info.setEditable(true);
index fd33dc9..4eaf93d 100644 (file)
             <!-- Justification by stretching word spacing. -->
             <enum name="inter_word" value = "1" />
         </attr>
+        <!-- Whether or not this view is a heading for accessibility purposes. -->
+        <attr name="accessibilityHeading" format="boolean"/>
     </declare-styleable>
     <declare-styleable name="TextViewAppearance">
         <!-- Base text color, typeface, size, and style. -->
index 656add6..9cdf553 100644 (file)
       <public name="firstBaselineToTopHeight" />
       <public name="lastBaselineToBottomHeight" />
       <public name="lineHeight" />
+      <public name="accessibilityHeading" />
     </public-group>
 
     <public-group type="style" first-id="0x010302e0">