diff options
-rw-r--r-- | api/current.txt | 2 | ||||
-rw-r--r-- | cmds/pm/src/com/android/commands/pm/Pm.java | 41 | ||||
-rw-r--r-- | core/java/android/app/ApplicationPackageManager.java | 13 | ||||
-rw-r--r-- | core/java/android/content/Intent.java | 16 | ||||
-rw-r--r-- | core/java/android/content/pm/IPackageManager.aidl | 6 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageManager.java | 31 | ||||
-rw-r--r-- | core/java/android/content/pm/VerificationParams.aidl | 19 | ||||
-rw-r--r-- | core/java/android/content/pm/VerificationParams.java | 187 | ||||
-rw-r--r-- | core/tests/coretests/src/android/content/pm/VerificationParamsTest.java | 171 | ||||
-rw-r--r-- | services/java/com/android/server/pm/PackageManagerService.java | 50 | ||||
-rw-r--r-- | test-runner/src/android/test/mock/MockPackageManager.java | 11 |
11 files changed, 523 insertions, 24 deletions
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 @@ package android.content { 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.ParceledListSlice; 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 @@ public final class Pm { 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 @@ public final class Pm { 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 @@ public final class Pm { 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 @@ public final class Pm { 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 @@ public final class Pm { 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.ResolveInfo; 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 @@ final class ApplicationPackageManager extends PackageManager { } @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 @@ import java.util.Set; * <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 @@ public class Intent implements Parcelable, Cloneable { = "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.PermissionInfo; 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 @@ interface IPackageManager { 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 @@ public abstract class PackageManager { 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..5bb7f69 --- /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.ResolveInfo; 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 class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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.ProviderInfo; 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 @@ public class MockPackageManager extends PackageManager { 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(); |