Add extras to ClipDescription

This is required to expand metadata capabilities of DragEvent.
Apps receiving ACTION_DRAG_* events have access to
ClipDescription, but not ClipData.

Adding extras to ClipDescription allows for a richer behavior of apps
responding to these events.

Bug: 25788641
Change-Id: I07e374f71d16f8441dc3a0b02c7d833e0139b74b
diff --git a/api/current.txt b/api/current.txt
index 7ddd5af..6c23563 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7441,12 +7441,16 @@
     method public static boolean compareMimeTypes(java.lang.String, java.lang.String);
     method public int describeContents();
     method public java.lang.String[] filterMimeTypes(java.lang.String);
+    method public android.os.PersistableBundle getExtras();
     method public java.lang.CharSequence getLabel();
     method public java.lang.String getMimeType(int);
     method public int getMimeTypeCount();
     method public boolean hasMimeType(java.lang.String);
+    method public void setExtras(android.os.PersistableBundle);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
+    field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
+    field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
     field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
     field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
     field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
diff --git a/api/system-current.txt b/api/system-current.txt
index edc9f18..bfafd25 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -7682,12 +7682,16 @@
     method public static boolean compareMimeTypes(java.lang.String, java.lang.String);
     method public int describeContents();
     method public java.lang.String[] filterMimeTypes(java.lang.String);
+    method public android.os.PersistableBundle getExtras();
     method public java.lang.CharSequence getLabel();
     method public java.lang.String getMimeType(int);
     method public int getMimeTypeCount();
     method public boolean hasMimeType(java.lang.String);
+    method public void setExtras(android.os.PersistableBundle);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
+    field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
+    field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
     field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
     field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
     field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
diff --git a/api/test-current.txt b/api/test-current.txt
index 4838702..095ce5b 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -7441,12 +7441,16 @@
     method public static boolean compareMimeTypes(java.lang.String, java.lang.String);
     method public int describeContents();
     method public java.lang.String[] filterMimeTypes(java.lang.String);
+    method public android.os.PersistableBundle getExtras();
     method public java.lang.CharSequence getLabel();
     method public java.lang.String getMimeType(int);
     method public int getMimeTypeCount();
     method public boolean hasMimeType(java.lang.String);
+    method public void setExtras(android.os.PersistableBundle);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
+    field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
+    field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
     field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
     field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
     field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
diff --git a/core/java/android/content/ClipDescription.java b/core/java/android/content/ClipDescription.java
index e988516..1b024e2 100644
--- a/core/java/android/content/ClipDescription.java
+++ b/core/java/android/content/ClipDescription.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.text.TextUtils;
 
 import java.util.ArrayList;
@@ -59,8 +60,35 @@
      */
     public static final String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
 
+    /**
+     * The name of the extra used to define a component name when copying/dragging
+     * an app icon from Launcher.
+     * <p>
+     * Type: String
+     * </p>
+     * <p>
+     * Use {@link ComponentName#unflattenFromString(String)}
+     * and {@link ComponentName#flattenToString()} to convert the extra value
+     * to/from {@link ComponentName}.
+     * </p>
+     */
+    public static final String EXTRA_TARGET_COMPONENT_NAME =
+            "android.content.extra.TARGET_COMPONENT_NAME";
+
+    /**
+     * The name of the extra used to define a user serial number when copying/dragging
+     * an app icon from Launcher.
+     * <p>
+     * Type: long
+     * </p>
+     */
+    public static final String EXTRA_USER_SERIAL_NUMBER =
+            "android.content.extra.USER_SERIAL_NUMBER";
+
+
     final CharSequence mLabel;
     final String[] mMimeTypes;
+    private PersistableBundle mExtras;
 
     /**
      * Create a new clip.
@@ -173,6 +201,27 @@
         return mMimeTypes[index];
     }
 
+    /**
+     * Retrieve extended data from the clip description.
+     *
+     * @return the bundle containing extended data previously set with
+     * {@link #setExtras(PersistableBundle)}, or null if no extras have been set.
+     *
+     * @see #setExtras(PersistableBundle)
+     */
+    public PersistableBundle getExtras() {
+        return mExtras;
+    }
+
+    /**
+     * Add extended data to the clip description.
+     *
+     * @see #getExtras()
+     */
+    public void setExtras(PersistableBundle extras) {
+        mExtras = new PersistableBundle(extras);
+    }
+
     /** @hide */
     public void validate() {
         if (mMimeTypes == null) {
@@ -211,6 +260,13 @@
             b.append(mLabel);
             b.append('"');
         }
+        if (mExtras != null) {
+            if (!first) {
+                b.append(' ');
+            }
+            first = false;
+            b.append(mExtras.toString());
+        }
         return !first;
     }
 
@@ -236,11 +292,13 @@
     public void writeToParcel(Parcel dest, int flags) {
         TextUtils.writeToParcel(mLabel, dest, flags);
         dest.writeStringArray(mMimeTypes);
+        dest.writePersistableBundle(mExtras);
     }
 
     ClipDescription(Parcel in) {
         mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         mMimeTypes = in.createStringArray();
+        mExtras = in.readPersistableBundle();
     }
 
     public static final Parcelable.Creator<ClipDescription> CREATOR =