diff options
5 files changed, 67 insertions, 7 deletions
diff --git a/core/java/android/view/ContentInfo.java b/core/java/android/view/ContentInfo.java index 547bc9d49380..b55d9b3a1913 100644 --- a/core/java/android/view/ContentInfo.java +++ b/core/java/android/view/ContentInfo.java @@ -26,6 +26,7 @@ import android.content.ClipDescription; import android.net.Uri; import android.os.Bundle; import android.util.Pair; +import android.view.inputmethod.InputContentInfo; import com.android.internal.util.Preconditions; @@ -141,6 +142,10 @@ public final class ContentInfo { private final Uri mLinkUri; @Nullable private final Bundle mExtras; + @Nullable + private final InputContentInfo mInputContentInfo; + @Nullable + private final DragAndDropPermissions mDragAndDropPermissions; private ContentInfo(Builder b) { this.mClip = Objects.requireNonNull(b.mClip); @@ -149,6 +154,23 @@ public final class ContentInfo { this.mFlags = Preconditions.checkFlagsArgument(b.mFlags, FLAG_CONVERT_TO_PLAIN_TEXT); this.mLinkUri = b.mLinkUri; this.mExtras = b.mExtras; + this.mInputContentInfo = b.mInputContentInfo; + this.mDragAndDropPermissions = b.mDragAndDropPermissions; + } + + /** + * If the content came from a source that supports proactive release of URI permissions + * (e.g. IME), releases permissions; otherwise a no-op. + * + * @hide + */ + public void releasePermissions() { + if (mInputContentInfo != null) { + mInputContentInfo.releasePermission(); + } + if (mDragAndDropPermissions != null) { + mDragAndDropPermissions.release(); + } } @NonNull @@ -275,6 +297,10 @@ public final class ContentInfo { private Uri mLinkUri; @Nullable private Bundle mExtras; + @Nullable + private InputContentInfo mInputContentInfo; + @Nullable + private DragAndDropPermissions mDragAndDropPermissions; /** * Creates a new builder initialized with the data from the given builder. @@ -285,6 +311,8 @@ public final class ContentInfo { mFlags = other.mFlags; mLinkUri = other.mLinkUri; mExtras = other.mExtras; + mInputContentInfo = other.mInputContentInfo; + mDragAndDropPermissions = other.mDragAndDropPermissions; } /** @@ -355,6 +383,31 @@ public final class ContentInfo { } /** + * Set the {@link InputContentInfo} object if the content is coming from the IME. This can + * be used for proactive cleanup of permissions. + * + * @hide + */ + @NonNull + public Builder setInputContentInfo(@Nullable InputContentInfo inputContentInfo) { + mInputContentInfo = inputContentInfo; + return this; + } + + /** + * Set the {@link DragAndDropPermissions} object if the content is coming via drag-and-drop. + * This can be used for proactive cleanup of permissions. + * + * @hide + */ + @NonNull + public Builder setDragAndDropPermissions(@Nullable DragAndDropPermissions permissions) { + mDragAndDropPermissions = permissions; + return this; + } + + + /** * @return A new {@link ContentInfo} instance with the data from this builder. */ @NonNull diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 615dd82fb848..63a7dea058c8 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -26801,8 +26801,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (permissions != null) { permissions.takeTransient(); } - final ContentInfo payload = new ContentInfo.Builder( - event.getClipData(), SOURCE_DRAG_AND_DROP).build(); + final ContentInfo payload = + new ContentInfo.Builder(event.getClipData(), SOURCE_DRAG_AND_DROP) + .setDragAndDropPermissions(permissions) + .build(); ContentInfo remainingPayload = performReceiveContent(payload); // Return true unless none of the payload was consumed. return remainingPayload != payload; diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java index c5bce28fcee1..9f796c068abe 100644 --- a/core/java/android/view/inputmethod/BaseInputConnection.java +++ b/core/java/android/view/inputmethod/BaseInputConnection.java @@ -959,10 +959,10 @@ public class BaseInputConnection implements InputConnection { } final ClipData clip = new ClipData(inputContentInfo.getDescription(), new ClipData.Item(inputContentInfo.getContentUri())); - final ContentInfo payload = - new ContentInfo.Builder(clip, SOURCE_INPUT_METHOD) + final ContentInfo payload = new ContentInfo.Builder(clip, SOURCE_INPUT_METHOD) .setLinkUri(inputContentInfo.getLinkUri()) .setExtras(opts) + .setInputContentInfo(inputContentInfo) .build(); return mTargetView.performReceiveContent(payload) == null; } diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 238ce85622b5..48e25c513048 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -2894,8 +2894,8 @@ public class Editor { final int originalLength = mTextView.getText().length(); Selection.setSelection((Spannable) mTextView.getText(), offset); final ClipData clip = event.getClipData(); - final ContentInfo payload = - new ContentInfo.Builder(clip, SOURCE_DRAG_AND_DROP) + final ContentInfo payload = new ContentInfo.Builder(clip, SOURCE_DRAG_AND_DROP) + .setDragAndDropPermissions(permissions) .build(); mTextView.performReceiveContent(payload); if (dragDropIntoItself) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java index 6e78059f694e..5a78ea82ab04 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -921,13 +921,18 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene if (clip.getItemCount() > 1 || description.getMimeTypeCount() < 1 || remainingItems != null) { - // TODO(b/172363500): Update to loop over all the items + // Direct-reply in notifications currently only supports only one uri item + // at a time and requires the MIME type to be set. + Log.w(TAG, "Invalid payload: " + payload); return payload; } Uri contentUri = clip.getItemAt(0).getUri(); String mimeType = description.getMimeType(0); Intent dataIntent = mRemoteInputView.prepareRemoteInputFromData(mimeType, contentUri); + // We can release the uri permissions granted to us as soon as we've created the + // grant for the target app in the call above. + payload.releasePermissions(); mRemoteInputView.sendRemoteInput(dataIntent); } return remainingItems; |