From a0ba51c2ab75c8e0406bbd43742597552b6dae98 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 21 Mar 2017 20:23:36 -0600 Subject: [PATCH] Deprecate EXTRA_STREAM. ClipData is much more flexible, and it should be used instead of EXTRA_STREAM moving forward. To ensure that legacy apps continue working, the OS will offer to promote/demote the ClipData value from/to EXTRA_STREAM. (We already had the promotion logic, but we were missing the demotion logic.) Test: builds, boots Bug: 35293781 Change-Id: I82cd0b95cf021292282649290ab046cc310fe160 --- api/current.txt | 2 +- api/system-current.txt | 2 +- api/test-current.txt | 2 +- core/java/android/content/Intent.java | 40 ++++++++++++++++++++++++++++++----- 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/api/current.txt b/api/current.txt index 90c48fb045de..405507009de0 100644 --- a/api/current.txt +++ b/api/current.txt @@ -9479,7 +9479,7 @@ package android.content { field public static final deprecated java.lang.String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT"; field public static final deprecated java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME"; field public static final java.lang.String EXTRA_SHUTDOWN_USERSPACE_ONLY = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY"; - field public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM"; + field public static final deprecated java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM"; field public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT"; field public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE"; field public static final java.lang.String EXTRA_TEXT = "android.intent.extra.TEXT"; diff --git a/api/system-current.txt b/api/system-current.txt index 0d54bee49610..f2be20b904fe 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -10014,7 +10014,7 @@ package android.content { field public static final deprecated java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME"; field public static final java.lang.String EXTRA_SHUTDOWN_USERSPACE_ONLY = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY"; field public static final java.lang.String EXTRA_SPLIT_NAME = "android.intent.extra.SPLIT_NAME"; - field public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM"; + field public static final deprecated java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM"; field public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT"; field public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE"; field public static final java.lang.String EXTRA_TEXT = "android.intent.extra.TEXT"; diff --git a/api/test-current.txt b/api/test-current.txt index e56255c9f9ff..6cb219317632 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -9509,7 +9509,7 @@ package android.content { field public static final deprecated java.lang.String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT"; field public static final deprecated java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME"; field public static final java.lang.String EXTRA_SHUTDOWN_USERSPACE_ONLY = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY"; - field public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM"; + field public static final deprecated java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM"; field public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT"; field public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE"; field public static final java.lang.String EXTRA_TEXT = "android.intent.extra.TEXT"; diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index bd31b03d7cff..2fe84767163c 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -16,6 +16,8 @@ package android.content; +import static android.content.ContentProvider.maybeAddUserId; + import android.annotation.AnyRes; import android.annotation.BroadcastBehavior; import android.annotation.IntDef; @@ -41,7 +43,6 @@ import android.os.ResultReceiver; import android.os.ShellCommand; import android.os.StrictMode; import android.os.UserHandle; -import android.os.storage.StorageManager; import android.provider.DocumentsContract; import android.provider.DocumentsProvider; import android.provider.MediaStore; @@ -49,7 +50,9 @@ import android.provider.OpenableColumns; import android.util.ArraySet; import android.util.AttributeSet; import android.util.Log; + import com.android.internal.util.XmlUtils; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; @@ -67,8 +70,6 @@ import java.util.Locale; import java.util.Objects; import java.util.Set; -import static android.content.ContentProvider.maybeAddUserId; - /** * An intent is an abstract description of an operation to be performed. It * can be used with {@link Context#startActivity(Intent) startActivity} to @@ -3854,9 +3855,23 @@ public class Intent implements Parcelable, Cloneable { public static final String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT"; /** - * A content: URI holding a stream of data associated with the Intent, - * used with {@link #ACTION_SEND} to supply the data being sent. + * A content: URI holding a stream of data associated with the Intent, used + * with {@link #ACTION_SEND} to supply the data being sent. + *

+ * Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN} this value + * will be automatically promoted to {@link Intent#setClipData(ClipData)} + * when that value is not already defined. + *

+ * Starting in {@link android.os.Build.VERSION_CODES#O} this value will be + * automatically demoted from {@link Intent#getClipData()} when this value + * is not already defined. + * + * @deprecated apps should use {@link Intent#setClipData(ClipData)} and + * {@link Intent#getClipData()} instead of this extra, since + * only those APIs can extend temporary permission grants to the + * underlying resource. */ + @Deprecated public static final String EXTRA_STREAM = "android.intent.extra.STREAM"; /** @@ -9362,6 +9377,21 @@ public class Intent implements Parcelable, Cloneable { mContentUserHint = UserHandle.USER_CURRENT; } } + + // If someone is sending us ClipData, but not EXTRA_STREAM, offer to + // downgrade that content for older apps to find + if (mClipData != null && mClipData.getItemCount() > 0 && !hasExtra(EXTRA_STREAM)) { + final String action = getAction(); + if (ACTION_SEND.equals(action)) { + putExtra(EXTRA_STREAM, mClipData.getItemAt(0).getUri()); + } else if (ACTION_SEND_MULTIPLE.equals(action)) { + final ArrayList list = new ArrayList<>(); + for (int i = 0; i < mClipData.getItemCount(); i++) { + list.add(mClipData.getItemAt(i).getUri()); + } + putExtra(EXTRA_STREAM, list); + } + } } /** -- 2.11.0