Loading core/api/current.txt +1 −1 Original line number Original line Diff line number Diff line Loading @@ -50893,7 +50893,7 @@ package android.view { method public int getFlags(); method public int getFlags(); method @Nullable public android.net.Uri getLinkUri(); method @Nullable public android.net.Uri getLinkUri(); method public int getSource(); method public int getSource(); method @NonNull public java.util.Map<java.lang.Boolean,android.view.ContentInfo> partition(@NonNull java.util.function.Predicate<android.content.ClipData.Item>); method @NonNull public android.util.Pair<android.view.ContentInfo,android.view.ContentInfo> partition(@NonNull java.util.function.Predicate<android.content.ClipData.Item>); field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1 field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1 field public static final int SOURCE_APP = 0; // 0x0 field public static final int SOURCE_APP = 0; // 0x0 field public static final int SOURCE_AUTOFILL = 4; // 0x4 field public static final int SOURCE_AUTOFILL = 4; // 0x4 core/java/android/view/ContentInfo.java +30 −29 Original line number Original line Diff line number Diff line Loading @@ -20,16 +20,16 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.content.ClipData; import android.content.ClipData; import android.content.ClipDescription; import android.net.Uri; import android.net.Uri; import android.os.Bundle; import android.os.Bundle; import android.util.ArrayMap; import android.util.Pair; import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.ArrayList; import java.util.Map; import java.util.Objects; import java.util.Objects; import java.util.function.Predicate; import java.util.function.Predicate; Loading Loading @@ -208,50 +208,51 @@ public final class ContentInfo { } } /** /** * Partitions the content based on the given predicate. * Partitions this content based on the given predicate. * * * <p>Similar to a * <p>This function classifies the content and organizes it into a pair, grouping the items * {@link java.util.stream.Collectors#partitioningBy(Predicate) partitioning collector}, * that matched vs didn't match the predicate. * 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 * <p>Except for the {@link ClipData} items, the returned objects will contain all the same * metadata as the original. * metadata as this {@link ContentInfo}. * * * @param itemPredicate The predicate to test each {@link ClipData.Item} to determine which * @param itemPredicate The predicate to test each {@link ClipData.Item} to determine which * partition to place it into. * partition to place it into. * @return A map containing the partitioned content. The map will contain a single entry if * @return A pair containing the partitioned content. The pair's first object will have the * all items were classified into the same partition (all matched or all didn't match the * content that matched the predicate, or null if none of the items matched. The pair's * predicate) or two entries (if there's at least one item that matched the predicate and at * second object will have the content that didn't match the predicate, or null if all of * least one item that didn't match the predicate). * the items matched. */ */ @NonNull @NonNull public Map<Boolean, ContentInfo> partition(@NonNull Predicate<ClipData.Item> itemPredicate) { public Pair<ContentInfo, ContentInfo> partition( @NonNull Predicate<ClipData.Item> itemPredicate) { if (mClip.getItemCount() == 1) { if (mClip.getItemCount() == 1) { Map<Boolean, ContentInfo> result = new ArrayMap<>(1); boolean matched = itemPredicate.test(mClip.getItemAt(0)); result.put(itemPredicate.test(mClip.getItemAt(0)), this); return Pair.create(matched ? this : null, matched ? null : this); return result; } } ArrayList<ClipData.Item> accepted = new ArrayList<>(); ArrayList<ClipData.Item> acceptedItems = new ArrayList<>(); ArrayList<ClipData.Item> remaining = new ArrayList<>(); ArrayList<ClipData.Item> remainingItems = new ArrayList<>(); for (int i = 0; i < mClip.getItemCount(); i++) { for (int i = 0; i < mClip.getItemCount(); i++) { ClipData.Item item = mClip.getItemAt(i); ClipData.Item item = mClip.getItemAt(i); if (itemPredicate.test(item)) { if (itemPredicate.test(item)) { accepted.add(item); acceptedItems.add(item); } else { } else { remaining.add(item); remainingItems.add(item); } } } } Map<Boolean, ContentInfo> result = new ArrayMap<>(2); if (acceptedItems.isEmpty()) { if (!accepted.isEmpty()) { return Pair.create(null, this); ClipData acceptedClip = new ClipData(mClip.getDescription(), accepted); result.put(true, new Builder(this).setClip(acceptedClip).build()); } } if (!remaining.isEmpty()) { if (remainingItems.isEmpty()) { ClipData remainingClip = new ClipData(mClip.getDescription(), remaining); return Pair.create(this, null); result.put(false, new Builder(this).setClip(remainingClip).build()); } } return result; ContentInfo accepted = new Builder(this) .setClip(new ClipData(new ClipDescription(mClip.getDescription()), acceptedItems)) .build(); ContentInfo remaining = new Builder(this) .setClip(new ClipData(new ClipDescription(mClip.getDescription()), remainingItems)) .build(); return Pair.create(accepted, remaining); } } /** /** Loading core/java/android/view/OnReceiveContentListener.java +6 −6 Original line number Original line Diff line number Diff line Loading @@ -35,12 +35,12 @@ import android.annotation.Nullable; * * * @Override * @Override * public ContentInfo onReceiveContent(View view, ContentInfo payload) { * public ContentInfo onReceiveContent(View view, ContentInfo payload) { * Map<Boolean, ContentInfo> split = * Pair<ContentInfo, ContentInfo> split = * payload.partition(item -> item.getUri() != null); * payload.partition(item -> item.getUri() != null); * ContentInfo uriItems = split.get(true); * ContentInfo uriContent = split.first; * ContentInfo remainingItems = split.get(false); * ContentInfo remaining = split.second; * if (uriItems != null) { * if (uriContent != null) { * ClipData clip = uriItems.getClip(); * ClipData clip = uriContent.getClip(); * for (int i = 0; i < clip.getItemCount(); i++) { * for (int i = 0; i < clip.getItemCount(); i++) { * Uri uri = clip.getItemAt(i).getUri(); * Uri uri = clip.getItemAt(i).getUri(); * // ... app-specific logic to handle the URI ... * // ... app-specific logic to handle the URI ... Loading @@ -48,7 +48,7 @@ import android.annotation.Nullable; * } * } * // Return anything that we didn't handle ourselves. This preserves the default platform * // 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. * // behavior for text and anything else for which we are not implementing custom handling. * return remainingItems; * return remaining; * } * } * } * } * * Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +8 −8 Original line number Original line Diff line number Diff line Loading @@ -42,6 +42,7 @@ import android.text.SpannedString; import android.text.TextWatcher; import android.text.TextWatcher; import android.util.AttributeSet; import android.util.AttributeSet; import android.util.Log; import android.util.Log; import android.util.Pair; import android.view.ContentInfo; import android.view.ContentInfo; import android.view.KeyEvent; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.LayoutInflater; Loading Loading @@ -75,7 +76,6 @@ import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.LightBarController; import com.android.systemui.statusbar.phone.LightBarController; import java.util.HashMap; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; import java.util.function.Consumer; /** /** Loading Loading @@ -593,16 +593,16 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene @Nullable @Nullable public ContentInfo onReceiveContent(@NonNull View view, public ContentInfo onReceiveContent(@NonNull View view, @NonNull ContentInfo payload) { @NonNull ContentInfo payload) { Map<Boolean, ContentInfo> split = payload.partition( Pair<ContentInfo, ContentInfo> split = payload.partition( item -> item.getUri() != null); item -> item.getUri() != null); ContentInfo uriItems = split.get(true); ContentInfo uriContent = split.first; ContentInfo remainingItems = split.get(false); ContentInfo remaining = split.second; if (uriItems != null) { if (uriContent != null) { ClipData clip = uriItems.getClip(); ClipData clip = uriContent.getClip(); ClipDescription description = clip.getDescription(); ClipDescription description = clip.getDescription(); if (clip.getItemCount() > 1 if (clip.getItemCount() > 1 || description.getMimeTypeCount() < 1 || description.getMimeTypeCount() < 1 || remainingItems != null) { || remaining != null) { // TODO(b/172363500): Update to loop over all the items // TODO(b/172363500): Update to loop over all the items return payload; return payload; } } Loading @@ -612,7 +612,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene .prepareRemoteInputFromData(mimeType, contentUri); .prepareRemoteInputFromData(mimeType, contentUri); mRemoteInputView.sendRemoteInput(dataIntent); mRemoteInputView.sendRemoteInput(dataIntent); } } return remainingItems; return remaining; } } }); }); } } Loading Loading
core/api/current.txt +1 −1 Original line number Original line Diff line number Diff line Loading @@ -50893,7 +50893,7 @@ package android.view { method public int getFlags(); method public int getFlags(); method @Nullable public android.net.Uri getLinkUri(); method @Nullable public android.net.Uri getLinkUri(); method public int getSource(); method public int getSource(); method @NonNull public java.util.Map<java.lang.Boolean,android.view.ContentInfo> partition(@NonNull java.util.function.Predicate<android.content.ClipData.Item>); method @NonNull public android.util.Pair<android.view.ContentInfo,android.view.ContentInfo> partition(@NonNull java.util.function.Predicate<android.content.ClipData.Item>); field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1 field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1 field public static final int SOURCE_APP = 0; // 0x0 field public static final int SOURCE_APP = 0; // 0x0 field public static final int SOURCE_AUTOFILL = 4; // 0x4 field public static final int SOURCE_AUTOFILL = 4; // 0x4
core/java/android/view/ContentInfo.java +30 −29 Original line number Original line Diff line number Diff line Loading @@ -20,16 +20,16 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.content.ClipData; import android.content.ClipData; import android.content.ClipDescription; import android.net.Uri; import android.net.Uri; import android.os.Bundle; import android.os.Bundle; import android.util.ArrayMap; import android.util.Pair; import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.ArrayList; import java.util.Map; import java.util.Objects; import java.util.Objects; import java.util.function.Predicate; import java.util.function.Predicate; Loading Loading @@ -208,50 +208,51 @@ public final class ContentInfo { } } /** /** * Partitions the content based on the given predicate. * Partitions this content based on the given predicate. * * * <p>Similar to a * <p>This function classifies the content and organizes it into a pair, grouping the items * {@link java.util.stream.Collectors#partitioningBy(Predicate) partitioning collector}, * that matched vs didn't match the predicate. * 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 * <p>Except for the {@link ClipData} items, the returned objects will contain all the same * metadata as the original. * metadata as this {@link ContentInfo}. * * * @param itemPredicate The predicate to test each {@link ClipData.Item} to determine which * @param itemPredicate The predicate to test each {@link ClipData.Item} to determine which * partition to place it into. * partition to place it into. * @return A map containing the partitioned content. The map will contain a single entry if * @return A pair containing the partitioned content. The pair's first object will have the * all items were classified into the same partition (all matched or all didn't match the * content that matched the predicate, or null if none of the items matched. The pair's * predicate) or two entries (if there's at least one item that matched the predicate and at * second object will have the content that didn't match the predicate, or null if all of * least one item that didn't match the predicate). * the items matched. */ */ @NonNull @NonNull public Map<Boolean, ContentInfo> partition(@NonNull Predicate<ClipData.Item> itemPredicate) { public Pair<ContentInfo, ContentInfo> partition( @NonNull Predicate<ClipData.Item> itemPredicate) { if (mClip.getItemCount() == 1) { if (mClip.getItemCount() == 1) { Map<Boolean, ContentInfo> result = new ArrayMap<>(1); boolean matched = itemPredicate.test(mClip.getItemAt(0)); result.put(itemPredicate.test(mClip.getItemAt(0)), this); return Pair.create(matched ? this : null, matched ? null : this); return result; } } ArrayList<ClipData.Item> accepted = new ArrayList<>(); ArrayList<ClipData.Item> acceptedItems = new ArrayList<>(); ArrayList<ClipData.Item> remaining = new ArrayList<>(); ArrayList<ClipData.Item> remainingItems = new ArrayList<>(); for (int i = 0; i < mClip.getItemCount(); i++) { for (int i = 0; i < mClip.getItemCount(); i++) { ClipData.Item item = mClip.getItemAt(i); ClipData.Item item = mClip.getItemAt(i); if (itemPredicate.test(item)) { if (itemPredicate.test(item)) { accepted.add(item); acceptedItems.add(item); } else { } else { remaining.add(item); remainingItems.add(item); } } } } Map<Boolean, ContentInfo> result = new ArrayMap<>(2); if (acceptedItems.isEmpty()) { if (!accepted.isEmpty()) { return Pair.create(null, this); ClipData acceptedClip = new ClipData(mClip.getDescription(), accepted); result.put(true, new Builder(this).setClip(acceptedClip).build()); } } if (!remaining.isEmpty()) { if (remainingItems.isEmpty()) { ClipData remainingClip = new ClipData(mClip.getDescription(), remaining); return Pair.create(this, null); result.put(false, new Builder(this).setClip(remainingClip).build()); } } return result; ContentInfo accepted = new Builder(this) .setClip(new ClipData(new ClipDescription(mClip.getDescription()), acceptedItems)) .build(); ContentInfo remaining = new Builder(this) .setClip(new ClipData(new ClipDescription(mClip.getDescription()), remainingItems)) .build(); return Pair.create(accepted, remaining); } } /** /** Loading
core/java/android/view/OnReceiveContentListener.java +6 −6 Original line number Original line Diff line number Diff line Loading @@ -35,12 +35,12 @@ import android.annotation.Nullable; * * * @Override * @Override * public ContentInfo onReceiveContent(View view, ContentInfo payload) { * public ContentInfo onReceiveContent(View view, ContentInfo payload) { * Map<Boolean, ContentInfo> split = * Pair<ContentInfo, ContentInfo> split = * payload.partition(item -> item.getUri() != null); * payload.partition(item -> item.getUri() != null); * ContentInfo uriItems = split.get(true); * ContentInfo uriContent = split.first; * ContentInfo remainingItems = split.get(false); * ContentInfo remaining = split.second; * if (uriItems != null) { * if (uriContent != null) { * ClipData clip = uriItems.getClip(); * ClipData clip = uriContent.getClip(); * for (int i = 0; i < clip.getItemCount(); i++) { * for (int i = 0; i < clip.getItemCount(); i++) { * Uri uri = clip.getItemAt(i).getUri(); * Uri uri = clip.getItemAt(i).getUri(); * // ... app-specific logic to handle the URI ... * // ... app-specific logic to handle the URI ... Loading @@ -48,7 +48,7 @@ import android.annotation.Nullable; * } * } * // Return anything that we didn't handle ourselves. This preserves the default platform * // 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. * // behavior for text and anything else for which we are not implementing custom handling. * return remainingItems; * return remaining; * } * } * } * } * * Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +8 −8 Original line number Original line Diff line number Diff line Loading @@ -42,6 +42,7 @@ import android.text.SpannedString; import android.text.TextWatcher; import android.text.TextWatcher; import android.util.AttributeSet; import android.util.AttributeSet; import android.util.Log; import android.util.Log; import android.util.Pair; import android.view.ContentInfo; import android.view.ContentInfo; import android.view.KeyEvent; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.LayoutInflater; Loading Loading @@ -75,7 +76,6 @@ import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.LightBarController; import com.android.systemui.statusbar.phone.LightBarController; import java.util.HashMap; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; import java.util.function.Consumer; /** /** Loading Loading @@ -593,16 +593,16 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene @Nullable @Nullable public ContentInfo onReceiveContent(@NonNull View view, public ContentInfo onReceiveContent(@NonNull View view, @NonNull ContentInfo payload) { @NonNull ContentInfo payload) { Map<Boolean, ContentInfo> split = payload.partition( Pair<ContentInfo, ContentInfo> split = payload.partition( item -> item.getUri() != null); item -> item.getUri() != null); ContentInfo uriItems = split.get(true); ContentInfo uriContent = split.first; ContentInfo remainingItems = split.get(false); ContentInfo remaining = split.second; if (uriItems != null) { if (uriContent != null) { ClipData clip = uriItems.getClip(); ClipData clip = uriContent.getClip(); ClipDescription description = clip.getDescription(); ClipDescription description = clip.getDescription(); if (clip.getItemCount() > 1 if (clip.getItemCount() > 1 || description.getMimeTypeCount() < 1 || description.getMimeTypeCount() < 1 || remainingItems != null) { || remaining != null) { // TODO(b/172363500): Update to loop over all the items // TODO(b/172363500): Update to loop over all the items return payload; return payload; } } Loading @@ -612,7 +612,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene .prepareRemoteInputFromData(mimeType, contentUri); .prepareRemoteInputFromData(mimeType, contentUri); mRemoteInputView.sendRemoteInput(dataIntent); mRemoteInputView.sendRemoteInput(dataIntent); } } return remainingItems; return remaining; } } }); }); } } Loading