Loading api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -47136,7 +47136,9 @@ package android.text.style { public abstract class ReplacementSpan extends android.text.style.MetricAffectingSpan { ctor public ReplacementSpan(); method public abstract void draw(@NonNull android.graphics.Canvas, CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, float, int, int, int, @NonNull android.graphics.Paint); method @Nullable public CharSequence getContentDescription(); method public abstract int getSize(@NonNull android.graphics.Paint, CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @Nullable android.graphics.Paint.FontMetricsInt); method public void setContentDescription(@Nullable CharSequence); method public void updateDrawState(android.text.TextPaint); method public void updateMeasureState(android.text.TextPaint); } core/java/android/text/TextUtils.java +9 −2 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.os.Parcelable; import android.sysprop.DisplayProperties; import android.text.style.AbsoluteSizeSpan; import android.text.style.AccessibilityClickableSpan; import android.text.style.AccessibilityReplacementSpan; import android.text.style.AccessibilityURLSpan; import android.text.style.AlignmentSpan; import android.text.style.BackgroundColorSpan; Loading Loading @@ -735,6 +736,8 @@ public class TextUtils { /** @hide */ public static final int LINE_HEIGHT_SPAN = 28; /** @hide */ public static final int ACCESSIBILITY_REPLACEMENT_SPAN = 29; /** @hide */ public static final int LAST_SPAN = LINE_HEIGHT_SPAN; /** Loading Loading @@ -934,6 +937,10 @@ public class TextUtils { readSpan(p, sp, new LineHeightSpan.Standard(p)); break; case ACCESSIBILITY_REPLACEMENT_SPAN: readSpan(p, sp, new AccessibilityReplacementSpan(p)); break; default: throw new RuntimeException("bogus span encoding " + kind); } Loading core/java/android/text/style/AccessibilityReplacementSpan.java 0 → 100644 +100 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.text.style; import android.graphics.Canvas; import android.graphics.Paint; import android.os.Parcel; import android.os.Parcelable; import android.text.ParcelableSpan; import android.text.TextUtils; /** * This class serves as a parcelable placeholder for the ReplacementSpans. * * This span contains content description of original span to let Accessibility service to do the * substitution for it. * * @hide */ public class AccessibilityReplacementSpan extends ReplacementSpan implements ParcelableSpan { // The content description of the span this one replaces private CharSequence mContentDescription; /** * @param contentDescription The content description of the span this one replaces */ public AccessibilityReplacementSpan(CharSequence contentDescription) { this.setContentDescription(contentDescription); mContentDescription = contentDescription; } public AccessibilityReplacementSpan(Parcel p) { mContentDescription = p.readCharSequence(); } @Override public int getSpanTypeId() { return getSpanTypeIdInternal(); } @Override public int getSpanTypeIdInternal() { return TextUtils.ACCESSIBILITY_REPLACEMENT_SPAN; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { writeToParcelInternal(dest, flags); } @Override public void writeToParcelInternal(Parcel dest, int flags) { dest.writeCharSequence(mContentDescription); } @Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { return 0; } @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { } public static final @android.annotation.NonNull Parcelable.Creator<AccessibilityReplacementSpan> CREATOR = new Parcelable.Creator<AccessibilityReplacementSpan>() { @Override public AccessibilityReplacementSpan createFromParcel(Parcel parcel) { return new AccessibilityReplacementSpan(parcel); } @Override public AccessibilityReplacementSpan[] newArray(int size) { return new AccessibilityReplacementSpan[size]; } }; } core/java/android/text/style/ReplacementSpan.java +23 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ import android.text.TextPaint; public abstract class ReplacementSpan extends MetricAffectingSpan { private CharSequence mContentDescription = null; /** * Returns the width of the span. Extending classes can set the height of the span by updating * attributes of {@link android.graphics.Paint.FontMetricsInt}. If the span covers the whole Loading Loading @@ -60,6 +62,27 @@ public abstract class ReplacementSpan extends MetricAffectingSpan { @IntRange(from = 0) int start, @IntRange(from = 0) int end, float x, int top, int y, int bottom, @NonNull Paint paint); /** * Gets a brief description of this ImageSpan for use in accessibility support. * * @return The content description. */ @Nullable public CharSequence getContentDescription() { return mContentDescription; } /** * Sets the specific content description into ImageSpan. * ReplacementSpans are shared with accessibility services, * but only the content description is available from them. * * @param contentDescription content description. The default value is null. */ public void setContentDescription(@Nullable CharSequence contentDescription) { mContentDescription = contentDescription; } /** * This method does nothing, since ReplacementSpans are measured * explicitly instead of affecting Paint properties. Loading core/java/android/view/accessibility/AccessibilityNodeInfo.java +76 −25 Original line number Diff line number Diff line Loading @@ -39,8 +39,10 @@ import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextUtils; import android.text.style.AccessibilityClickableSpan; import android.text.style.AccessibilityReplacementSpan; import android.text.style.AccessibilityURLSpan; import android.text.style.ClickableSpan; import android.text.style.ReplacementSpan; import android.text.style.URLSpan; import android.util.ArrayMap; import android.util.ArraySet; Loading Loading @@ -2641,14 +2643,32 @@ public class AccessibilityNodeInfo implements Parcelable { public void setText(CharSequence text) { enforceNotSealed(); mOriginalText = text; // Replace any ClickableSpans in mText with placeholders if (text instanceof Spanned) { ClickableSpan[] spans = CharSequence tmpText = text; tmpText = replaceClickableSpan(tmpText); tmpText = replaceReplacementSpan(tmpText); mText = tmpText; return; } mText = (text == null) ? null : text.subSequence(0, text.length()); } /** * Replaces any ClickableSpans in mText with placeholders. * * @param text The text. * * @return The spannable with ClickableSpan replacement. */ private CharSequence replaceClickableSpan(CharSequence text) { ClickableSpan[] clickableSpans = ((Spanned) text).getSpans(0, text.length(), ClickableSpan.class); if (spans.length > 0) { Spannable spannable = new SpannableStringBuilder(text); for (int i = 0; i < spans.length; i++) { ClickableSpan span = spans[i]; if (clickableSpans.length == 0) { return text; } for (int i = 0; i < clickableSpans.length; i++) { ClickableSpan span = clickableSpans[i]; if ((span instanceof AccessibilityClickableSpan) || (span instanceof AccessibilityURLSpan)) { // We've already done enough Loading @@ -2664,11 +2684,42 @@ public class AccessibilityNodeInfo implements Parcelable { spannable.setSpan(replacementSpan, spanToReplaceStart, spanToReplaceEnd, spanToReplaceFlags); } mText = spannable; return; return spannable; } /** * Replace any ImageSpans in mText with its content description. * * @param text The text. * * @return The spannable with ReplacementSpan replacement. */ private CharSequence replaceReplacementSpan(CharSequence text) { ReplacementSpan[] replacementSpans = ((Spanned) text).getSpans(0, text.length(), ReplacementSpan.class); SpannableStringBuilder spannable = new SpannableStringBuilder(text); if (replacementSpans.length == 0) { return text; } mText = (text == null) ? null : text.subSequence(0, text.length()); for (int i = 0; i < replacementSpans.length; i++) { ReplacementSpan span = replacementSpans[i]; CharSequence replacementText = span.getContentDescription(); if (span instanceof AccessibilityReplacementSpan) { // We've already done enough break; } if (replacementText == null) { continue; } int spanToReplaceStart = spannable.getSpanStart(span); int spanToReplaceEnd = spannable.getSpanEnd(span); int spanToReplaceFlags = spannable.getSpanFlags(span); spannable.removeSpan(span); ReplacementSpan replacementSpan = new AccessibilityReplacementSpan(replacementText); spannable.setSpan(replacementSpan, spanToReplaceStart, spanToReplaceEnd, spanToReplaceFlags); } return spannable; } /** Loading Loading
api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -47136,7 +47136,9 @@ package android.text.style { public abstract class ReplacementSpan extends android.text.style.MetricAffectingSpan { ctor public ReplacementSpan(); method public abstract void draw(@NonNull android.graphics.Canvas, CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, float, int, int, int, @NonNull android.graphics.Paint); method @Nullable public CharSequence getContentDescription(); method public abstract int getSize(@NonNull android.graphics.Paint, CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @Nullable android.graphics.Paint.FontMetricsInt); method public void setContentDescription(@Nullable CharSequence); method public void updateDrawState(android.text.TextPaint); method public void updateMeasureState(android.text.TextPaint); }
core/java/android/text/TextUtils.java +9 −2 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.os.Parcelable; import android.sysprop.DisplayProperties; import android.text.style.AbsoluteSizeSpan; import android.text.style.AccessibilityClickableSpan; import android.text.style.AccessibilityReplacementSpan; import android.text.style.AccessibilityURLSpan; import android.text.style.AlignmentSpan; import android.text.style.BackgroundColorSpan; Loading Loading @@ -735,6 +736,8 @@ public class TextUtils { /** @hide */ public static final int LINE_HEIGHT_SPAN = 28; /** @hide */ public static final int ACCESSIBILITY_REPLACEMENT_SPAN = 29; /** @hide */ public static final int LAST_SPAN = LINE_HEIGHT_SPAN; /** Loading Loading @@ -934,6 +937,10 @@ public class TextUtils { readSpan(p, sp, new LineHeightSpan.Standard(p)); break; case ACCESSIBILITY_REPLACEMENT_SPAN: readSpan(p, sp, new AccessibilityReplacementSpan(p)); break; default: throw new RuntimeException("bogus span encoding " + kind); } Loading
core/java/android/text/style/AccessibilityReplacementSpan.java 0 → 100644 +100 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.text.style; import android.graphics.Canvas; import android.graphics.Paint; import android.os.Parcel; import android.os.Parcelable; import android.text.ParcelableSpan; import android.text.TextUtils; /** * This class serves as a parcelable placeholder for the ReplacementSpans. * * This span contains content description of original span to let Accessibility service to do the * substitution for it. * * @hide */ public class AccessibilityReplacementSpan extends ReplacementSpan implements ParcelableSpan { // The content description of the span this one replaces private CharSequence mContentDescription; /** * @param contentDescription The content description of the span this one replaces */ public AccessibilityReplacementSpan(CharSequence contentDescription) { this.setContentDescription(contentDescription); mContentDescription = contentDescription; } public AccessibilityReplacementSpan(Parcel p) { mContentDescription = p.readCharSequence(); } @Override public int getSpanTypeId() { return getSpanTypeIdInternal(); } @Override public int getSpanTypeIdInternal() { return TextUtils.ACCESSIBILITY_REPLACEMENT_SPAN; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { writeToParcelInternal(dest, flags); } @Override public void writeToParcelInternal(Parcel dest, int flags) { dest.writeCharSequence(mContentDescription); } @Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { return 0; } @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { } public static final @android.annotation.NonNull Parcelable.Creator<AccessibilityReplacementSpan> CREATOR = new Parcelable.Creator<AccessibilityReplacementSpan>() { @Override public AccessibilityReplacementSpan createFromParcel(Parcel parcel) { return new AccessibilityReplacementSpan(parcel); } @Override public AccessibilityReplacementSpan[] newArray(int size) { return new AccessibilityReplacementSpan[size]; } }; }
core/java/android/text/style/ReplacementSpan.java +23 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ import android.text.TextPaint; public abstract class ReplacementSpan extends MetricAffectingSpan { private CharSequence mContentDescription = null; /** * Returns the width of the span. Extending classes can set the height of the span by updating * attributes of {@link android.graphics.Paint.FontMetricsInt}. If the span covers the whole Loading Loading @@ -60,6 +62,27 @@ public abstract class ReplacementSpan extends MetricAffectingSpan { @IntRange(from = 0) int start, @IntRange(from = 0) int end, float x, int top, int y, int bottom, @NonNull Paint paint); /** * Gets a brief description of this ImageSpan for use in accessibility support. * * @return The content description. */ @Nullable public CharSequence getContentDescription() { return mContentDescription; } /** * Sets the specific content description into ImageSpan. * ReplacementSpans are shared with accessibility services, * but only the content description is available from them. * * @param contentDescription content description. The default value is null. */ public void setContentDescription(@Nullable CharSequence contentDescription) { mContentDescription = contentDescription; } /** * This method does nothing, since ReplacementSpans are measured * explicitly instead of affecting Paint properties. Loading
core/java/android/view/accessibility/AccessibilityNodeInfo.java +76 −25 Original line number Diff line number Diff line Loading @@ -39,8 +39,10 @@ import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextUtils; import android.text.style.AccessibilityClickableSpan; import android.text.style.AccessibilityReplacementSpan; import android.text.style.AccessibilityURLSpan; import android.text.style.ClickableSpan; import android.text.style.ReplacementSpan; import android.text.style.URLSpan; import android.util.ArrayMap; import android.util.ArraySet; Loading Loading @@ -2641,14 +2643,32 @@ public class AccessibilityNodeInfo implements Parcelable { public void setText(CharSequence text) { enforceNotSealed(); mOriginalText = text; // Replace any ClickableSpans in mText with placeholders if (text instanceof Spanned) { ClickableSpan[] spans = CharSequence tmpText = text; tmpText = replaceClickableSpan(tmpText); tmpText = replaceReplacementSpan(tmpText); mText = tmpText; return; } mText = (text == null) ? null : text.subSequence(0, text.length()); } /** * Replaces any ClickableSpans in mText with placeholders. * * @param text The text. * * @return The spannable with ClickableSpan replacement. */ private CharSequence replaceClickableSpan(CharSequence text) { ClickableSpan[] clickableSpans = ((Spanned) text).getSpans(0, text.length(), ClickableSpan.class); if (spans.length > 0) { Spannable spannable = new SpannableStringBuilder(text); for (int i = 0; i < spans.length; i++) { ClickableSpan span = spans[i]; if (clickableSpans.length == 0) { return text; } for (int i = 0; i < clickableSpans.length; i++) { ClickableSpan span = clickableSpans[i]; if ((span instanceof AccessibilityClickableSpan) || (span instanceof AccessibilityURLSpan)) { // We've already done enough Loading @@ -2664,11 +2684,42 @@ public class AccessibilityNodeInfo implements Parcelable { spannable.setSpan(replacementSpan, spanToReplaceStart, spanToReplaceEnd, spanToReplaceFlags); } mText = spannable; return; return spannable; } /** * Replace any ImageSpans in mText with its content description. * * @param text The text. * * @return The spannable with ReplacementSpan replacement. */ private CharSequence replaceReplacementSpan(CharSequence text) { ReplacementSpan[] replacementSpans = ((Spanned) text).getSpans(0, text.length(), ReplacementSpan.class); SpannableStringBuilder spannable = new SpannableStringBuilder(text); if (replacementSpans.length == 0) { return text; } mText = (text == null) ? null : text.subSequence(0, text.length()); for (int i = 0; i < replacementSpans.length; i++) { ReplacementSpan span = replacementSpans[i]; CharSequence replacementText = span.getContentDescription(); if (span instanceof AccessibilityReplacementSpan) { // We've already done enough break; } if (replacementText == null) { continue; } int spanToReplaceStart = spannable.getSpanStart(span); int spanToReplaceEnd = spannable.getSpanEnd(span); int spanToReplaceFlags = spannable.getSpanFlags(span); spannable.removeSpan(span); ReplacementSpan replacementSpan = new AccessibilityReplacementSpan(replacementText); spannable.setSpan(replacementSpan, spanToReplaceStart, spanToReplaceEnd, spanToReplaceFlags); } return spannable; } /** Loading