diff options
| author | Nikita Dubrovsky <dubrovsky@google.com> | 2020-11-30 22:33:03 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-11-30 22:33:03 +0000 |
| commit | 83de85f7b6c8ceead887434d162abf578dc529ee (patch) | |
| tree | a0dfa825d6a64deeda12487c38725a17725e4846 /core/java | |
| parent | 0a993aac9ad03628d0efcf47fb702c230caee93a (diff) | |
| parent | 10f027f69f21c59d29358b8ec5978595b64c3dbf (diff) | |
Merge "Move/rename OnReceiveContentListener.Payload to android.view.ContentInfo"
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/view/ContentInfo.java | 358 | ||||
| -rw-r--r-- | core/java/android/view/OnReceiveContentListener.java | 343 | ||||
| -rw-r--r-- | core/java/android/view/View.java | 12 | ||||
| -rw-r--r-- | core/java/android/view/autofill/AutofillManager.java | 8 | ||||
| -rw-r--r-- | core/java/android/view/inputmethod/BaseInputConnection.java | 8 | ||||
| -rw-r--r-- | core/java/android/widget/Editor.java | 8 | ||||
| -rw-r--r-- | core/java/android/widget/TextView.java | 20 | ||||
| -rw-r--r-- | core/java/android/widget/TextViewOnReceiveContentListener.java | 29 |
8 files changed, 416 insertions, 370 deletions
diff --git a/core/java/android/view/ContentInfo.java b/core/java/android/view/ContentInfo.java new file mode 100644 index 000000000000..b58937beed55 --- /dev/null +++ b/core/java/android/view/ContentInfo.java @@ -0,0 +1,358 @@ +/* + * 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.view; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.ClipData; +import android.net.Uri; +import android.os.Bundle; +import android.util.ArrayMap; + +import com.android.internal.util.Preconditions; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.Map; +import java.util.Objects; +import java.util.function.Predicate; + +/** + * Holds all the relevant data for a request to {@link View#performReceiveContent}. + */ +public final class ContentInfo { + + /** + * Specifies the UI through which content is being inserted. Future versions of Android may + * support additional values. + * + * @hide + */ + @IntDef(prefix = {"SOURCE_"}, value = {SOURCE_APP, SOURCE_CLIPBOARD, SOURCE_INPUT_METHOD, + SOURCE_DRAG_AND_DROP, SOURCE_AUTOFILL, SOURCE_PROCESS_TEXT}) + @Retention(RetentionPolicy.SOURCE) + public @interface Source {} + + /** + * Specifies that the operation was triggered by the app that contains the target view. + */ + public static final int SOURCE_APP = 0; + + /** + * Specifies that the operation was triggered by a paste from the clipboard (e.g. "Paste" or + * "Paste as plain text" action in the insertion/selection menu). + */ + public static final int SOURCE_CLIPBOARD = 1; + + /** + * Specifies that the operation was triggered from the soft keyboard (also known as input + * method editor or IME). See https://developer.android.com/guide/topics/text/image-keyboard + * for more info. + */ + public static final int SOURCE_INPUT_METHOD = 2; + + /** + * Specifies that the operation was triggered by the drag/drop framework. See + * https://developer.android.com/guide/topics/ui/drag-drop for more info. + */ + public static final int SOURCE_DRAG_AND_DROP = 3; + + /** + * Specifies that the operation was triggered by the autofill framework. See + * https://developer.android.com/guide/topics/text/autofill for more info. + */ + public static final int SOURCE_AUTOFILL = 4; + + /** + * Specifies that the operation was triggered by a result from a + * {@link android.content.Intent#ACTION_PROCESS_TEXT PROCESS_TEXT} action in the selection + * menu. + */ + public static final int SOURCE_PROCESS_TEXT = 5; + + /** + * Returns the symbolic name of the given source. + * + * @hide + */ + static String sourceToString(@Source int source) { + switch (source) { + case SOURCE_APP: return "SOURCE_APP"; + case SOURCE_CLIPBOARD: return "SOURCE_CLIPBOARD"; + case SOURCE_INPUT_METHOD: return "SOURCE_INPUT_METHOD"; + case SOURCE_DRAG_AND_DROP: return "SOURCE_DRAG_AND_DROP"; + case SOURCE_AUTOFILL: return "SOURCE_AUTOFILL"; + case SOURCE_PROCESS_TEXT: return "SOURCE_PROCESS_TEXT"; + } + return String.valueOf(source); + } + + /** + * Flags to configure the insertion behavior. + * + * @hide + */ + @IntDef(flag = true, prefix = {"FLAG_"}, value = {FLAG_CONVERT_TO_PLAIN_TEXT}) + @Retention(RetentionPolicy.SOURCE) + public @interface Flags {} + + /** + * Flag requesting that the content should be converted to plain text prior to inserting. + */ + public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1 << 0; + + /** + * Returns the symbolic names of the set flags or {@code "0"} if no flags are set. + * + * @hide + */ + static String flagsToString(@Flags int flags) { + if ((flags & FLAG_CONVERT_TO_PLAIN_TEXT) != 0) { + return "FLAG_CONVERT_TO_PLAIN_TEXT"; + } + return String.valueOf(flags); + } + + @NonNull + private final ClipData mClip; + @Source + private final int mSource; + @Flags + private final int mFlags; + @Nullable + private final Uri mLinkUri; + @Nullable + private final Bundle mExtras; + + private ContentInfo(Builder b) { + this.mClip = Objects.requireNonNull(b.mClip); + this.mSource = Preconditions.checkArgumentInRange(b.mSource, 0, SOURCE_PROCESS_TEXT, + "source"); + this.mFlags = Preconditions.checkFlagsArgument(b.mFlags, FLAG_CONVERT_TO_PLAIN_TEXT); + this.mLinkUri = b.mLinkUri; + this.mExtras = b.mExtras; + } + + @NonNull + @Override + public String toString() { + return "ContentInfo{" + + "clip=" + mClip + + ", source=" + sourceToString(mSource) + + ", flags=" + flagsToString(mFlags) + + ", linkUri=" + mLinkUri + + ", extras=" + mExtras + + "}"; + } + + /** + * The data to be inserted. + */ + @NonNull + public ClipData getClip() { + return mClip; + } + + /** + * The source of the operation. See {@code SOURCE_} constants. Future versions of Android + * may pass additional values. + */ + @Source + public int getSource() { + return mSource; + } + + /** + * Optional flags that control the insertion behavior. See {@code FLAG_} constants. + */ + @Flags + public int getFlags() { + return mFlags; + } + + /** + * Optional http/https URI for the content that may be provided by the IME. This is only + * populated if the source is {@link #SOURCE_INPUT_METHOD} and if a non-empty + * {@link android.view.inputmethod.InputContentInfo#getLinkUri linkUri} was passed by the + * IME. + */ + @Nullable + public Uri getLinkUri() { + return mLinkUri; + } + + /** + * Optional additional metadata. If the source is {@link #SOURCE_INPUT_METHOD}, this will + * include the {@link android.view.inputmethod.InputConnection#commitContent opts} passed by + * the IME. + */ + @Nullable + public Bundle getExtras() { + return mExtras; + } + + /** + * Partitions the content based on the given predicate. + * + * <p>Similar to a + * {@link java.util.stream.Collectors#partitioningBy(Predicate) partitioning collector}, + * this function classifies the content and organizes it into a map, grouping the items that + * matched vs didn't match the predicate. + * + * <p>Except for the {@link ClipData} items, the returned objects will contain all the same + * metadata as the original. + * + * @param itemPredicate The predicate to test each {@link ClipData.Item} to determine which + * partition to place it into. + * @return A map containing the partitioned content. The map will contain a single entry if + * all items were classified into the same partition (all matched or all didn't match the + * predicate) or two entries (if there's at least one item that matched the predicate and at + * least one item that didn't match the predicate). + */ + @NonNull + public Map<Boolean, ContentInfo> partition(@NonNull Predicate<ClipData.Item> itemPredicate) { + if (mClip.getItemCount() == 1) { + Map<Boolean, ContentInfo> result = new ArrayMap<>(1); + result.put(itemPredicate.test(mClip.getItemAt(0)), this); + return result; + } + ArrayList<ClipData.Item> accepted = new ArrayList<>(); + ArrayList<ClipData.Item> remaining = new ArrayList<>(); + for (int i = 0; i < mClip.getItemCount(); i++) { + ClipData.Item item = mClip.getItemAt(i); + if (itemPredicate.test(item)) { + accepted.add(item); + } else { + remaining.add(item); + } + } + Map<Boolean, ContentInfo> result = new ArrayMap<>(2); + if (!accepted.isEmpty()) { + ClipData acceptedClip = new ClipData(mClip.getDescription(), accepted); + result.put(true, new Builder(this).setClip(acceptedClip).build()); + } + if (!remaining.isEmpty()) { + ClipData remainingClip = new ClipData(mClip.getDescription(), remaining); + result.put(false, new Builder(this).setClip(remainingClip).build()); + } + return result; + } + + /** + * Builder for {@link ContentInfo}. + */ + public static final class Builder { + @NonNull + private ClipData mClip; + @Source + private int mSource; + @Flags + private int mFlags; + @Nullable + private Uri mLinkUri; + @Nullable + private Bundle mExtras; + + /** + * Creates a new builder initialized with the data from the given builder. + */ + public Builder(@NonNull ContentInfo other) { + mClip = other.mClip; + mSource = other.mSource; + mFlags = other.mFlags; + mLinkUri = other.mLinkUri; + mExtras = other.mExtras; + } + + /** + * Creates a new builder. + * @param clip The data to insert. + * @param source The source of the operation. See {@code SOURCE_} constants. + */ + public Builder(@NonNull ClipData clip, @Source int source) { + mClip = clip; + mSource = source; + } + + /** + * Sets the data to be inserted. + * @param clip The data to insert. + * @return this builder + */ + @NonNull + public Builder setClip(@NonNull ClipData clip) { + mClip = clip; + return this; + } + + /** + * Sets the source of the operation. + * @param source The source of the operation. See {@code SOURCE_} constants. + * @return this builder + */ + @NonNull + public Builder setSource(@Source int source) { + mSource = source; + return this; + } + + /** + * Sets flags that control content insertion behavior. + * @param flags Optional flags to configure the insertion behavior. Use 0 for default + * behavior. See {@code FLAG_} constants. + * @return this builder + */ + @NonNull + public Builder setFlags(@Flags int flags) { + mFlags = flags; + return this; + } + + /** + * Sets the http/https URI for the content. See + * {@link android.view.inputmethod.InputContentInfo#getLinkUri} for more info. + * @param linkUri Optional http/https URI for the content. + * @return this builder + */ + @NonNull + public Builder setLinkUri(@Nullable Uri linkUri) { + mLinkUri = linkUri; + return this; + } + + /** + * Sets additional metadata. + * @param extras Optional bundle with additional metadata. + * @return this builder + */ + @NonNull + public Builder setExtras(@Nullable Bundle extras) { + mExtras = extras; + return this; + } + + /** + * @return A new {@link ContentInfo} instance with the data from this builder. + */ + @NonNull + public ContentInfo build() { + return new ContentInfo(this); + } + } +} diff --git a/core/java/android/view/OnReceiveContentListener.java b/core/java/android/view/OnReceiveContentListener.java index db9c53863c7f..b551fa80b5cd 100644 --- a/core/java/android/view/OnReceiveContentListener.java +++ b/core/java/android/view/OnReceiveContentListener.java @@ -16,22 +16,8 @@ package android.view; -import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.content.ClipData; -import android.net.Uri; -import android.os.Bundle; -import android.util.ArrayMap; - -import com.android.internal.util.Preconditions; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.Map; -import java.util.Objects; -import java.util.function.Predicate; /** * Listener for apps to implement handling for insertion of content. Content may be both text and @@ -48,10 +34,13 @@ import java.util.function.Predicate; * public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"}; * * @Override - * public Payload onReceiveContent(View view, Payload payload) { - * Map<Boolean, Payload> split = payload.partition(item -> item.getUri() != null); - * if (split.get(true) != null) { - * ClipData clip = payload.getClip(); + * public ContentInfo onReceiveContent(View view, ContentInfo payload) { + * Map<Boolean, ContentInfo> split = + * payload.partition(item -> item.getUri() != null); + * ContentInfo uriItems = split.get(true); + * ContentInfo remainingItems = split.get(false); + * if (uriItems != null) { + * ClipData clip = uriItems.getClip(); * for (int i = 0; i < clip.getItemCount(); i++) { * Uri uri = clip.getItemAt(i).getUri(); * // ... app-specific logic to handle the URI ... @@ -59,7 +48,7 @@ import java.util.function.Predicate; * } * // Return anything that we didn't handle ourselves. This preserves the default platform * // behavior for text and anything else for which we are not implementing custom handling. - * return split.get(false); + * return remainingItems; * } * } * @@ -83,8 +72,8 @@ public interface OnReceiveContentListener { * handling. For example, an implementation may provide handling for content URIs (to provide * support for inserting images, etc) and delegate the processing of text to the platform to * preserve the common behavior for inserting text. See the class javadoc for a sample - * implementation and see {@link Payload#partition} for a convenient way to split the passed-in - * content. + * implementation and see {@link ContentInfo#partition} for a convenient way to split the + * passed-in content. * * <p>If implementing handling for text: if the view has a selection, the selection should * be overwritten by the passed-in content; if there's no selection, the passed-in content @@ -103,314 +92,6 @@ public interface OnReceiveContentListener { * succeed even if this method returns null. For example, an app may end up not inserting * an item if it exceeds the app's size limit for that type of content. */ - @Nullable Payload onReceiveContent(@NonNull View view, @NonNull Payload payload); - - /** - * Holds all the relevant data for a request to {@link OnReceiveContentListener}. - */ - final class Payload { - - /** - * Specifies the UI through which content is being inserted. Future versions of Android may - * support additional values. - * - * @hide - */ - @IntDef(prefix = {"SOURCE_"}, value = {SOURCE_APP, SOURCE_CLIPBOARD, SOURCE_INPUT_METHOD, - SOURCE_DRAG_AND_DROP, SOURCE_AUTOFILL, SOURCE_PROCESS_TEXT}) - @Retention(RetentionPolicy.SOURCE) - public @interface Source {} - - /** - * Specifies that the operation was triggered by the app that contains the target view. - */ - public static final int SOURCE_APP = 0; - - /** - * Specifies that the operation was triggered by a paste from the clipboard (e.g. "Paste" or - * "Paste as plain text" action in the insertion/selection menu). - */ - public static final int SOURCE_CLIPBOARD = 1; - - /** - * Specifies that the operation was triggered from the soft keyboard (also known as input - * method editor or IME). See https://developer.android.com/guide/topics/text/image-keyboard - * for more info. - */ - public static final int SOURCE_INPUT_METHOD = 2; - - /** - * Specifies that the operation was triggered by the drag/drop framework. See - * https://developer.android.com/guide/topics/ui/drag-drop for more info. - */ - public static final int SOURCE_DRAG_AND_DROP = 3; - - /** - * Specifies that the operation was triggered by the autofill framework. See - * https://developer.android.com/guide/topics/text/autofill for more info. - */ - public static final int SOURCE_AUTOFILL = 4; - - /** - * Specifies that the operation was triggered by a result from a - * {@link android.content.Intent#ACTION_PROCESS_TEXT PROCESS_TEXT} action in the selection - * menu. - */ - public static final int SOURCE_PROCESS_TEXT = 5; - - /** - * Returns the symbolic name of the given source. - * - * @hide - */ - static String sourceToString(@Source int source) { - switch (source) { - case SOURCE_APP: return "SOURCE_APP"; - case SOURCE_CLIPBOARD: return "SOURCE_CLIPBOARD"; - case SOURCE_INPUT_METHOD: return "SOURCE_INPUT_METHOD"; - case SOURCE_DRAG_AND_DROP: return "SOURCE_DRAG_AND_DROP"; - case SOURCE_AUTOFILL: return "SOURCE_AUTOFILL"; - case SOURCE_PROCESS_TEXT: return "SOURCE_PROCESS_TEXT"; - } - return String.valueOf(source); - } - - /** - * Flags to configure the insertion behavior. - * - * @hide - */ - @IntDef(flag = true, prefix = {"FLAG_"}, value = {FLAG_CONVERT_TO_PLAIN_TEXT}) - @Retention(RetentionPolicy.SOURCE) - public @interface Flags {} - - /** - * Flag requesting that the content should be converted to plain text prior to inserting. - */ - public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1 << 0; - - /** - * Returns the symbolic names of the set flags or {@code "0"} if no flags are set. - * - * @hide - */ - static String flagsToString(@Flags int flags) { - if ((flags & FLAG_CONVERT_TO_PLAIN_TEXT) != 0) { - return "FLAG_CONVERT_TO_PLAIN_TEXT"; - } - return String.valueOf(flags); - } - - @NonNull private final ClipData mClip; - private final @Source int mSource; - private final @Flags int mFlags; - @Nullable private final Uri mLinkUri; - @Nullable private final Bundle mExtras; - - private Payload(Builder b) { - this.mClip = Objects.requireNonNull(b.mClip); - this.mSource = Preconditions.checkArgumentInRange(b.mSource, 0, SOURCE_PROCESS_TEXT, - "source"); - this.mFlags = Preconditions.checkFlagsArgument(b.mFlags, FLAG_CONVERT_TO_PLAIN_TEXT); - this.mLinkUri = b.mLinkUri; - this.mExtras = b.mExtras; - } - - @NonNull - @Override - public String toString() { - return "Payload{" - + "clip=" + mClip - + ", source=" + sourceToString(mSource) - + ", flags=" + flagsToString(mFlags) - + ", linkUri=" + mLinkUri - + ", extras=" + mExtras - + "}"; - } - - /** - * The data to be inserted. - */ - public @NonNull ClipData getClip() { - return mClip; - } - - /** - * The source of the operation. See {@code SOURCE_} constants. Future versions of Android - * may pass additional values. - */ - public @Source int getSource() { - return mSource; - } - - /** - * Optional flags that control the insertion behavior. See {@code FLAG_} constants. - */ - public @Flags int getFlags() { - return mFlags; - } - - /** - * Optional http/https URI for the content that may be provided by the IME. This is only - * populated if the source is {@link #SOURCE_INPUT_METHOD} and if a non-empty - * {@link android.view.inputmethod.InputContentInfo#getLinkUri linkUri} was passed by the - * IME. - */ - public @Nullable Uri getLinkUri() { - return mLinkUri; - } - - /** - * Optional additional metadata. If the source is {@link #SOURCE_INPUT_METHOD}, this will - * include the {@link android.view.inputmethod.InputConnection#commitContent opts} passed by - * the IME. - */ - public @Nullable Bundle getExtras() { - return mExtras; - } - - /** - * Partitions this payload based on the given predicate. - * - * <p>Similar to a - * {@link java.util.stream.Collectors#partitioningBy(Predicate) partitioning collector}, - * this function classifies the content in this payload and organizes it into a map, - * grouping the content that matched vs didn't match the predicate. - * - * <p>Except for the {@link ClipData} items, the returned payloads will contain all the same - * metadata as the original payload. - * - * @param itemPredicate The predicate to test each {@link ClipData.Item} to determine which - * partition to place it into. - * @return A map containing the partitioned content. The map will contain a single entry if - * all items were classified into the same partition (all matched or all didn't match the - * predicate) or two entries (if there's at least one item that matched the predicate and at - * least one item that didn't match the predicate). - */ - public @NonNull Map<Boolean, Payload> partition( - @NonNull Predicate<ClipData.Item> itemPredicate) { - if (mClip.getItemCount() == 1) { - Map<Boolean, Payload> result = new ArrayMap<>(1); - result.put(itemPredicate.test(mClip.getItemAt(0)), this); - return result; - } - ArrayList<ClipData.Item> accepted = new ArrayList<>(); - ArrayList<ClipData.Item> remaining = new ArrayList<>(); - for (int i = 0; i < mClip.getItemCount(); i++) { - ClipData.Item item = mClip.getItemAt(i); - if (itemPredicate.test(item)) { - accepted.add(item); - } else { - remaining.add(item); - } - } - Map<Boolean, Payload> result = new ArrayMap<>(2); - if (!accepted.isEmpty()) { - ClipData acceptedClip = new ClipData(mClip.getDescription(), accepted); - result.put(true, new Builder(this).setClip(acceptedClip).build()); - } - if (!remaining.isEmpty()) { - ClipData remainingClip = new ClipData(mClip.getDescription(), remaining); - result.put(false, new Builder(this).setClip(remainingClip).build()); - } - return result; - } - - /** - * Builder for {@link Payload}. - */ - public static final class Builder { - @NonNull private ClipData mClip; - private @Source int mSource; - private @Flags int mFlags; - @Nullable private Uri mLinkUri; - @Nullable private Bundle mExtras; - - /** - * Creates a new builder initialized with the data from the given builder. - */ - public Builder(@NonNull Payload payload) { - mClip = payload.mClip; - mSource = payload.mSource; - mFlags = payload.mFlags; - mLinkUri = payload.mLinkUri; - mExtras = payload.mExtras; - } - - /** - * Creates a new builder. - * @param clip The data to insert. - * @param source The source of the operation. See {@code SOURCE_} constants. - */ - public Builder(@NonNull ClipData clip, @Source int source) { - mClip = clip; - mSource = source; - } - - /** - * Sets the data to be inserted. - * @param clip The data to insert. - * @return this builder - */ - @NonNull - public Builder setClip(@NonNull ClipData clip) { - mClip = clip; - return this; - } - - /** - * Sets the source of the operation. - * @param source The source of the operation. See {@code SOURCE_} constants. - * @return this builder - */ - @NonNull - public Builder setSource(@Source int source) { - mSource = source; - return this; - } - - /** - * Sets flags that control content insertion behavior. - * @param flags Optional flags to configure the insertion behavior. Use 0 for default - * behavior. See {@code FLAG_} constants. - * @return this builder - */ - @NonNull - public Builder setFlags(@Flags int flags) { - mFlags = flags; - return this; - } - - /** - * Sets the http/https URI for the content. See - * {@link android.view.inputmethod.InputContentInfo#getLinkUri} for more info. - * @param linkUri Optional http/https URI for the content. - * @return this builder - */ - @NonNull - public Builder setLinkUri(@Nullable Uri linkUri) { - mLinkUri = linkUri; - return this; - } - - /** - * Sets additional metadata. - * @param extras Optional bundle with additional metadata. - * @return this builder - */ - @NonNull - public Builder setExtras(@Nullable Bundle extras) { - mExtras = extras; - return this; - } - - /** - * @return A new {@link Payload} instance with the data from this builder. - */ - @NonNull - public Payload build() { - return new Payload(this); - } - } - } + @Nullable + ContentInfo onReceiveContent(@NonNull View view, @NonNull ContentInfo payload); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 30ec2b050dbe..a5c66537b11f 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -112,7 +112,6 @@ import android.view.AccessibilityIterators.TextSegmentIterator; import android.view.AccessibilityIterators.WordTextSegmentIterator; import android.view.ContextMenu.ContextMenuInfo; import android.view.InputDevice.InputSourceClass; -import android.view.OnReceiveContentListener.Payload; import android.view.Window.OnContentApplyWindowInsetsListener; import android.view.WindowInsets.Type; import android.view.WindowInsetsAnimation.Bounds; @@ -9063,11 +9062,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return The portion of the passed-in content that was not accepted (may be all, some, or none * of the passed-in content). */ - public @Nullable Payload performReceiveContent(@NonNull Payload payload) { + @Nullable + public ContentInfo performReceiveContent(@NonNull ContentInfo payload) { final OnReceiveContentListener listener = (mListenerInfo == null) ? null : getListenerInfo().mOnReceiveContentListener; if (listener != null) { - final Payload remaining = listener.onReceiveContent(this, payload); + final ContentInfo remaining = listener.onReceiveContent(this, payload); return (remaining == null) ? null : onReceiveContent(remaining); } return onReceiveContent(payload); @@ -9088,7 +9088,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return The portion of the passed-in content that was not handled (may be all, some, or none * of the passed-in content). */ - public @Nullable Payload onReceiveContent(@NonNull Payload payload) { + @Nullable + public ContentInfo onReceiveContent(@NonNull ContentInfo payload) { return payload; } @@ -9113,7 +9114,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return The MIME types accepted by {@link #performReceiveContent} for this view (may * include patterns such as "image/*"). */ - public @Nullable String[] getOnReceiveContentMimeTypes() { + @Nullable + public String[] getOnReceiveContentMimeTypes() { return mOnReceiveContentMimeTypes; } diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 8fdcac7b4f9d..364ae8186e54 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -19,7 +19,7 @@ package android.view.autofill; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE; import static android.service.autofill.FillRequest.FLAG_VIEW_NOT_FOCUSED; -import static android.view.OnReceiveContentListener.Payload.SOURCE_AUTOFILL; +import static android.view.ContentInfo.SOURCE_AUTOFILL; import static android.view.autofill.Helper.sDebug; import static android.view.autofill.Helper.sVerbose; import static android.view.autofill.Helper.toList; @@ -61,8 +61,8 @@ import android.util.Log; import android.util.Slog; import android.util.SparseArray; import android.view.Choreographer; +import android.view.ContentInfo; import android.view.KeyEvent; -import android.view.OnReceiveContentListener.Payload; import android.view.View; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; @@ -2371,8 +2371,8 @@ public final class AutofillManager { reportAutofillContentFailure(id); return; } - Payload payload = new Payload.Builder(clip, SOURCE_AUTOFILL).build(); - Payload result = view.performReceiveContent(payload); + ContentInfo payload = new ContentInfo.Builder(clip, SOURCE_AUTOFILL).build(); + ContentInfo result = view.performReceiveContent(payload); if (result != null) { Log.w(TAG, "autofillContent(): receiver could not insert content: id=" + id + ", view=" + view + ", clip=" + clip); diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java index 1ab9edf0caa2..f057c1239e52 100644 --- a/core/java/android/view/inputmethod/BaseInputConnection.java +++ b/core/java/android/view/inputmethod/BaseInputConnection.java @@ -16,7 +16,7 @@ package android.view.inputmethod; -import static android.view.OnReceiveContentListener.Payload.SOURCE_INPUT_METHOD; +import static android.view.ContentInfo.SOURCE_INPUT_METHOD; import android.annotation.CallSuper; import android.annotation.IntRange; @@ -38,9 +38,9 @@ import android.text.TextUtils; import android.text.method.MetaKeyKeyListener; import android.util.Log; import android.util.LogPrinter; +import android.view.ContentInfo; import android.view.KeyCharacterMap; import android.view.KeyEvent; -import android.view.OnReceiveContentListener; import android.view.View; import com.android.internal.util.Preconditions; @@ -952,8 +952,8 @@ public class BaseInputConnection implements InputConnection { } final ClipData clip = new ClipData(inputContentInfo.getDescription(), new ClipData.Item(inputContentInfo.getContentUri())); - final OnReceiveContentListener.Payload payload = - new OnReceiveContentListener.Payload.Builder(clip, SOURCE_INPUT_METHOD) + final ContentInfo payload = + new ContentInfo.Builder(clip, SOURCE_INPUT_METHOD) .setLinkUri(inputContentInfo.getLinkUri()) .setExtras(opts) .build(); diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 00ba326d2ba9..0025d1e2a853 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -16,7 +16,7 @@ package android.widget; -import static android.view.OnReceiveContentListener.Payload.SOURCE_DRAG_AND_DROP; +import static android.view.ContentInfo.SOURCE_DRAG_AND_DROP; import android.R; import android.animation.ValueAnimator; @@ -87,6 +87,7 @@ import android.util.SparseArray; import android.util.TypedValue; import android.view.ActionMode; import android.view.ActionMode.Callback; +import android.view.ContentInfo; import android.view.ContextMenu; import android.view.ContextThemeWrapper; import android.view.DragAndDropPermissions; @@ -98,7 +99,6 @@ import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; -import android.view.OnReceiveContentListener; import android.view.SubMenu; import android.view.View; import android.view.View.DragShadowBuilder; @@ -2869,8 +2869,8 @@ public class Editor { final int originalLength = mTextView.getText().length(); Selection.setSelection((Spannable) mTextView.getText(), offset); final ClipData clip = event.getClipData(); - final OnReceiveContentListener.Payload payload = - new OnReceiveContentListener.Payload.Builder(clip, SOURCE_DRAG_AND_DROP) + final ContentInfo payload = + new ContentInfo.Builder(clip, SOURCE_DRAG_AND_DROP) .build(); mTextView.performReceiveContent(payload); if (dragDropIntoItself) { diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 98f808784803..2357f368c428 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -17,10 +17,10 @@ package android.widget; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; -import static android.view.OnReceiveContentListener.Payload.FLAG_CONVERT_TO_PLAIN_TEXT; -import static android.view.OnReceiveContentListener.Payload.SOURCE_AUTOFILL; -import static android.view.OnReceiveContentListener.Payload.SOURCE_CLIPBOARD; -import static android.view.OnReceiveContentListener.Payload.SOURCE_PROCESS_TEXT; +import static android.view.ContentInfo.FLAG_CONVERT_TO_PLAIN_TEXT; +import static android.view.ContentInfo.SOURCE_AUTOFILL; +import static android.view.ContentInfo.SOURCE_CLIPBOARD; +import static android.view.ContentInfo.SOURCE_PROCESS_TEXT; import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_RENDERING_INFO_KEY; import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH; import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX; @@ -146,6 +146,7 @@ import android.util.TypedValue; import android.view.AccessibilityIterators.TextSegmentIterator; import android.view.ActionMode; import android.view.Choreographer; +import android.view.ContentInfo; import android.view.ContextMenu; import android.view.DragEvent; import android.view.Gravity; @@ -154,7 +155,6 @@ import android.view.InputDevice; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.MotionEvent; -import android.view.OnReceiveContentListener.Payload; import android.view.PointerIcon; import android.view.View; import android.view.ViewConfiguration; @@ -2151,7 +2151,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (result != null) { if (isTextEditable()) { ClipData clip = ClipData.newPlainText("", result); - Payload payload = new Payload.Builder(clip, SOURCE_PROCESS_TEXT).build(); + ContentInfo payload = + new ContentInfo.Builder(clip, SOURCE_PROCESS_TEXT).build(); performReceiveContent(payload); if (mEditor != null) { mEditor.refreshTextActionMode(); @@ -11857,7 +11858,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener + " cannot be autofilled into " + this); return; } - final Payload payload = new Payload.Builder(clip, SOURCE_AUTOFILL).build(); + final ContentInfo payload = new ContentInfo.Builder(clip, SOURCE_AUTOFILL).build(); performReceiveContent(payload); } @@ -12924,7 +12925,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (clip == null) { return; } - final Payload payload = new Payload.Builder(clip, SOURCE_CLIPBOARD) + final ContentInfo payload = new ContentInfo.Builder(clip, SOURCE_CLIPBOARD) .setFlags(withFormatting ? 0 : FLAG_CONVERT_TO_PLAIN_TEXT) .build(); performReceiveContent(payload); @@ -13740,8 +13741,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * @return The portion of the passed-in content that was not handled (may be all, some, or none * of the passed-in content). */ + @Nullable @Override - public @Nullable Payload onReceiveContent(@NonNull Payload payload) { + public ContentInfo onReceiveContent(@NonNull ContentInfo payload) { if (mEditor != null) { return mEditor.getDefaultOnReceiveContentListener().onReceiveContent(this, payload); } diff --git a/core/java/android/widget/TextViewOnReceiveContentListener.java b/core/java/android/widget/TextViewOnReceiveContentListener.java index 7ef68ec7a4ee..8cef1061c423 100644 --- a/core/java/android/widget/TextViewOnReceiveContentListener.java +++ b/core/java/android/widget/TextViewOnReceiveContentListener.java @@ -17,10 +17,10 @@ package android.widget; import static android.content.ContentResolver.SCHEME_CONTENT; -import static android.view.OnReceiveContentListener.Payload.FLAG_CONVERT_TO_PLAIN_TEXT; -import static android.view.OnReceiveContentListener.Payload.SOURCE_AUTOFILL; -import static android.view.OnReceiveContentListener.Payload.SOURCE_DRAG_AND_DROP; -import static android.view.OnReceiveContentListener.Payload.SOURCE_INPUT_METHOD; +import static android.view.ContentInfo.FLAG_CONVERT_TO_PLAIN_TEXT; +import static android.view.ContentInfo.SOURCE_AUTOFILL; +import static android.view.ContentInfo.SOURCE_DRAG_AND_DROP; +import static android.view.ContentInfo.SOURCE_INPUT_METHOD; import android.annotation.NonNull; import android.annotation.Nullable; @@ -38,9 +38,10 @@ import android.text.Selection; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.util.Log; +import android.view.ContentInfo; +import android.view.ContentInfo.Flags; +import android.view.ContentInfo.Source; import android.view.OnReceiveContentListener; -import android.view.OnReceiveContentListener.Payload.Flags; -import android.view.OnReceiveContentListener.Payload.Source; import android.view.View; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; @@ -53,20 +54,21 @@ import java.util.ArrayList; import java.util.Arrays; /** - * Default implementation of {@link OnReceiveContentListener} for editable - * {@link TextView} components. This class handles insertion of text (plain text, styled text, HTML, - * etc) but not images or other content. + * Default implementation for {@link View#onReceiveContent} for editable {@link TextView} + * components. This class handles insertion of text (plain text, styled text, HTML, etc) but not + * images or other content. * * @hide */ @VisibleForTesting public final class TextViewOnReceiveContentListener implements OnReceiveContentListener { - private static final String LOG_TAG = "OnReceiveContent"; + private static final String LOG_TAG = "ReceiveContent"; @Nullable private InputConnectionInfo mInputConnectionInfo; + @Nullable @Override - public @Nullable Payload onReceiveContent(@NonNull View view, @NonNull Payload payload) { + public ContentInfo onReceiveContent(@NonNull View view, @NonNull ContentInfo payload) { if (Log.isLoggable(LOG_TAG, Log.DEBUG)) { Log.d(LOG_TAG, "onReceive: " + payload); } @@ -126,7 +128,7 @@ public final class TextViewOnReceiveContentListener implements OnReceiveContentL editable.replace(start, end, replacement); } - private void onReceiveForAutofill(@NonNull TextView view, @NonNull Payload payload) { + private void onReceiveForAutofill(@NonNull TextView view, @NonNull ContentInfo payload) { ClipData clip = payload.getClip(); if (isUsageOfImeCommitContentEnabled(view)) { clip = handleNonTextViaImeCommitContent(clip); @@ -145,7 +147,8 @@ public final class TextViewOnReceiveContentListener implements OnReceiveContentL Selection.setSelection(editable, editable.length()); } - private static void onReceiveForDragAndDrop(@NonNull TextView view, @NonNull Payload payload) { + private static void onReceiveForDragAndDrop(@NonNull TextView view, + @NonNull ContentInfo payload) { final CharSequence text = coerceToText(payload.getClip(), view.getContext(), payload.getFlags()); replaceSelection((Editable) view.getText(), text); |
