summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/text/DynamicLayout.java35
-rw-r--r--core/java/android/text/flags/flags.aconfig7
-rw-r--r--core/java/android/widget/Editor.java8
3 files changed, 46 insertions, 4 deletions
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index 7b9cb6afd6a0..928604983b70 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -40,6 +40,7 @@ import android.util.Pools.SynchronizedPool;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;
+import com.android.text.flags.Flags;
import java.lang.ref.WeakReference;
@@ -1276,8 +1277,21 @@ public class DynamicLayout extends Layout {
}
public void onSpanRemoved(Spannable s, Object o, int start, int end) {
- if (o instanceof UpdateLayout)
- transformAndReflow(s, start, end);
+ if (o instanceof UpdateLayout) {
+ if (Flags.insertModeCrashWhenDelete()) {
+ final DynamicLayout dynamicLayout = mLayout.get();
+ if (dynamicLayout != null && dynamicLayout.mDisplay instanceof OffsetMapping) {
+ // It's possible that a Span is removed when the text covering it is
+ // deleted, in this case, the original start and end of the span might be
+ // OOB. So it'll reflow the entire string instead.
+ reflow(s, 0, 0, s.length());
+ } else {
+ reflow(s, start, end - start, end - start);
+ }
+ } else {
+ transformAndReflow(s, start, end);
+ }
+ }
}
public void onSpanChanged(Spannable s, Object o, int start, int end, int nstart, int nend) {
@@ -1287,8 +1301,21 @@ public class DynamicLayout extends Layout {
// instead of causing an exception
start = 0;
}
- transformAndReflow(s, start, end);
- transformAndReflow(s, nstart, nend);
+ if (Flags.insertModeCrashWhenDelete()) {
+ final DynamicLayout dynamicLayout = mLayout.get();
+ if (dynamicLayout != null && dynamicLayout.mDisplay instanceof OffsetMapping) {
+ // When text is changed, it'll also trigger onSpanChanged. In this case we
+ // can't determine the updated range in the transformed text. So it'll
+ // reflow the entire range instead.
+ reflow(s, 0, 0, s.length());
+ } else {
+ reflow(s, start, end - start, end - start);
+ reflow(s, nstart, nend - nstart, nend - nstart);
+ }
+ } else {
+ transformAndReflow(s, start, end);
+ transformAndReflow(s, nstart, nend);
+ }
}
}
diff --git a/core/java/android/text/flags/flags.aconfig b/core/java/android/text/flags/flags.aconfig
index bf1a59625c93..6e45fea930d2 100644
--- a/core/java/android/text/flags/flags.aconfig
+++ b/core/java/android/text/flags/flags.aconfig
@@ -89,3 +89,10 @@ flag {
description: "Feature flag for clearing focus when the escape key is pressed."
bug: "312921137"
}
+
+flag {
+ name: "insert_mode_crash_when_delete"
+ namespace: "text"
+ description: "A feature flag for fixing the crash while delete text in insert mode."
+ bug: "314254153"
+}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index ddcfb40e00ce..57d268ced6f4 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -148,6 +148,7 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;
import com.android.internal.util.Preconditions;
import com.android.internal.view.FloatingActionMode;
+import com.android.text.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -2343,6 +2344,13 @@ public class Editor {
*/
void invalidateTextDisplayList(Layout layout, int start, int end) {
if (mTextRenderNodes != null && layout instanceof DynamicLayout) {
+ if (Flags.insertModeCrashWhenDelete()
+ && mTextView.isOffsetMappingAvailable()) {
+ // Text is transformed with an OffsetMapping, and we can't know the changed range
+ // on the transformed text. Invalidate the all display lists instead.
+ invalidateTextDisplayList();
+ return;
+ }
final int startTransformed =
mTextView.originalToTransformed(start, OffsetMapping.MAP_STRATEGY_CHARACTER);
final int endTransformed =