Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27f9097f authored by Yinglei Wang's avatar Yinglei Wang Committed by Android (Google) Code Review
Browse files

Merge "Implement supplemental description API" into main

parents 48bdf403 4fe100ea
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1609,6 +1609,7 @@ package android {
    field public static final int summaryColumn = 16843426; // 0x10102a2
    field public static final int summaryOff = 16843248; // 0x10101f0
    field public static final int summaryOn = 16843247; // 0x10101ef
    field @FlaggedApi("android.view.accessibility.supplemental_description") public static final int supplementalDescription;
    field public static final int supportedTypes = 16844369; // 0x1010651
    field public static final int supportsAssist = 16844016; // 0x10104f0
    field public static final int supportsBatteryGameMode = 16844374; // 0x1010656
@@ -53215,6 +53216,7 @@ package android.view {
    method public android.animation.StateListAnimator getStateListAnimator();
    method protected int getSuggestedMinimumHeight();
    method protected int getSuggestedMinimumWidth();
    method @FlaggedApi("android.view.accessibility.supplemental_description") @Nullable public CharSequence getSupplementalDescription();
    method @NonNull public java.util.List<android.graphics.Rect> getSystemGestureExclusionRects();
    method @Deprecated public int getSystemUiVisibility();
    method public Object getTag();
@@ -53595,6 +53597,7 @@ package android.view {
    method public void setSoundEffectsEnabled(boolean);
    method public void setStateDescription(@Nullable CharSequence);
    method public void setStateListAnimator(android.animation.StateListAnimator);
    method @FlaggedApi("android.view.accessibility.supplemental_description") public void setSupplementalDescription(@Nullable CharSequence);
    method public void setSystemGestureExclusionRects(@NonNull java.util.List<android.graphics.Rect>);
    method @Deprecated public void setSystemUiVisibility(int);
    method public void setTag(Object);
@@ -55201,6 +55204,7 @@ package android.view.accessibility {
    field public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 8; // 0x8
    field public static final int CONTENT_CHANGE_TYPE_STATE_DESCRIPTION = 64; // 0x40
    field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1; // 0x1
    field @FlaggedApi("android.view.accessibility.supplemental_description") public static final int CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION = 32768; // 0x8000
    field public static final int CONTENT_CHANGE_TYPE_TEXT = 2; // 0x2
    field public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0; // 0x0
    field @NonNull public static final android.os.Parcelable.Creator<android.view.accessibility.AccessibilityEvent> CREATOR;
@@ -55363,6 +55367,7 @@ package android.view.accessibility {
    method @Nullable public android.view.accessibility.AccessibilityNodeInfo getParent(int);
    method public android.view.accessibility.AccessibilityNodeInfo.RangeInfo getRangeInfo();
    method @Nullable public CharSequence getStateDescription();
    method @FlaggedApi("android.view.accessibility.supplemental_description") @Nullable public CharSequence getSupplementalDescription();
    method public CharSequence getText();
    method public int getTextSelectionEnd();
    method public int getTextSelectionStart();
@@ -55471,6 +55476,7 @@ package android.view.accessibility {
    method public void setSource(android.view.View);
    method public void setSource(android.view.View, int);
    method public void setStateDescription(@Nullable CharSequence);
    method @FlaggedApi("android.view.accessibility.supplemental_description") public void setSupplementalDescription(@Nullable CharSequence);
    method public void setText(CharSequence);
    method public void setTextEntryKey(boolean);
    method public void setTextSelectable(boolean);
+93 −0
Original line number Diff line number Diff line
@@ -181,6 +181,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.Flags;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Transformation;
@@ -4863,6 +4864,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    private CharSequence mContentDescription;
    /**
     * Brief supplemental information for view and is primarily used for accessibility support.
     */
    private CharSequence mSupplementalDescription;
    /**
     * If this view represents a distinct part of the window, it can have a title that labels the
     * area.
@@ -6534,6 +6540,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                case R.styleable.View_contentSensitivity:
                    setContentSensitivity(a.getInt(attr, CONTENT_SENSITIVITY_AUTO));
                    break;
                default: {
                    if (Flags.supplementalDescription()) {
                        if (attr == com.android.internal.R.styleable.View_supplementalDescription) {
                            setSupplementalDescription(a.getString(attr));
                        }
                    }
                }
            }
        }
@@ -11805,6 +11818,39 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        return mContentDescription;
    }
    /**
     * Returns the {@link View}'s supplemental description.
     * <p>
     * A supplemental description provides
     * brief supplemental information for this node, such as the purpose of the node when
     * that purpose is not conveyed within its textual representation. For example, if a
     * dropdown select has a purpose of setting font family, the supplemental description
     * could be "font family". If this node has children, its supplemental description serves
     * as additional information and is not intended to replace any existing information
     * in the subtree. This is different from the {@link #getContentDescription()} in that
     * this description is purely supplemental while a content description may be used
     * to replace a description for a node or its subtree that an assistive technology
     * would otherwise compute based on other properties of the node and its descendants.
     *
     * <p>
     * <strong>Note:</strong> Do not override this method, as it will have no
     * effect on the supplemental description presented to accessibility services.
     * You must call {@link #setSupplementalDescription(CharSequence)} to modify the
     * supplemental description.
     *
     * @return the supplemental description
     * @see #setSupplementalDescription(CharSequence)
     * @see #getContentDescription()
     * @attr ref android.R.styleable#View_supplementalDescription
     */
    @FlaggedApi(Flags.FLAG_SUPPLEMENTAL_DESCRIPTION)
    @ViewDebug.ExportedProperty(category = "accessibility")
    @InspectableProperty
    @Nullable
    public CharSequence getSupplementalDescription() {
        return mSupplementalDescription;
    }
    /**
     * Sets the {@link View}'s state description.
     * <p>
@@ -11891,6 +11937,53 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
    }
    /**
     * Sets the {@link View}'s supplemental description.
     * <p>
     * A supplemental description provides
     * brief supplemental information for this node, such as the purpose of the node when
     * that purpose is not conveyed within its textual representation. For example, if a
     * dropdown select has a purpose of setting font family, the supplemental description
     * could be "font family". If this node has children, its supplemental description serves
     * as additional information and is not intended to replace any existing information
     * in the subtree. This is different from the {@link #setContentDescription(CharSequence)}
     * in that this description is purely supplemental while a content description may be used
     * to replace a description for a node or its subtree that an assistive technology
     * would otherwise compute based on other properties of the node and its descendants.
     *
     * <p>
     * This should omit role or state. Role refers to the kind of user-interface element the View
     * is, such as a Button or Checkbox. State refers to a frequently changing property of the View,
     * such as an On/Off state of a button or the audio level of a volume slider.
     *
     * @param supplementalDescription The supplemental description.
     * @see #getSupplementalDescription()
     * @see #setContentDescription(CharSequence)
     * @see #setStateDescription(CharSequence) for state changes.
     * @attr ref android.R.styleable#View_supplementalDescription
     */
    @FlaggedApi(Flags.FLAG_SUPPLEMENTAL_DESCRIPTION)
    @RemotableViewMethod
    public void setSupplementalDescription(@Nullable CharSequence supplementalDescription) {
        if (mSupplementalDescription == null) {
            if (supplementalDescription == null) {
                return;
            }
        } else if (mSupplementalDescription.equals(supplementalDescription)) {
            return;
        }
        mSupplementalDescription = supplementalDescription;
        final boolean nonEmptyDesc = supplementalDescription != null
                && !supplementalDescription.isEmpty();
        if (nonEmptyDesc && getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
            setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
            notifySubtreeAccessibilityStateChangedIfNeeded();
        } else {
            notifyViewAccessibilityStateChangedIfNeeded(
                    AccessibilityEvent.CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION);
        }
    }
    /**
     * Sets the id of a view that screen readers are requested to visit after this view.
     *
+23 −1
Original line number Diff line number Diff line
@@ -810,6 +810,20 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
    @FlaggedApi(Flags.FLAG_A11Y_EXPANSION_STATE_API)
    public static final int CONTENT_CHANGE_TYPE_EXPANDED = 1 << 14;

    /**
     * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
     * The source node changed its supplemental description, which is returned by
     * {@link AccessibilityNodeInfo#getSupplementalDescription()}.
     * The view changing its supplemental description should call
     * {@link AccessibilityNodeInfo#setSupplementalDescription(CharSequence)} and
     * then send this event.
     *
     * @see AccessibilityNodeInfo#getSupplementalDescription()
     * @see AccessibilityNodeInfo#setSupplementalDescription(CharSequence)
     */
    @FlaggedApi(Flags.FLAG_SUPPLEMENTAL_DESCRIPTION)
    public static final int CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION = 1 << 15;

    // Speech state change types.

    /** Change type for {@link #TYPE_SPEECH_STATE_CHANGE} event: another service is speaking. */
@@ -942,6 +956,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
                CONTENT_CHANGE_TYPE_CONTENT_INVALID,
                CONTENT_CHANGE_TYPE_ERROR,
                CONTENT_CHANGE_TYPE_ENABLED,
                CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION,
            })
    public @interface ContentChangeTypes {}

@@ -1222,7 +1237,14 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
                return "CONTENT_CHANGE_TYPE_CONTENT_INVALID";
            case CONTENT_CHANGE_TYPE_ERROR: return "CONTENT_CHANGE_TYPE_ERROR";
            case CONTENT_CHANGE_TYPE_ENABLED: return "CONTENT_CHANGE_TYPE_ENABLED";
            default: return Integer.toHexString(type);
            default: {
                if (Flags.supplementalDescription()) {
                    if (type == CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION) {
                        return "CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION";
                    }
                }
                return Integer.toHexString(type);
            }
        }
    }

+65 −0
Original line number Diff line number Diff line
@@ -1085,6 +1085,7 @@ public class AccessibilityNodeInfo implements Parcelable {
    private CharSequence mPaneTitle;
    private CharSequence mStateDescription;
    private CharSequence mContentDescription;
    private CharSequence mSupplementalDescription;
    private CharSequence mTooltipText;
    private String mViewIdResourceName;
    private String mUniqueId;
@@ -3686,6 +3687,27 @@ public class AccessibilityNodeInfo implements Parcelable {
        return mContentDescription;
    }

    /**
     * Gets the supplemental description of this node. A supplemental description provides
     * brief supplemental information for this node, such as the purpose of the node when
     * that purpose is not conveyed within its textual representation. For example, if a
     * dropdown select has a purpose of setting font family, the supplemental description
     * could be "font family". If this node has children, its supplemental description serves
     * as additional information and is not intended to replace any existing information
     * in the subtree. This is different from the {@link #getContentDescription()} in that
     * this description is purely supplemental while a content description may be used
     * to replace a description for a node or its subtree that an assistive technology
     * would otherwise compute based on other properties of the node and its descendants.
     *
     * @return The supplemental description.
     * @see #setSupplementalDescription(CharSequence)
     * @see #getContentDescription()
     */
    @FlaggedApi(Flags.FLAG_SUPPLEMENTAL_DESCRIPTION)
    @Nullable
    public CharSequence getSupplementalDescription() {
        return mSupplementalDescription;
    }

    /**
     * Sets the state description of this node.
@@ -3723,6 +3745,35 @@ public class AccessibilityNodeInfo implements Parcelable {
                : contentDescription.subSequence(0, contentDescription.length());
    }

    /**
     * Sets the supplemental description of this node. A supplemental description provides
     * brief supplemental information for this node, such as the purpose of the node when
     * that purpose is not conveyed within its textual representation. For example, if a
     * dropdown select has a purpose of setting font family, the supplemental description
     * could be "font family". If this node has children, its supplemental description serves
     * as additional information and is not intended to replace any existing information
     * in the subtree. This is different from the {@link #setContentDescription(CharSequence)}
     * in that this description is purely supplemental while a content description may be used
     * to replace a description for a node or its subtree that an assistive technology
     * would otherwise compute based on other properties of the node and its descendants.
     * <p>
     *   <strong>Note:</strong> Cannot be called from an
     *   {@link android.accessibilityservice.AccessibilityService}.
     *   This class is made immutable before being delivered to an AccessibilityService.
     *
     * @param supplementalDescription The supplemental description.
     *
     * @throws IllegalStateException If called from an AccessibilityService.
     * @see #getSupplementalDescription()
     * @see #setContentDescription(CharSequence)
     */
    @FlaggedApi(Flags.FLAG_SUPPLEMENTAL_DESCRIPTION)
    public void setSupplementalDescription(@Nullable CharSequence supplementalDescription) {
        enforceNotSealed();
        mSupplementalDescription = (supplementalDescription == null) ? null
                : supplementalDescription.subSequence(0, supplementalDescription.length());
    }

    /**
     * Gets the tooltip text of this node.
     *
@@ -4657,6 +4708,10 @@ public class AccessibilityNodeInfo implements Parcelable {
            nonDefaultFields |= bitAt(fieldIndex);
        }
        fieldIndex++;
        if (!Objects.equals(mSupplementalDescription, DEFAULT.mSupplementalDescription)) {
            nonDefaultFields |= bitAt(fieldIndex);
        }
        fieldIndex++;
        if (!Objects.equals(mPaneTitle, DEFAULT.mPaneTitle)) {
            nonDefaultFields |= bitAt(fieldIndex);
        }
@@ -4843,6 +4898,9 @@ public class AccessibilityNodeInfo implements Parcelable {
        if (isBitSet(nonDefaultFields, fieldIndex++)) {
            parcel.writeCharSequence(mContentDescription);
        }
        if (isBitSet(nonDefaultFields, fieldIndex++)) {
            parcel.writeCharSequence(mSupplementalDescription);
        }
        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mPaneTitle);
        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mTooltipText);
        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mContainerTitle);
@@ -4950,6 +5008,7 @@ public class AccessibilityNodeInfo implements Parcelable {
        mError = other.mError;
        mStateDescription = other.mStateDescription;
        mContentDescription = other.mContentDescription;
        mSupplementalDescription = other.mSupplementalDescription;
        mPaneTitle = other.mPaneTitle;
        mTooltipText = other.mTooltipText;
        mContainerTitle = other.mContainerTitle;
@@ -5119,6 +5178,9 @@ public class AccessibilityNodeInfo implements Parcelable {
        if (isBitSet(nonDefaultFields, fieldIndex++)) {
            mContentDescription = parcel.readCharSequence();
        }
        if (isBitSet(nonDefaultFields, fieldIndex++)) {
            mSupplementalDescription = parcel.readCharSequence();
        }
        if (isBitSet(nonDefaultFields, fieldIndex++)) mPaneTitle = parcel.readCharSequence();
        if (isBitSet(nonDefaultFields, fieldIndex++)) mTooltipText = parcel.readCharSequence();
        if (isBitSet(nonDefaultFields, fieldIndex++)) mContainerTitle = parcel.readCharSequence();
@@ -5483,6 +5545,9 @@ public class AccessibilityNodeInfo implements Parcelable {
        builder.append("; maxTextLength: ").append(mMaxTextLength);
        builder.append("; stateDescription: ").append(mStateDescription);
        builder.append("; contentDescription: ").append(mContentDescription);
        if (Flags.supplementalDescription()) {
            builder.append("; supplementalDescription: ").append(mSupplementalDescription);
        }
        builder.append("; tooltipText: ").append(mTooltipText);
        builder.append("; containerTitle: ").append(mContainerTitle);
        builder.append("; viewIdResName: ").append(mViewIdResourceName);
+7 −0
Original line number Diff line number Diff line
@@ -221,6 +221,13 @@ flag {
    }
}

flag {
    name: "supplemental_description"
    namespace: "accessibility"
    description: "Feature flag for supplemental description api"
    bug: "375266174"
}

flag {
    name: "support_multiple_labeledby"
    namespace: "accessibility"
Loading