Pass the originating uid to the package verifier

Bug: 6923241
Change-Id: I85a3e0d53b469543cb0551d3a440d2663b5d0697
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index b9518b8..c301c5c 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1305,6 +1305,14 @@
             = "android.intent.extra.REFERRER";
 
     /**
+     * Used as an int extra field with {@link #ACTION_INSTALL_PACKAGE} and
+     * {@link} #ACTION_VIEW} to indicate the uid of the package that initiated the install
+     * @hide
+     */
+    public static final String EXTRA_ORIGINATING_UID
+            = "android.intent.extra.ORIGINATING_UID";
+
+    /**
      * Used as a boolean extra field with {@link #ACTION_INSTALL_PACKAGE} to install a
      * package.  Tells the installer UI to skip the confirmation with the user
      * if the .apk is replacing an existing one.
diff --git a/core/java/android/content/pm/VerificationParams.java b/core/java/android/content/pm/VerificationParams.java
index 6454de0..22e1a85 100644
--- a/core/java/android/content/pm/VerificationParams.java
+++ b/core/java/android/content/pm/VerificationParams.java
@@ -27,6 +27,9 @@
  * @hide
  */
 public class VerificationParams implements Parcelable {
+    /** A constant used to indicate that a uid value is not present. */
+    public static final int NO_UID = -1;
+
     /** What we print out first when toString() is called. */
     private static final String TO_STRING_PREFIX = "VerificationParams{";
 
@@ -39,6 +42,9 @@
     /** HTTP referrer URI associated with the originatingURI. */
     private final Uri mReferrer;
 
+    /** UID of the application that the install request originated from. */
+    private final int mOriginatingUid;
+
     /** UID of application requesting the install */
     private int mInstallerUid;
 
@@ -57,16 +63,19 @@
      *            from. May be {@code null}.
      * @param referrer HTTP referrer URI associated with the originatingURI.
      *            May be {@code null}.
+     * @param originatingUid UID of the application that the install request originated
+     *            from, or NO_UID if not present
      * @param manifestDigest an object that holds the digest of the package
      *            which can be used to verify ownership. May be {@code null}.
      */
     public VerificationParams(Uri verificationURI, Uri originatingURI, Uri referrer,
-            ManifestDigest manifestDigest) {
+            int originatingUid, ManifestDigest manifestDigest) {
         mVerificationURI = verificationURI;
         mOriginatingURI = originatingURI;
         mReferrer = referrer;
+        mOriginatingUid = originatingUid;
         mManifestDigest = manifestDigest;
-        mInstallerUid = -1;
+        mInstallerUid = NO_UID;
     }
 
     public Uri getVerificationURI() {
@@ -81,11 +90,16 @@
         return mReferrer;
     }
 
+    /** return NO_UID if not available */
+    public int getOriginatingUid() {
+        return mOriginatingUid;
+    }
+
     public ManifestDigest getManifestDigest() {
         return mManifestDigest;
     }
 
-    /** @return -1 when not set */
+    /** @return NO_UID when not set */
     public int getInstallerUid() {
         return mInstallerUid;
     }
@@ -111,31 +125,39 @@
 
         final VerificationParams other = (VerificationParams) o;
 
-        if (mVerificationURI == null && other.mVerificationURI != null) {
-            return false;
-        }
-        if (!mVerificationURI.equals(other.mVerificationURI)) {
+        if (mVerificationURI == null) {
+            if (other.mVerificationURI != null) {
+                return false;
+            }
+        } else if (!mVerificationURI.equals(other.mVerificationURI)) {
             return false;
         }
 
-        if (mOriginatingURI == null && other.mOriginatingURI != null) {
-            return false;
-        }
-        if (!mOriginatingURI.equals(other.mOriginatingURI)) {
+        if (mOriginatingURI == null) {
+            if (other.mOriginatingURI != null) {
+                return false;
+            }
+        } else if (!mOriginatingURI.equals(other.mOriginatingURI)) {
             return false;
         }
 
-        if (mReferrer == null && other.mReferrer != null) {
-            return false;
-        }
-        if (!mReferrer.equals(other.mReferrer)) {
+        if (mReferrer == null) {
+            if (other.mReferrer != null) {
+                return false;
+            }
+        } else if (!mReferrer.equals(other.mReferrer)) {
             return false;
         }
 
-        if (mManifestDigest == null && other.mManifestDigest != null) {
+        if (mOriginatingUid != other.mOriginatingUid) {
             return false;
         }
-        if (mManifestDigest != null && !mManifestDigest.equals(other.mManifestDigest)) {
+
+        if (mManifestDigest == null) {
+            if (other.mManifestDigest != null) {
+                return false;
+            }
+        } else if (!mManifestDigest.equals(other.mManifestDigest)) {
             return false;
         }
 
@@ -150,11 +172,12 @@
     public int hashCode() {
         int hash = 3;
 
-        hash += 5 * (mVerificationURI==null?1:mVerificationURI.hashCode());
-        hash += 7 * (mOriginatingURI==null?1:mOriginatingURI.hashCode());
-        hash += 11 * (mReferrer==null?1:mReferrer.hashCode());
-        hash += 13 * (mManifestDigest==null?1:mManifestDigest.hashCode());
-        hash += 17 * mInstallerUid;
+        hash += 5 * (mVerificationURI == null ? 1 : mVerificationURI.hashCode());
+        hash += 7 * (mOriginatingURI == null ? 1 : mOriginatingURI.hashCode());
+        hash += 11 * (mReferrer == null ? 1 : mReferrer.hashCode());
+        hash += 13 * mOriginatingUid;
+        hash += 17 * (mManifestDigest == null ? 1 : mManifestDigest.hashCode());
+        hash += 19 * mInstallerUid;
 
         return hash;
     }
@@ -169,6 +192,8 @@
         sb.append(mOriginatingURI.toString());
         sb.append(",mReferrer=");
         sb.append(mReferrer.toString());
+        sb.append(",mOriginatingUid=");
+        sb.append(mOriginatingUid);
         sb.append(",mManifestDigest=");
         sb.append(mManifestDigest.toString());
         sb.append(",mInstallerUid=");
@@ -183,6 +208,7 @@
         dest.writeParcelable(mVerificationURI, 0);
         dest.writeParcelable(mOriginatingURI, 0);
         dest.writeParcelable(mReferrer, 0);
+        dest.writeInt(mOriginatingUid);
         dest.writeParcelable(mManifestDigest, 0);
         dest.writeInt(mInstallerUid);
     }
@@ -192,6 +218,7 @@
         mVerificationURI = source.readParcelable(Uri.class.getClassLoader());
         mOriginatingURI = source.readParcelable(Uri.class.getClassLoader());
         mReferrer = source.readParcelable(Uri.class.getClassLoader());
+        mOriginatingUid = source.readInt();
         mManifestDigest = source.readParcelable(ManifestDigest.class.getClassLoader());
         mInstallerUid = source.readInt();
     }
diff --git a/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java b/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java
index 105bcba..9b216cb 100644
--- a/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java
+++ b/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java
@@ -40,11 +40,13 @@
     private final static Uri ORIGINATING_URI = Uri.parse(ORIGINATING_URI_STRING);
     private final static Uri REFERRER = Uri.parse(REFERRER_STRING);
 
+    private final static int ORIGINATING_UID = 10042;
+
     private final static ManifestDigest MANIFEST_DIGEST = new ManifestDigest(DIGEST_BYTES);
 
     public void testParcel() throws Exception {
         VerificationParams expected = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
-                REFERRER, MANIFEST_DIGEST);
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
 
         Parcel parcel = Parcel.obtain();
         expected.writeToParcel(parcel, 0);
@@ -58,71 +60,86 @@
 
         assertEquals(REFERRER, actual.getReferrer());
 
+        assertEquals(ORIGINATING_UID, actual.getOriginatingUid());
+
         assertEquals(MANIFEST_DIGEST, actual.getManifestDigest());
     }
 
     public void testEquals_Success() throws Exception {
         VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
-                REFERRER, MANIFEST_DIGEST);
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
 
         VerificationParams params2 = new VerificationParams(
                 Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
-                Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES));
+                Uri.parse(REFERRER_STRING), ORIGINATING_UID, new ManifestDigest(DIGEST_BYTES));
 
         assertEquals(params1, params2);
     }
 
     public void testEquals_VerificationUri_Failure() throws Exception {
         VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
-            REFERRER, MANIFEST_DIGEST);
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
 
         VerificationParams params2 = new VerificationParams(
                 Uri.parse("http://a.different.uri/"), Uri.parse(ORIGINATING_URI_STRING),
-                Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES));
+                Uri.parse(REFERRER_STRING), ORIGINATING_UID, new ManifestDigest(DIGEST_BYTES));
 
         assertFalse(params1.equals(params2));
     }
 
     public void testEquals_OriginatingUri_Failure() throws Exception {
         VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
-                REFERRER, MANIFEST_DIGEST);
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
 
         VerificationParams params2 = new VerificationParams(
                 Uri.parse(VERIFICATION_URI_STRING), Uri.parse("http://a.different.uri/"),
-                Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES));
+                Uri.parse(REFERRER_STRING), ORIGINATING_UID, new ManifestDigest(DIGEST_BYTES));
 
         assertFalse(params1.equals(params2));
     }
 
     public void testEquals_Referrer_Failure() throws Exception {
         VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
-                REFERRER, MANIFEST_DIGEST);
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
 
         VerificationParams params2 = new VerificationParams(
                 Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
-                Uri.parse("http://a.different.uri/"), new ManifestDigest(DIGEST_BYTES));
+                Uri.parse("http://a.different.uri/"), ORIGINATING_UID,
+                new ManifestDigest(DIGEST_BYTES));
+
+        assertFalse(params1.equals(params2));
+    }
+
+    public void testEquals_Originating_Uid_Failure() throws Exception {
+        VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
+
+        VerificationParams params2 = new VerificationParams(
+                Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
+                Uri.parse(REFERRER_STRING), 12345, new ManifestDigest(DIGEST_BYTES));
 
         assertFalse(params1.equals(params2));
     }
 
     public void testEquals_ManifestDigest_Failure() throws Exception {
         VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
-                REFERRER, MANIFEST_DIGEST);
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
 
         VerificationParams params2 = new VerificationParams(
                 Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
-                Uri.parse(REFERRER_STRING), new ManifestDigest("a different digest".getBytes()));
+                Uri.parse(REFERRER_STRING), ORIGINATING_UID,
+                new ManifestDigest("a different digest".getBytes()));
 
         assertFalse(params1.equals(params2));
     }
 
     public void testEquals_InstallerUid_Failure() throws Exception {
         VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
-                REFERRER, MANIFEST_DIGEST);
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
 
         VerificationParams params2 = new VerificationParams(
                 Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
-                Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES));
+                Uri.parse(REFERRER_STRING), ORIGINATING_UID, new ManifestDigest(DIGEST_BYTES));
         params2.setInstallerUid(INSTALLER_UID);
 
         assertFalse(params1.equals(params2));
@@ -130,65 +147,78 @@
 
     public void testHashCode_Success() throws Exception {
         VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
-                REFERRER, MANIFEST_DIGEST);
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
 
         VerificationParams params2 = new VerificationParams(
                 Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
-                Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES));
+                Uri.parse(REFERRER_STRING), ORIGINATING_UID, new ManifestDigest(DIGEST_BYTES));
 
         assertEquals(params1.hashCode(), params2.hashCode());
     }
 
     public void testHashCode_VerificationUri_Failure() throws Exception {
         VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
-                REFERRER, MANIFEST_DIGEST);
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
 
         VerificationParams params2 = new VerificationParams(null, Uri.parse(ORIGINATING_URI_STRING),
-                Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES));
+                Uri.parse(REFERRER_STRING), ORIGINATING_UID, new ManifestDigest(DIGEST_BYTES));
 
         assertFalse(params1.hashCode() == params2.hashCode());
     }
 
     public void testHashCode_OriginatingUri_Failure() throws Exception {
         VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
-                REFERRER, MANIFEST_DIGEST);
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
 
         VerificationParams params2 = new VerificationParams(
                 Uri.parse(VERIFICATION_URI_STRING), Uri.parse("http://a.different.uri/"),
-                Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES));
+                Uri.parse(REFERRER_STRING), ORIGINATING_UID, new ManifestDigest(DIGEST_BYTES));
 
         assertFalse(params1.hashCode() == params2.hashCode());
     }
 
     public void testHashCode_Referrer_Failure() throws Exception {
         VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
-                REFERRER, MANIFEST_DIGEST);
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
 
         VerificationParams params2 = new VerificationParams(
                 Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING), null,
-                new ManifestDigest(DIGEST_BYTES));
+                ORIGINATING_UID, new ManifestDigest(DIGEST_BYTES));
+
+        assertFalse(params1.hashCode() == params2.hashCode());
+    }
+
+    public void testHashCode_Originating_Uid_Failure() throws Exception {
+        VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
+
+        VerificationParams params2 = new VerificationParams(
+                Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
+                Uri.parse(REFERRER_STRING), 12345, new ManifestDigest(DIGEST_BYTES));
 
         assertFalse(params1.hashCode() == params2.hashCode());
     }
 
     public void testHashCode_ManifestDigest_Failure() throws Exception {
         VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
-                REFERRER, MANIFEST_DIGEST);
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
 
         VerificationParams params2 = new VerificationParams(
                 Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
-                Uri.parse(REFERRER_STRING), new ManifestDigest("a different digest".getBytes()));
+                Uri.parse(REFERRER_STRING), ORIGINATING_UID,
+                new ManifestDigest("a different digest".getBytes()));
 
         assertFalse(params1.hashCode() == params2.hashCode());
     }
 
     public void testHashCode_InstallerUid_Failure() throws Exception {
         VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
-                REFERRER, MANIFEST_DIGEST);
+                REFERRER, ORIGINATING_UID, MANIFEST_DIGEST);
 
         VerificationParams params2 = new VerificationParams(
                 Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
-                Uri.parse(REFERRER_STRING), new ManifestDigest("a different digest".getBytes()));
+                Uri.parse(REFERRER_STRING), ORIGINATING_UID,
+                new ManifestDigest("a different digest".getBytes()));
         params2.setInstallerUid(INSTALLER_UID);
 
         assertFalse(params1.hashCode() == params2.hashCode());