diff options
| author | Nikita Dubrovsky <dubrovsky@google.com> | 2020-08-11 23:41:21 -0700 |
|---|---|---|
| committer | Nikita Dubrovsky <dubrovsky@google.com> | 2020-09-25 13:46:33 -0700 |
| commit | dd9869aa4c0a58230ba51956eae245d4415cca63 (patch) | |
| tree | b98a759382b446525647c0d07386fa838abfcb1f /core/java/android/widget/TextViewRichContentReceiver.java | |
| parent | 35762bfa973fbda5b2c970e476b888bd96ec7fbd (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.java | 153 |
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; - } -} |
