summaryrefslogtreecommitdiff
path: root/core/java/android/widget/TextViewRichContentReceiver.java
diff options
context:
space:
mode:
authorNikita Dubrovsky <dubrovsky@google.com>2020-08-11 23:41:21 -0700
committerNikita Dubrovsky <dubrovsky@google.com>2020-09-25 13:46:33 -0700
commitdd9869aa4c0a58230ba51956eae245d4415cca63 (patch)
treeb98a759382b446525647c0d07386fa838abfcb1f /core/java/android/widget/TextViewRichContentReceiver.java
parent35762bfa973fbda5b2c970e476b888bd96ec7fbd (diff)
Update RichContentReceiver API (now OnReceiveContentCallback)
Bug: 163718378 Bug: 165632620 Bug: 152068298 Test: Unit tests atest CtsWidgetTestCases:TextViewOnReceiveContentCallbackTest atest CtsViewTestCases:ViewTest atest FrameworksCoreTests:TextViewProcessTextTest Change-Id: I3fa65b47c920a9d1ddad88a79e60864dc8109753
Diffstat (limited to 'core/java/android/widget/TextViewRichContentReceiver.java')
-rw-r--r--core/java/android/widget/TextViewRichContentReceiver.java153
1 files changed, 0 insertions, 153 deletions
diff --git a/core/java/android/widget/TextViewRichContentReceiver.java b/core/java/android/widget/TextViewRichContentReceiver.java
deleted file mode 100644
index 4f2d95466997..000000000000
--- a/core/java/android/widget/TextViewRichContentReceiver.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2020 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.widget;
-
-import android.annotation.NonNull;
-import android.content.ClipData;
-import android.content.Context;
-import android.text.Editable;
-import android.text.Selection;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
-import android.util.Log;
-
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * Default implementation of {@link RichContentReceiver} for editable {@link TextView} components.
- * This class handles insertion of text (plain text, styled text, HTML, etc) but not images or other
- * rich content. Typically this class will be used as a delegate by custom implementations of
- * {@link RichContentReceiver}, to provide consistent behavior for insertion of text while
- * implementing custom behavior for insertion of other content (images, etc). See
- * {@link TextView#DEFAULT_RICH_CONTENT_RECEIVER}.
- *
- * @hide
- */
-final class TextViewRichContentReceiver implements RichContentReceiver<TextView> {
- static final TextViewRichContentReceiver INSTANCE = new TextViewRichContentReceiver();
-
- private static final String LOG_TAG = "RichContentReceiver";
-
- private static final Set<String> MIME_TYPES_ALL_TEXT = Collections.singleton("text/*");
-
- @Override
- public Set<String> getSupportedMimeTypes() {
- return MIME_TYPES_ALL_TEXT;
- }
-
- @Override
- public boolean onReceive(@NonNull TextView textView, @NonNull ClipData clip,
- @Source int source, @Flags int flags) {
- if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
- StringBuilder sb = new StringBuilder("onReceive: clip=");
- if (clip.getDescription() == null) {
- sb.append("null");
- } else {
- clip.getDescription().toShortStringTypesOnly(sb);
- }
- sb.append(", source=").append(RichContentReceiver.sourceToString(source));
- sb.append(", flags=").append(RichContentReceiver.flagsToString(flags));
- Log.d(LOG_TAG, sb.toString());
- }
- if (source == SOURCE_AUTOFILL) {
- return onReceiveForAutofill(textView, clip, flags);
- }
- if (source == SOURCE_DRAG_AND_DROP) {
- return onReceiveForDragAndDrop(textView, clip, flags);
- }
- if (source == SOURCE_INPUT_METHOD && !supports(clip.getDescription())) {
- return false;
- }
-
- // The code here follows the original paste logic from TextView:
- // https://cs.android.com/android/_/android/platform/frameworks/base/+/9fefb65aa9e7beae9ca8306b925b9fbfaeffecc9:core/java/android/widget/TextView.java;l=12644
- // In particular, multiple items within the given ClipData will trigger separate calls to
- // replace/insert. This is to preserve the original behavior with respect to TextWatcher
- // notifications fired from SpannableStringBuilder when replace/insert is called.
- final Editable editable = (Editable) textView.getText();
- final Context context = textView.getContext();
- boolean didFirst = false;
- for (int i = 0; i < clip.getItemCount(); i++) {
- CharSequence itemText;
- if ((flags & FLAG_CONVERT_TO_PLAIN_TEXT) != 0) {
- itemText = clip.getItemAt(i).coerceToText(context);
- itemText = (itemText instanceof Spanned) ? itemText.toString() : itemText;
- } else {
- itemText = clip.getItemAt(i).coerceToStyledText(context);
- }
- if (itemText != null) {
- if (!didFirst) {
- replaceSelection(editable, itemText);
- didFirst = true;
- } else {
- editable.insert(Selection.getSelectionEnd(editable), "\n");
- editable.insert(Selection.getSelectionEnd(editable), itemText);
- }
- }
- }
- return didFirst;
- }
-
- private static void replaceSelection(@NonNull Editable editable,
- @NonNull CharSequence replacement) {
- final int selStart = Selection.getSelectionStart(editable);
- final int selEnd = Selection.getSelectionEnd(editable);
- final int start = Math.max(0, Math.min(selStart, selEnd));
- final int end = Math.max(0, Math.max(selStart, selEnd));
- Selection.setSelection(editable, end);
- editable.replace(start, end, replacement);
- }
-
- private static boolean onReceiveForAutofill(@NonNull TextView textView, @NonNull ClipData clip,
- @Flags int flags) {
- final CharSequence text = coerceToText(clip, textView.getContext(), flags);
- // First autofill it...
- textView.setText(text);
- // ...then move cursor to the end.
- final Editable editable = (Editable) textView.getText();
- Selection.setSelection(editable, editable.length());
- return true;
- }
-
- private static boolean onReceiveForDragAndDrop(@NonNull TextView textView,
- @NonNull ClipData clip, @Flags int flags) {
- final CharSequence text = coerceToText(clip, textView.getContext(), flags);
- if (text.length() == 0) {
- return false;
- }
- replaceSelection((Editable) textView.getText(), text);
- return true;
- }
-
- private static CharSequence coerceToText(ClipData clip, Context context, @Flags int flags) {
- SpannableStringBuilder ssb = new SpannableStringBuilder();
- for (int i = 0; i < clip.getItemCount(); i++) {
- CharSequence itemText;
- if ((flags & FLAG_CONVERT_TO_PLAIN_TEXT) != 0) {
- itemText = clip.getItemAt(i).coerceToText(context);
- itemText = (itemText instanceof Spanned) ? itemText.toString() : itemText;
- } else {
- itemText = clip.getItemAt(i).coerceToStyledText(context);
- }
- if (itemText != null) {
- ssb.append(itemText);
- }
- }
- return ssb;
- }
-}