Pass URLs to package verifiers
This change passes the originating URL and accompanied referrer to
package verifiers, when available.
Bug: 6544677
Change-Id: I9ebc71bc13f549bd88267e444816151a99bda000
diff --git a/api/current.txt b/api/current.txt
index d6d1732..5e0b2e6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5838,7 +5838,7 @@
field public static final java.lang.String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT";
field public static final java.lang.String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY";
field public static final java.lang.String EXTRA_NOT_UNKNOWN_SOURCE = "android.intent.extra.NOT_UNKNOWN_SOURCE";
- field public static final java.lang.String EXTRA_ORIGINATING_URL = "android.intent.extra.ORIGINATING_URL";
+ field public static final java.lang.String EXTRA_ORIGINATING_URI = "android.intent.extra.ORIGINATING_URI";
field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
field public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token";
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index eb1f9a2..b34fd05 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -36,6 +36,7 @@
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.UserInfo;
+import android.content.pm.VerificationParams;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.net.Uri;
@@ -787,6 +788,8 @@
String macAlgo = null;
byte[] macKey = null;
byte[] tag = null;
+ String originatingUriString = null;
+ String referrer = null;
while ((opt=nextOption()) != null) {
if (opt.equals("-l")) {
@@ -850,6 +853,20 @@
showUsage();
return;
}
+ } else if (opt.equals("--originating-uri")) {
+ originatingUriString = nextOptionData();
+ if (originatingUriString == null) {
+ System.err.println("Error: must supply argument for --originating-uri");
+ showUsage();
+ return;
+ }
+ } else if (opt.equals("--referrer")) {
+ referrer = nextOptionData();
+ if (referrer == null) {
+ System.err.println("Error: must supply argument for --referrer");
+ showUsage();
+ return;
+ }
} else {
System.err.println("Error: Unknown option: " + opt);
showUsage();
@@ -897,6 +914,20 @@
final Uri apkURI;
final Uri verificationURI;
+ final Uri originatingURI;
+ final Uri referrerURI;
+
+ if (originatingUriString != null) {
+ originatingURI = Uri.parse(originatingUriString);
+ } else {
+ originatingURI = null;
+ }
+
+ if (referrer != null) {
+ referrerURI = Uri.parse(referrer);
+ } else {
+ referrerURI = null;
+ }
// Populate apkURI, must be present
final String apkFilePath = nextArg();
@@ -920,8 +951,11 @@
PackageInstallObserver obs = new PackageInstallObserver();
try {
- mPm.installPackageWithVerification(apkURI, obs, installFlags, installerPackageName,
- verificationURI, null, encryptionParams);
+ VerificationParams verificationParams = new VerificationParams(verificationURI,
+ originatingURI, referrerURI, null);
+
+ mPm.installPackageWithVerificationAndEncryption(apkURI, obs, installFlags,
+ installerPackageName, verificationParams, encryptionParams);
synchronized (obs) {
while (!obs.finished) {
@@ -1441,7 +1475,8 @@
System.err.println(" pm list libraries");
System.err.println(" pm path PACKAGE");
System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]");
- System.err.println(" [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>] PATH");
+ System.err.println(" [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>]");
+ System.err.println(" [--originating-uri <URI>] [--referrer <URI>] PATH");
System.err.println(" pm uninstall [-k] PACKAGE");
System.err.println(" pm clear PACKAGE");
System.err.println(" pm enable PACKAGE_OR_COMPONENT");
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index e9c4701..7ab7086 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -43,6 +43,7 @@
import android.content.pm.ServiceInfo;
import android.content.pm.ManifestDigest;
import android.content.pm.UserInfo;
+import android.content.pm.VerificationParams;
import android.content.pm.VerifierDeviceIdentity;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
@@ -984,6 +985,18 @@
}
@Override
+ public void installPackageWithVerificationAndEncryption(Uri packageURI,
+ IPackageInstallObserver observer, int flags, String installerPackageName,
+ VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
+ try {
+ mPM.installPackageWithVerificationAndEncryption(packageURI, observer, flags,
+ installerPackageName, verificationParams, encryptionParams);
+ } catch (RemoteException e) {
+ // Should never happen!
+ }
+ }
+
+ @Override
public void verifyPendingInstall(int id, int response) {
try {
mPM.verifyPendingInstall(id, response);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 0190555..06edf32 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -571,7 +571,7 @@
* <li> {@link #EXTRA_INITIAL_INTENTS}
* <li> {@link #EXTRA_INTENT}
* <li> {@link #EXTRA_KEY_EVENT}
- * <li> {@link #EXTRA_ORIGINATING_URL}
+ * <li> {@link #EXTRA_ORIGINATING_URI}
* <li> {@link #EXTRA_PHONE_NUMBER}
* <li> {@link #EXTRA_REFERRER}
* <li> {@link #EXTRA_REMOTE_INTENT_TOKEN}
@@ -1288,17 +1288,17 @@
= "android.intent.extra.NOT_UNKNOWN_SOURCE";
/**
- * Used as a string extra field with {@link #ACTION_INSTALL_PACKAGE} and
- * {@link #ACTION_VIEW} to indicate the URL from which the local APK in the Intent
+ * Used as a URI extra field with {@link #ACTION_INSTALL_PACKAGE} and
+ * {@link #ACTION_VIEW} to indicate the URI from which the local APK in the Intent
* data field originated from.
*/
- public static final String EXTRA_ORIGINATING_URL
- = "android.intent.extra.ORIGINATING_URL";
+ public static final String EXTRA_ORIGINATING_URI
+ = "android.intent.extra.ORIGINATING_URI";
/**
- * Used as a string extra field with {@link #ACTION_INSTALL_PACKAGE} and
- * {@link #ACTION_VIEW} to indicate the HTTP referrer associated with the Intent
- * data field or {@link #EXTRA_ORIGINATING_URL}.
+ * Used as a URI extra field with {@link #ACTION_INSTALL_PACKAGE} and
+ * {@link #ACTION_VIEW} to indicate the HTTP referrer URI associated with the Intent
+ * data field or {@link #EXTRA_ORIGINATING_URI}.
*/
public static final String EXTRA_REFERRER
= "android.intent.extra.REFERRER";
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 6c19282..f266b00 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -39,6 +39,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
+import android.content.pm.VerificationParams;
import android.content.pm.VerifierDeviceIdentity;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
@@ -362,6 +363,11 @@
int flags, in String installerPackageName, in Uri verificationURI,
in ManifestDigest manifestDigest, in ContainerEncryptionParams encryptionParams);
+ void installPackageWithVerificationAndEncryption(in Uri packageURI,
+ in IPackageInstallObserver observer, int flags, in String installerPackageName,
+ in VerificationParams verificationParams,
+ in ContainerEncryptionParams encryptionParams);
+
void verifyPendingInstall(int id, int verificationCode);
VerifierDeviceIdentity getVerifierDeviceIdentity();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 2837931..e9e0ee3 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2227,6 +2227,37 @@
ContainerEncryptionParams encryptionParams);
/**
+ * Similar to
+ * {@link #installPackage(Uri, IPackageInstallObserver, int, String)} but
+ * with an extra verification information provided.
+ *
+ * @param packageURI The location of the package file to install. This can
+ * be a 'file:' or a 'content:' URI.
+ * @param observer An observer callback to get notified when the package
+ * installation is complete.
+ * {@link IPackageInstallObserver#packageInstalled(String, int)}
+ * will be called when that happens. observer may be null to
+ * indicate that no callback is desired.
+ * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
+ * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}
+ * .
+ * @param installerPackageName Optional package name of the application that
+ * is performing the installation. This identifies which market
+ * the package came from.
+ * @param verificationParams an object that holds signal information to
+ * assist verification. May be {@code null}.
+ * @param encryptionParams if the package to be installed is encrypted,
+ * these parameters describing the encryption and authentication
+ * used. May be {@code null}.
+ *
+ * @hide
+ */
+ public abstract void installPackageWithVerificationAndEncryption(Uri packageURI,
+ IPackageInstallObserver observer, int flags, String installerPackageName,
+ VerificationParams verificationParams,
+ ContainerEncryptionParams encryptionParams);
+
+ /**
* Allows a package listening to the
* {@link Intent#ACTION_PACKAGE_NEEDS_VERIFICATION package verification
* broadcast} to respond to the package manager. The response must include
diff --git a/core/java/android/content/pm/VerificationParams.aidl b/core/java/android/content/pm/VerificationParams.aidl
new file mode 100644
index 0000000..5bb7f6962
--- /dev/null
+++ b/core/java/android/content/pm/VerificationParams.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+parcelable VerificationParams;
diff --git a/core/java/android/content/pm/VerificationParams.java b/core/java/android/content/pm/VerificationParams.java
new file mode 100644
index 0000000..9bec87e
--- /dev/null
+++ b/core/java/android/content/pm/VerificationParams.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.content.pm.ManifestDigest;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents verification parameters used to verify packages to be installed.
+ *
+ * @hide
+ */
+public class VerificationParams implements Parcelable {
+ /** What we print out first when toString() is called. */
+ private static final String TO_STRING_PREFIX = "VerificationParams{";
+
+ /** The location of the supplementary verification file. */
+ private final Uri mVerificationURI;
+
+ /** URI referencing where the package was downloaded from. */
+ private final Uri mOriginatingURI;
+
+ /** HTTP referrer URI associated with the originatingURI. */
+ private final Uri mReferrer;
+
+ /**
+ * An object that holds the digest of the package which can be used to
+ * verify ownership.
+ */
+ private final ManifestDigest mManifestDigest;
+
+ /**
+ * Creates verification specifications for installing with application verification.
+ *
+ * @param verificationURI The location of the supplementary verification
+ * file. This can be a 'file:' or a 'content:' URI. May be {@code null}.
+ * @param originatingURI URI referencing where the package was downloaded
+ * from. May be {@code null}.
+ * @param referrer HTTP referrer URI associated with the originatingURI.
+ * May be {@code null}.
+ * @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) {
+ mVerificationURI = verificationURI;
+ mOriginatingURI = originatingURI;
+ mReferrer = referrer;
+ mManifestDigest = manifestDigest;
+ }
+
+ public Uri getVerificationURI() {
+ return mVerificationURI;
+ }
+
+ public Uri getOriginatingURI() {
+ return mOriginatingURI;
+ }
+
+ public Uri getReferrer() {
+ return mReferrer;
+ }
+
+ public ManifestDigest getManifestDigest() {
+ return mManifestDigest;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof VerificationParams)) {
+ return false;
+ }
+
+ final VerificationParams other = (VerificationParams) o;
+
+ if (mVerificationURI == null && other.mVerificationURI != null) {
+ return false;
+ }
+ if (!mVerificationURI.equals(other.mVerificationURI)) {
+ return false;
+ }
+
+ if (mOriginatingURI == null && other.mOriginatingURI != null) {
+ return false;
+ }
+ if (!mOriginatingURI.equals(other.mOriginatingURI)) {
+ return false;
+ }
+
+ if (mReferrer == null && other.mReferrer != null) {
+ return false;
+ }
+ if (!mReferrer.equals(other.mReferrer)) {
+ return false;
+ }
+
+ if (mManifestDigest == null && other.mManifestDigest != null) {
+ return false;
+ }
+ if (mManifestDigest != null && !mManifestDigest.equals(other.mManifestDigest)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ 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());
+
+ return hash;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder(TO_STRING_PREFIX);
+
+ sb.append("mVerificationURI=");
+ sb.append(mVerificationURI.toString());
+ sb.append(",mOriginatingURI=");
+ sb.append(mOriginatingURI.toString());
+ sb.append(",mReferrer=");
+ sb.append(mReferrer.toString());
+ sb.append(",mManifestDigest=");
+ sb.append(mManifestDigest.toString());
+ sb.append('}');
+
+ return sb.toString();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(mVerificationURI, 0);
+ dest.writeParcelable(mOriginatingURI, 0);
+ dest.writeParcelable(mReferrer, 0);
+ dest.writeParcelable(mManifestDigest, 0);
+ }
+
+
+ private VerificationParams(Parcel source) {
+ mVerificationURI = source.readParcelable(Uri.class.getClassLoader());
+ mOriginatingURI = source.readParcelable(Uri.class.getClassLoader());
+ mReferrer = source.readParcelable(Uri.class.getClassLoader());
+ mManifestDigest = source.readParcelable(ManifestDigest.class.getClassLoader());
+ }
+
+ public static final Parcelable.Creator<VerificationParams> CREATOR =
+ new Parcelable.Creator<VerificationParams>() {
+ public VerificationParams createFromParcel(Parcel source) {
+ return new VerificationParams(source);
+ }
+
+ public VerificationParams[] newArray(int size) {
+ return new VerificationParams[size];
+ }
+ };
+}
diff --git a/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java b/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java
new file mode 100644
index 0000000..b814e2d
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.content.pm.ManifestDigest;
+import android.content.pm.VerificationParams;
+import android.net.Uri;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+
+/**
+ * Tests the android.content.pm.VerificationParams class
+ *
+ * To test run:
+ * ./development/testrunner/runtest.py frameworks-core -c android.content.pm.VerificationParamsTest
+ */
+public class VerificationParamsTest extends AndroidTestCase {
+
+ private final static String VERIFICATION_URI_STRING = "http://verification.uri/path";
+ private final static String ORIGINATING_URI_STRING = "http://originating.uri/path";
+ private final static String REFERRER_STRING = "http://referrer.uri/path";
+ private final static byte[] DIGEST_BYTES = "fake digest".getBytes();
+
+ private final static Uri VERIFICATION_URI = Uri.parse(VERIFICATION_URI_STRING);
+ private final static Uri ORIGINATING_URI = Uri.parse(ORIGINATING_URI_STRING);
+ private final static Uri REFERRER = Uri.parse(REFERRER_STRING);
+
+ 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);
+
+ Parcel parcel = Parcel.obtain();
+ expected.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ VerificationParams actual = VerificationParams.CREATOR.createFromParcel(parcel);
+
+ assertEquals(VERIFICATION_URI, actual.getVerificationURI());
+
+ assertEquals(ORIGINATING_URI, actual.getOriginatingURI());
+
+ assertEquals(REFERRER, actual.getReferrer());
+
+ assertEquals(MANIFEST_DIGEST, actual.getManifestDigest());
+ }
+
+ public void testEquals_Success() throws Exception {
+ VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+ REFERRER, MANIFEST_DIGEST);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
+ Uri.parse(REFERRER_STRING), 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);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse("http://a.different.uri/"), Uri.parse(ORIGINATING_URI_STRING),
+ Uri.parse(REFERRER_STRING), 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);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse("http://a.different.uri/"),
+ Uri.parse(REFERRER_STRING), 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);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
+ Uri.parse("http://a.different.uri/"), 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);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
+ Uri.parse(REFERRER_STRING), new ManifestDigest("a different digest".getBytes()));
+
+ assertFalse(params1.equals(params2));
+ }
+
+ public void testHashCode_Success() throws Exception {
+ VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+ REFERRER, MANIFEST_DIGEST);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
+ Uri.parse(REFERRER_STRING), 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);
+
+ VerificationParams params2 = new VerificationParams(null, Uri.parse(ORIGINATING_URI_STRING),
+ Uri.parse(REFERRER_STRING), 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);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse("http://a.different.uri/"),
+ Uri.parse(REFERRER_STRING), 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);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING), null,
+ 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);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
+ Uri.parse(REFERRER_STRING), new ManifestDigest("a different digest".getBytes()));
+
+ assertFalse(params1.hashCode() == params2.hashCode());
+ }
+}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 430edf7..be82b34 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -79,6 +79,7 @@
import android.content.pm.ServiceInfo;
import android.content.pm.Signature;
import android.content.pm.ManifestDigest;
+import android.content.pm.VerificationParams;
import android.content.pm.VerifierDeviceIdentity;
import android.content.pm.VerifierInfo;
import android.net.Uri;
@@ -5351,7 +5352,17 @@
public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
int flags, String installerPackageName, Uri verificationURI,
ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
+ VerificationParams verificationParams = new VerificationParams(verificationURI, null, null,
+ manifestDigest);
+ installPackageWithVerificationAndEncryption(packageURI, observer, flags,
+ installerPackageName, verificationParams, encryptionParams);
+ }
+
+ public void installPackageWithVerificationAndEncryption(Uri packageURI,
+ IPackageInstallObserver observer, int flags, String installerPackageName,
+ VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
+ null);
final int uid = Binder.getCallingUid();
@@ -5368,7 +5379,7 @@
final Message msg = mHandler.obtainMessage(INIT_COPY);
msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
- verificationURI, manifestDigest, encryptionParams);
+ verificationParams, encryptionParams);
mHandler.sendMessage(msg);
}
@@ -5798,8 +5809,7 @@
private final Uri mPackageURI;
final String installerPackageName;
- final Uri verificationURI;
- final ManifestDigest manifestDigest;
+ final VerificationParams verificationParams;
private InstallArgs mArgs;
private int mRet;
private File mTempPackage;
@@ -5807,17 +5817,23 @@
InstallParams(Uri packageURI,
IPackageInstallObserver observer, int flags,
- String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest,
+ String installerPackageName, VerificationParams verificationParams,
ContainerEncryptionParams encryptionParams) {
this.mPackageURI = packageURI;
this.flags = flags;
this.observer = observer;
this.installerPackageName = installerPackageName;
- this.verificationURI = verificationURI;
- this.manifestDigest = manifestDigest;
+ this.verificationParams = verificationParams;
this.encryptionParams = encryptionParams;
}
+ public ManifestDigest getManifestDigest() {
+ if (verificationParams == null) {
+ return null;
+ }
+ return verificationParams.getManifestDigest();
+ }
+
private int installLocationPolicy(PackageInfoLite pkgLite, int flags) {
String packageName = pkgLite.packageName;
int installLocation = pkgLite.installLocation;
@@ -6006,9 +6022,19 @@
verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, flags);
- if (verificationURI != null) {
- verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
- verificationURI);
+ if (verificationParams != null) {
+ if (verificationParams.getVerificationURI() != null) {
+ verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
+ verificationParams.getVerificationURI());
+ }
+ if (verificationParams.getOriginatingURI() != null) {
+ verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
+ verificationParams.getOriginatingURI());
+ }
+ if (verificationParams.getReferrer() != null) {
+ verification.putExtra(Intent.EXTRA_REFERRER,
+ verificationParams.getReferrer());
+ }
}
final PackageVerificationState verificationState = new PackageVerificationState(
@@ -6344,7 +6370,7 @@
FileInstallArgs(InstallParams params) {
super(params.getPackageUri(), params.observer, params.flags,
- params.installerPackageName, params.manifestDigest);
+ params.installerPackageName, params.getManifestDigest());
}
FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
@@ -6631,7 +6657,7 @@
AsecInstallArgs(InstallParams params) {
super(params.getPackageUri(), params.observer, params.flags,
- params.installerPackageName, params.manifestDigest);
+ params.installerPackageName, params.getManifestDigest());
}
AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index ef14404..a85c8b5 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -39,6 +39,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
+import android.content.pm.VerificationParams;
import android.content.pm.VerifierDeviceIdentity;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
@@ -519,6 +520,16 @@
throw new UnsupportedOperationException();
}
+ /**
+ * @hide
+ */
+ @Override
+ public void installPackageWithVerificationAndEncryption(Uri packageURI,
+ IPackageInstallObserver observer, int flags, String installerPackageName,
+ VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public void verifyPendingInstall(int id, int verificationCode) {
throw new UnsupportedOperationException();