summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorNikita Dubrovsky <dubrovsky@google.com>2020-11-30 22:33:03 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-11-30 22:33:03 +0000
commit83de85f7b6c8ceead887434d162abf578dc529ee (patch)
treea0dfa825d6a64deeda12487c38725a17725e4846 /core/java
parent0a993aac9ad03628d0efcf47fb702c230caee93a (diff)
parent10f027f69f21c59d29358b8ec5978595b64c3dbf (diff)
Merge "Move/rename OnReceiveContentListener.Payload to android.view.ContentInfo"
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/view/ContentInfo.java358
-rw-r--r--core/java/android/view/OnReceiveContentListener.java343
-rw-r--r--core/java/android/view/View.java12
-rw-r--r--core/java/android/view/autofill/AutofillManager.java8
-rw-r--r--core/java/android/view/inputmethod/BaseInputConnection.java8
-rw-r--r--core/java/android/widget/Editor.java8
-rw-r--r--core/java/android/widget/TextView.java20
-rw-r--r--core/java/android/widget/TextViewOnReceiveContentListener.java29
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/*"};
*
* &#64;Override
- * public Payload onReceiveContent(View view, Payload payload) {
- * Map&lt;Boolean, Payload&gt; split = payload.partition(item -&gt; item.getUri() != null);
- * if (split.get(true) != null) {
- * ClipData clip = payload.getClip();
+ * public ContentInfo onReceiveContent(View view, ContentInfo payload) {
+ * Map&lt;Boolean, ContentInfo&gt; split =
+ * payload.partition(item -&gt; 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);