Merge commit '1aa64b53eb9b3cc7904705076a015a5cd0e3b536' into kraken * commit '1aa64b53eb9b3cc7904705076a015a5cd0e3b536': Change certificate policy.
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:installLocation="internalOnly"
|
||||||
package="com.android.frameworks.coretests">
|
package="com.android.frameworks.coretests">
|
||||||
|
|
||||||
<permission android:name="com.android.frameworks.coretests.permission.TEST_GRANTED"
|
<permission android:name="com.android.frameworks.coretests.permission.TEST_GRANTED"
|
||||||
|
|||||||
BIN
core/tests/coretests/res/raw/install_app1_cert1
Normal file
BIN
core/tests/coretests/res/raw/install_app1_cert1
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_app1_cert1_cert2
Normal file
BIN
core/tests/coretests/res/raw/install_app1_cert1_cert2
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_app1_cert2
Normal file
BIN
core/tests/coretests/res/raw/install_app1_cert2
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_app1_cert3
Normal file
BIN
core/tests/coretests/res/raw/install_app1_cert3
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_app1_cert3_cert4
Normal file
BIN
core/tests/coretests/res/raw/install_app1_cert3_cert4
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_app1_unsigned
Normal file
BIN
core/tests/coretests/res/raw/install_app1_unsigned
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_app2_cert1
Normal file
BIN
core/tests/coretests/res/raw/install_app2_cert1
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_app2_cert1_cert2
Normal file
BIN
core/tests/coretests/res/raw/install_app2_cert1_cert2
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_app2_cert2
Normal file
BIN
core/tests/coretests/res/raw/install_app2_cert2
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_app2_cert3
Normal file
BIN
core/tests/coretests/res/raw/install_app2_cert3
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_app2_unsigned
Normal file
BIN
core/tests/coretests/res/raw/install_app2_unsigned
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_shared1_cert1
Normal file
BIN
core/tests/coretests/res/raw/install_shared1_cert1
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_shared1_cert12
Normal file
BIN
core/tests/coretests/res/raw/install_shared1_cert12
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_shared1_cert1_cert2
Normal file
BIN
core/tests/coretests/res/raw/install_shared1_cert1_cert2
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_shared1_cert2
Normal file
BIN
core/tests/coretests/res/raw/install_shared1_cert2
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_shared1_unsigned
Normal file
BIN
core/tests/coretests/res/raw/install_shared1_unsigned
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_shared2_cert1
Normal file
BIN
core/tests/coretests/res/raw/install_shared2_cert1
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_shared2_cert12
Normal file
BIN
core/tests/coretests/res/raw/install_shared2_cert12
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_shared2_cert1_cert2
Normal file
BIN
core/tests/coretests/res/raw/install_shared2_cert1_cert2
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_shared2_cert2
Normal file
BIN
core/tests/coretests/res/raw/install_shared2_cert2
Normal file
Binary file not shown.
BIN
core/tests/coretests/res/raw/install_shared2_unsigned
Normal file
BIN
core/tests/coretests/res/raw/install_shared2_unsigned
Normal file
Binary file not shown.
@@ -23,10 +23,18 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.PackageParser;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.Resources.NotFoundException;
|
import android.content.res.Resources.NotFoundException;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.test.AndroidTestCase;
|
||||||
|
import android.test.suitebuilder.annotation.Suppress;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.util.Log;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.FileUtils;
|
import android.os.FileUtils;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -497,6 +505,15 @@ public class PackageManagerTests extends AndroidTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PackageParser.Package getParsedPackage(String outFileName, int rawResId) {
|
||||||
|
PackageManager pm = mContext.getPackageManager();
|
||||||
|
File filesDir = mContext.getFilesDir();
|
||||||
|
File outFile = new File(filesDir, outFileName);
|
||||||
|
Uri packageURI = getInstallablePackage(rawResId, outFile);
|
||||||
|
PackageParser.Package pkg = parsePackage(packageURI);
|
||||||
|
return pkg;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility function that reads a apk bundled as a raw resource
|
* Utility function that reads a apk bundled as a raw resource
|
||||||
* copies it into own data directory and invokes
|
* copies it into own data directory and invokes
|
||||||
@@ -529,7 +546,9 @@ public class PackageManagerTests extends AndroidTestCase {
|
|||||||
if (fail) {
|
if (fail) {
|
||||||
assertTrue(invokeInstallPackageFail(packageURI, flags,
|
assertTrue(invokeInstallPackageFail(packageURI, flags,
|
||||||
pkg.packageName, result));
|
pkg.packageName, result));
|
||||||
assertNotInstalled(pkg.packageName);
|
if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) == 0) {
|
||||||
|
assertNotInstalled(pkg.packageName);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
InstallReceiver receiver = new InstallReceiver(pkg.packageName);
|
InstallReceiver receiver = new InstallReceiver(pkg.packageName);
|
||||||
assertTrue(invokeInstallPackage(packageURI, flags,
|
assertTrue(invokeInstallPackage(packageURI, flags,
|
||||||
@@ -621,7 +640,7 @@ public class PackageManagerTests extends AndroidTestCase {
|
|||||||
* PackageManager api to install first and then replace it
|
* PackageManager api to install first and then replace it
|
||||||
* again.
|
* again.
|
||||||
*/
|
*/
|
||||||
public void replaceFromRawResource(int flags) {
|
private void sampleReplaceFromRawResource(int flags) {
|
||||||
InstallParams ip = sampleInstallFromRawResource(flags, false);
|
InstallParams ip = sampleInstallFromRawResource(flags, false);
|
||||||
boolean replace = ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0);
|
boolean replace = ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0);
|
||||||
Log.i(TAG, "replace=" + replace);
|
Log.i(TAG, "replace=" + replace);
|
||||||
@@ -648,28 +667,28 @@ public class PackageManagerTests extends AndroidTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testReplaceFailNormalInternal() {
|
public void testReplaceFailNormalInternal() {
|
||||||
replaceFromRawResource(0);
|
sampleReplaceFromRawResource(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testReplaceFailFwdLockedInternal() {
|
public void testReplaceFailFwdLockedInternal() {
|
||||||
replaceFromRawResource(PackageManager.INSTALL_FORWARD_LOCK);
|
sampleReplaceFromRawResource(PackageManager.INSTALL_FORWARD_LOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testReplaceFailSdcard() {
|
public void testReplaceFailSdcard() {
|
||||||
replaceFromRawResource(PackageManager.INSTALL_EXTERNAL);
|
sampleReplaceFromRawResource(PackageManager.INSTALL_EXTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testReplaceNormalInternal() {
|
public void testReplaceNormalInternal() {
|
||||||
replaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING);
|
sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testReplaceFwdLockedInternal() {
|
public void testReplaceFwdLockedInternal() {
|
||||||
replaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
|
sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
|
||||||
PackageManager.INSTALL_FORWARD_LOCK);
|
PackageManager.INSTALL_FORWARD_LOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testReplaceSdcard() {
|
public void testReplaceSdcard() {
|
||||||
replaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
|
sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
|
||||||
PackageManager.INSTALL_EXTERNAL);
|
PackageManager.INSTALL_EXTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1014,6 +1033,19 @@ public class PackageManagerTests extends AndroidTestCase {
|
|||||||
outFile.delete();
|
outFile.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void cleanUpInstall(String pkgName) {
|
||||||
|
if (pkgName == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.i(TAG, "Deleting package : " + pkgName);
|
||||||
|
try {
|
||||||
|
ApplicationInfo info = getPm().getApplicationInfo(pkgName,
|
||||||
|
PackageManager.GET_UNINSTALLED_PACKAGES);
|
||||||
|
if (info != null) {
|
||||||
|
getPm().deletePackage(pkgName, null, 0);
|
||||||
|
}
|
||||||
|
} catch (NameNotFoundException e) {}
|
||||||
|
}
|
||||||
|
|
||||||
public void testManifestInstallLocationInternal() {
|
public void testManifestInstallLocationInternal() {
|
||||||
installFromRawResource("install.apk", R.raw.install_loc_internal,
|
installFromRawResource("install.apk", R.raw.install_loc_internal,
|
||||||
@@ -2152,6 +2184,360 @@ public class PackageManagerTests extends AndroidTestCase {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* The following series of tests are related to upgrading apps with
|
||||||
|
* different certificates.
|
||||||
|
*/
|
||||||
|
private int APP1_UNSIGNED = R.raw.install_app1_unsigned;
|
||||||
|
private int APP1_CERT1 = R.raw.install_app1_cert1;
|
||||||
|
private int APP1_CERT2 = R.raw.install_app1_cert2;
|
||||||
|
private int APP1_CERT1_CERT2 = R.raw.install_app1_cert1_cert2;
|
||||||
|
private int APP1_CERT3_CERT4 = R.raw.install_app1_cert3_cert4;
|
||||||
|
private int APP1_CERT3 = R.raw.install_app1_cert3;
|
||||||
|
private int APP2_UNSIGNED = R.raw.install_app2_unsigned;
|
||||||
|
private int APP2_CERT1 = R.raw.install_app2_cert1;
|
||||||
|
private int APP2_CERT2 = R.raw.install_app2_cert2;
|
||||||
|
private int APP2_CERT1_CERT2 = R.raw.install_app2_cert1_cert2;
|
||||||
|
private int APP2_CERT3 = R.raw.install_app2_cert3;
|
||||||
|
|
||||||
|
private InstallParams replaceCerts(int apk1, int apk2, boolean cleanUp, boolean fail, int retCode) {
|
||||||
|
int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
|
||||||
|
String apk1Name = "install1.apk";
|
||||||
|
String apk2Name = "install2.apk";
|
||||||
|
PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
|
||||||
|
try {
|
||||||
|
InstallParams ip = installFromRawResource(apk1Name, apk1, 0, false,
|
||||||
|
false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
installFromRawResource(apk2Name, apk2, rFlags, false,
|
||||||
|
fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
return ip;
|
||||||
|
} catch (Exception e) {
|
||||||
|
failStr(e.getMessage());
|
||||||
|
} finally {
|
||||||
|
if (cleanUp) {
|
||||||
|
cleanUpInstall(pkg1.packageName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Test that an app signed with two certificates can be upgraded by the
|
||||||
|
* same app signed with two certificates.
|
||||||
|
*/
|
||||||
|
public void testReplaceMatchAllCerts() {
|
||||||
|
replaceCerts(APP1_CERT1_CERT2, APP1_CERT1_CERT2, true, false, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test that an app signed with two certificates cannot be upgraded
|
||||||
|
* by an app signed with a different certificate.
|
||||||
|
*/
|
||||||
|
public void testReplaceMatchNoCerts1() {
|
||||||
|
replaceCerts(APP1_CERT1_CERT2, APP1_CERT3, true, true,
|
||||||
|
PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Test that an app signed with two certificates cannot be upgraded
|
||||||
|
* by an app signed with a different certificate.
|
||||||
|
*/
|
||||||
|
public void testReplaceMatchNoCerts2() {
|
||||||
|
replaceCerts(APP1_CERT1_CERT2, APP1_CERT3_CERT4, true, true,
|
||||||
|
PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Test that an app signed with two certificates cannot be upgraded by
|
||||||
|
* an app signed with a subset of initial certificates.
|
||||||
|
*/
|
||||||
|
public void testReplaceMatchSomeCerts1() {
|
||||||
|
replaceCerts(APP1_CERT1_CERT2, APP1_CERT1, true, true,
|
||||||
|
PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Test that an app signed with two certificates cannot be upgraded by
|
||||||
|
* an app signed with the last certificate.
|
||||||
|
*/
|
||||||
|
public void testReplaceMatchSomeCerts2() {
|
||||||
|
replaceCerts(APP1_CERT1_CERT2, APP1_CERT2, true, true,
|
||||||
|
PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Test that an app signed with a certificate can be upgraded by app
|
||||||
|
* signed with a superset of certificates.
|
||||||
|
*/
|
||||||
|
public void testReplaceMatchMoreCerts() {
|
||||||
|
replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, true, true,
|
||||||
|
PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Test that an app signed with a certificate can be upgraded by app
|
||||||
|
* signed with a superset of certificates. Then verify that the an app
|
||||||
|
* signed with the original set of certs cannot upgrade the new one.
|
||||||
|
*/
|
||||||
|
public void testReplaceMatchMoreCertsReplaceSomeCerts() {
|
||||||
|
InstallParams ip = replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, false, true,
|
||||||
|
PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
|
||||||
|
try {
|
||||||
|
int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
|
||||||
|
installFromRawResource("install.apk", APP1_CERT1, rFlags, false,
|
||||||
|
false, -1,
|
||||||
|
PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
} catch (Exception e) {
|
||||||
|
failStr(e.getMessage());
|
||||||
|
} finally {
|
||||||
|
if (ip != null) {
|
||||||
|
cleanUpInstall(ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* The following tests are related to testing the checkSignatures
|
||||||
|
* api.
|
||||||
|
*/
|
||||||
|
private void checkSignatures(int apk1, int apk2, int expMatchResult) {
|
||||||
|
checkSharedSignatures(apk1, apk2, true, false, -1, expMatchResult);
|
||||||
|
}
|
||||||
|
public void testCheckSignaturesAllMatch() {
|
||||||
|
int apk1 = APP1_CERT1_CERT2;
|
||||||
|
int apk2 = APP2_CERT1_CERT2;
|
||||||
|
checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
|
||||||
|
}
|
||||||
|
public void testCheckSignaturesNoMatch() {
|
||||||
|
int apk1 = APP1_CERT1;
|
||||||
|
int apk2 = APP2_CERT2;
|
||||||
|
checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
|
||||||
|
}
|
||||||
|
public void testCheckSignaturesSomeMatch1() {
|
||||||
|
int apk1 = APP1_CERT1_CERT2;
|
||||||
|
int apk2 = APP2_CERT1;
|
||||||
|
checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
|
||||||
|
}
|
||||||
|
public void testCheckSignaturesSomeMatch2() {
|
||||||
|
int apk1 = APP1_CERT1_CERT2;
|
||||||
|
int apk2 = APP2_CERT2;
|
||||||
|
checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
|
||||||
|
}
|
||||||
|
public void testCheckSignaturesMoreMatch() {
|
||||||
|
int apk1 = APP1_CERT1;
|
||||||
|
int apk2 = APP2_CERT1_CERT2;
|
||||||
|
checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
|
||||||
|
}
|
||||||
|
public void testCheckSignaturesUnknown() {
|
||||||
|
int apk1 = APP1_CERT1_CERT2;
|
||||||
|
int apk2 = APP2_CERT1_CERT2;
|
||||||
|
String apk1Name = "install1.apk";
|
||||||
|
String apk2Name = "install2.apk";
|
||||||
|
InstallParams ip1 = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ip1 = installFromRawResource(apk1Name, apk1, 0, false,
|
||||||
|
false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
PackageManager pm = mContext.getPackageManager();
|
||||||
|
// Delete app2
|
||||||
|
File filesDir = mContext.getFilesDir();
|
||||||
|
File outFile = new File(filesDir, apk2Name);
|
||||||
|
int rawResId = apk2;
|
||||||
|
Uri packageURI = getInstallablePackage(rawResId, outFile);
|
||||||
|
PackageParser.Package pkg = parsePackage(packageURI);
|
||||||
|
getPm().deletePackage(pkg.packageName, null, 0);
|
||||||
|
// Check signatures now
|
||||||
|
int match = mContext.getPackageManager().checkSignatures(
|
||||||
|
ip1.pkg.packageName, pkg.packageName);
|
||||||
|
assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
|
||||||
|
} finally {
|
||||||
|
if (ip1 != null) {
|
||||||
|
cleanUpInstall(ip1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void testInstallNoCertificates() {
|
||||||
|
int apk1 = APP1_UNSIGNED;
|
||||||
|
String apk1Name = "install1.apk";
|
||||||
|
InstallParams ip1 = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
installFromRawResource(apk1Name, apk1, 0, false,
|
||||||
|
true, PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES,
|
||||||
|
PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* The following tests are related to apps using shared uids signed
|
||||||
|
* with different certs.
|
||||||
|
*/
|
||||||
|
private int SHARED1_UNSIGNED = R.raw.install_shared1_unsigned;
|
||||||
|
private int SHARED1_CERT1 = R.raw.install_shared1_cert1;
|
||||||
|
private int SHARED1_CERT2 = R.raw.install_shared1_cert2;
|
||||||
|
private int SHARED1_CERT1_CERT2 = R.raw.install_shared1_cert1_cert2;
|
||||||
|
private int SHARED2_UNSIGNED = R.raw.install_shared2_unsigned;
|
||||||
|
private int SHARED2_CERT1 = R.raw.install_shared2_cert1;
|
||||||
|
private int SHARED2_CERT2 = R.raw.install_shared2_cert2;
|
||||||
|
private int SHARED2_CERT1_CERT2 = R.raw.install_shared2_cert1_cert2;
|
||||||
|
private void checkSharedSignatures(int apk1, int apk2, boolean cleanUp, boolean fail, int retCode, int expMatchResult) {
|
||||||
|
String apk1Name = "install1.apk";
|
||||||
|
String apk2Name = "install2.apk";
|
||||||
|
PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
|
||||||
|
PackageParser.Package pkg2 = getParsedPackage(apk2Name, apk2);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Clean up before testing first.
|
||||||
|
cleanUpInstall(pkg1.packageName);
|
||||||
|
cleanUpInstall(pkg2.packageName);
|
||||||
|
installFromRawResource(apk1Name, apk1, 0, false,
|
||||||
|
false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
if (fail) {
|
||||||
|
installFromRawResource(apk2Name, apk2, 0, false,
|
||||||
|
true, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
} else {
|
||||||
|
installFromRawResource(apk2Name, apk2, 0, false,
|
||||||
|
false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
int match = mContext.getPackageManager().checkSignatures(
|
||||||
|
pkg1.packageName, pkg2.packageName);
|
||||||
|
assertEquals(expMatchResult, match);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (cleanUp) {
|
||||||
|
cleanUpInstall(pkg1.packageName);
|
||||||
|
cleanUpInstall(pkg2.packageName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void testCheckSignaturesSharedAllMatch() {
|
||||||
|
int apk1 = SHARED1_CERT1_CERT2;
|
||||||
|
int apk2 = SHARED2_CERT1_CERT2;
|
||||||
|
boolean fail = false;
|
||||||
|
int retCode = -1;
|
||||||
|
int expMatchResult = PackageManager.SIGNATURE_MATCH;
|
||||||
|
checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
|
||||||
|
}
|
||||||
|
public void testCheckSignaturesSharedNoMatch() {
|
||||||
|
int apk1 = SHARED1_CERT1;
|
||||||
|
int apk2 = SHARED2_CERT2;
|
||||||
|
boolean fail = true;
|
||||||
|
int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
|
||||||
|
int expMatchResult = -1;
|
||||||
|
checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Test that an app signed with cert1 and cert2 cannot be replaced when signed with cert1 alone.
|
||||||
|
*/
|
||||||
|
public void testCheckSignaturesSharedSomeMatch1() {
|
||||||
|
int apk1 = SHARED1_CERT1_CERT2;
|
||||||
|
int apk2 = SHARED2_CERT1;
|
||||||
|
boolean fail = true;
|
||||||
|
int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
|
||||||
|
int expMatchResult = -1;
|
||||||
|
checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Test that an app signed with cert1 and cert2 cannot be replaced when signed with cert2 alone.
|
||||||
|
*/
|
||||||
|
public void testCheckSignaturesSharedSomeMatch2() {
|
||||||
|
int apk1 = SHARED1_CERT1_CERT2;
|
||||||
|
int apk2 = SHARED2_CERT2;
|
||||||
|
boolean fail = true;
|
||||||
|
int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
|
||||||
|
int expMatchResult = -1;
|
||||||
|
checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
|
||||||
|
}
|
||||||
|
public void testCheckSignaturesSharedUnknown() {
|
||||||
|
int apk1 = SHARED1_CERT1_CERT2;
|
||||||
|
int apk2 = SHARED2_CERT1_CERT2;
|
||||||
|
String apk1Name = "install1.apk";
|
||||||
|
String apk2Name = "install2.apk";
|
||||||
|
InstallParams ip1 = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ip1 = installFromRawResource(apk1Name, apk1, 0, false,
|
||||||
|
false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
PackageManager pm = mContext.getPackageManager();
|
||||||
|
// Delete app2
|
||||||
|
PackageParser.Package pkg = getParsedPackage(apk2Name, apk2);
|
||||||
|
getPm().deletePackage(pkg.packageName, null, 0);
|
||||||
|
// Check signatures now
|
||||||
|
int match = mContext.getPackageManager().checkSignatures(
|
||||||
|
ip1.pkg.packageName, pkg.packageName);
|
||||||
|
assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
|
||||||
|
} finally {
|
||||||
|
if (ip1 != null) {
|
||||||
|
cleanUpInstall(ip1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testReplaceFirstSharedMatchAllCerts() {
|
||||||
|
int apk1 = SHARED1_CERT1;
|
||||||
|
int apk2 = SHARED2_CERT1;
|
||||||
|
int rapk1 = SHARED1_CERT1;
|
||||||
|
checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
|
||||||
|
replaceCerts(apk1, rapk1, true, false, -1);
|
||||||
|
}
|
||||||
|
public void testReplaceSecondSharedMatchAllCerts() {
|
||||||
|
int apk1 = SHARED1_CERT1;
|
||||||
|
int apk2 = SHARED2_CERT1;
|
||||||
|
int rapk2 = SHARED2_CERT1;
|
||||||
|
checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
|
||||||
|
replaceCerts(apk2, rapk2, true, false, -1);
|
||||||
|
}
|
||||||
|
public void testReplaceFirstSharedMatchSomeCerts() {
|
||||||
|
int apk1 = SHARED1_CERT1_CERT2;
|
||||||
|
int apk2 = SHARED2_CERT1_CERT2;
|
||||||
|
int rapk1 = SHARED1_CERT1;
|
||||||
|
boolean fail = true;
|
||||||
|
int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
|
||||||
|
checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
|
||||||
|
installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
|
||||||
|
fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
}
|
||||||
|
public void testReplaceSecondSharedMatchSomeCerts() {
|
||||||
|
int apk1 = SHARED1_CERT1_CERT2;
|
||||||
|
int apk2 = SHARED2_CERT1_CERT2;
|
||||||
|
int rapk2 = SHARED2_CERT1;
|
||||||
|
boolean fail = true;
|
||||||
|
int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
|
||||||
|
checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
|
||||||
|
installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
|
||||||
|
fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
}
|
||||||
|
public void testReplaceFirstSharedMatchNoCerts() {
|
||||||
|
int apk1 = SHARED1_CERT1;
|
||||||
|
int apk2 = SHARED2_CERT1;
|
||||||
|
int rapk1 = SHARED1_CERT2;
|
||||||
|
boolean fail = true;
|
||||||
|
int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
|
||||||
|
checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
|
||||||
|
installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
|
||||||
|
fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
}
|
||||||
|
public void testReplaceSecondSharedMatchNoCerts() {
|
||||||
|
int apk1 = SHARED1_CERT1;
|
||||||
|
int apk2 = SHARED2_CERT1;
|
||||||
|
int rapk2 = SHARED2_CERT2;
|
||||||
|
boolean fail = true;
|
||||||
|
int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
|
||||||
|
checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
|
||||||
|
installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
|
||||||
|
fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
}
|
||||||
|
public void testReplaceFirstSharedMatchMoreCerts() {
|
||||||
|
int apk1 = SHARED1_CERT1;
|
||||||
|
int apk2 = SHARED2_CERT1;
|
||||||
|
int rapk1 = SHARED1_CERT1_CERT2;
|
||||||
|
boolean fail = true;
|
||||||
|
int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
|
||||||
|
checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
|
||||||
|
installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
|
||||||
|
fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
}
|
||||||
|
public void testReplaceSecondSharedMatchMoreCerts() {
|
||||||
|
int apk1 = SHARED1_CERT1;
|
||||||
|
int apk2 = SHARED2_CERT1;
|
||||||
|
int rapk2 = SHARED2_CERT1_CERT2;
|
||||||
|
boolean fail = true;
|
||||||
|
int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
|
||||||
|
checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
|
||||||
|
installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
|
||||||
|
fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
}
|
||||||
/*---------- Recommended install location tests ----*/
|
/*---------- Recommended install location tests ----*/
|
||||||
/*
|
/*
|
||||||
* TODO's
|
* TODO's
|
||||||
|
|||||||
@@ -1835,21 +1835,19 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
if (s2 == null) {
|
if (s2 == null) {
|
||||||
return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
|
return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
|
||||||
}
|
}
|
||||||
final int N1 = s1.length;
|
HashSet<Signature> set1 = new HashSet<Signature>();
|
||||||
final int N2 = s2.length;
|
for (Signature sig : s1) {
|
||||||
for (int i=0; i<N1; i++) {
|
set1.add(sig);
|
||||||
boolean match = false;
|
|
||||||
for (int j=0; j<N2; j++) {
|
|
||||||
if (s1[i].equals(s2[j])) {
|
|
||||||
match = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!match) {
|
|
||||||
return PackageManager.SIGNATURE_NO_MATCH;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return PackageManager.SIGNATURE_MATCH;
|
HashSet<Signature> set2 = new HashSet<Signature>();
|
||||||
|
for (Signature sig : s2) {
|
||||||
|
set2.add(sig);
|
||||||
|
}
|
||||||
|
// Make sure s2 contains all signatures in s1.
|
||||||
|
if (set1.equals(set2)) {
|
||||||
|
return PackageManager.SIGNATURE_MATCH;
|
||||||
|
}
|
||||||
|
return PackageManager.SIGNATURE_NO_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getPackagesForUid(int uid) {
|
public String[] getPackagesForUid(int uid) {
|
||||||
@@ -2501,6 +2499,9 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
mLastScanError = pp.getParseError();
|
mLastScanError = pp.getParseError();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Lets implicitly assign existing certificates.
|
||||||
|
pkg.mSignatures = ps.signatures.mSignatures;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -2629,28 +2630,27 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean verifySignaturesLP(PackageSetting pkgSetting,
|
private boolean verifySignaturesLP(PackageSetting pkgSetting,
|
||||||
PackageParser.Package pkg, int parseFlags, boolean updateSignature) {
|
PackageParser.Package pkg) {
|
||||||
if (pkg.mSignatures != null) {
|
if (pkgSetting.signatures.mSignatures != null) {
|
||||||
if (!pkgSetting.signatures.updateSignatures(pkg.mSignatures,
|
// Already existing package. Make sure signatures match
|
||||||
updateSignature)) {
|
if (checkSignaturesLP(pkgSetting.signatures.mSignatures, pkg.mSignatures) !=
|
||||||
Slog.e(TAG, "Package " + pkg.packageName
|
PackageManager.SIGNATURE_MATCH) {
|
||||||
+ " signatures do not match the previously installed version; ignoring!");
|
|
||||||
mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pkgSetting.sharedUser != null) {
|
|
||||||
if (!pkgSetting.sharedUser.signatures.mergeSignatures(
|
|
||||||
pkg.mSignatures, updateSignature)) {
|
|
||||||
Slog.e(TAG, "Package " + pkg.packageName
|
Slog.e(TAG, "Package " + pkg.packageName
|
||||||
+ " has no signatures that match those in shared user "
|
+ " signatures do not match the previously installed version; ignoring!");
|
||||||
+ pkgSetting.sharedUser.name + "; ignoring!");
|
mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
|
||||||
mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// Check for shared user signatures
|
||||||
|
if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
|
||||||
|
if (checkSignaturesLP(pkgSetting.sharedUser.signatures.mSignatures,
|
||||||
|
pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
|
||||||
|
Slog.e(TAG, "Package " + pkg.packageName
|
||||||
|
+ " has no signatures that match those in shared user "
|
||||||
|
+ pkgSetting.sharedUser.name + "; ignoring!");
|
||||||
|
mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
pkg.mSignatures = pkgSetting.signatures.mSignatures;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2996,10 +2996,8 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
pkg.applicationInfo.uid = pkgSetting.userId;
|
pkg.applicationInfo.uid = pkgSetting.userId;
|
||||||
pkg.mExtras = pkgSetting;
|
pkg.mExtras = pkgSetting;
|
||||||
|
|
||||||
if (!verifySignaturesLP(pkgSetting, pkg, parseFlags,
|
if (!verifySignaturesLP(pkgSetting, pkg)) {
|
||||||
(scanMode&SCAN_UPDATE_SIGNATURE) != 0)) {
|
|
||||||
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
|
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
|
||||||
mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// The signature has changed, but this package is in the system
|
// The signature has changed, but this package is in the system
|
||||||
@@ -3011,8 +3009,9 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
// associated with an overall shared user, which doesn't seem all
|
// associated with an overall shared user, which doesn't seem all
|
||||||
// that unreasonable.
|
// that unreasonable.
|
||||||
if (pkgSetting.sharedUser != null) {
|
if (pkgSetting.sharedUser != null) {
|
||||||
if (!pkgSetting.sharedUser.signatures.mergeSignatures(
|
if (checkSignaturesLP(pkgSetting.sharedUser.signatures.mSignatures,
|
||||||
pkg.mSignatures, false)) {
|
pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
|
||||||
|
Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser);
|
||||||
mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
|
mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -5543,7 +5542,7 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
// First find the old package info and check signatures
|
// First find the old package info and check signatures
|
||||||
synchronized(mPackages) {
|
synchronized(mPackages) {
|
||||||
oldPackage = mPackages.get(pkgName);
|
oldPackage = mPackages.get(pkgName);
|
||||||
if (checkSignaturesLP(pkg.mSignatures, oldPackage.mSignatures)
|
if (checkSignaturesLP(oldPackage.mSignatures, pkg.mSignatures)
|
||||||
!= PackageManager.SIGNATURE_MATCH) {
|
!= PackageManager.SIGNATURE_MATCH) {
|
||||||
res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
|
res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
|
||||||
return;
|
return;
|
||||||
@@ -5571,7 +5570,6 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
oldInstallerPackageName = mSettings.getInstallerPackageName(pkgName);
|
oldInstallerPackageName = mSettings.getInstallerPackageName(pkgName);
|
||||||
}
|
}
|
||||||
|
|
||||||
parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
|
|
||||||
// First delete the existing package while retaining the data directory
|
// First delete the existing package while retaining the data directory
|
||||||
if (!deletePackageLI(pkgName, true, PackageManager.DONT_DELETE_DATA,
|
if (!deletePackageLI(pkgName, true, PackageManager.DONT_DELETE_DATA,
|
||||||
res.removedInfo)) {
|
res.removedInfo)) {
|
||||||
@@ -5595,20 +5593,7 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
|
if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
|
||||||
// If we deleted an exisiting package, the old source and resource files that we
|
|
||||||
// were keeping around in case we needed them (see below) can now be deleted.
|
|
||||||
// This info will be set on the res.removedInfo to clean up later on as post
|
|
||||||
// install action.
|
|
||||||
|
|
||||||
//update signature on the new package setting
|
|
||||||
//this should always succeed, since we checked the
|
|
||||||
//signature earlier.
|
|
||||||
synchronized(mPackages) {
|
|
||||||
verifySignaturesLP(mSettings.mPackages.get(pkgName), pkg,
|
|
||||||
parseFlags, true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// remove package from internal structures. Note that we want deletePackageX to
|
// remove package from internal structures. Note that we want deletePackageX to
|
||||||
// delete the package data and cache directories that it created in
|
// delete the package data and cache directories that it created in
|
||||||
// scanPackageLocked, unless those directories existed before we even tried to
|
// scanPackageLocked, unless those directories existed before we even tried to
|
||||||
@@ -5627,19 +5612,23 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
Slog.e(TAG, "Failed allocating storage when restoring pkg : " + pkgName);
|
Slog.e(TAG, "Failed allocating storage when restoring pkg : " + pkgName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PackageInstalledInfo restoreRes = new PackageInstalledInfo();
|
|
||||||
restoreRes.removedInfo = new PackageRemovedInfo();
|
|
||||||
// Parse old package
|
// Parse old package
|
||||||
parseFlags &= ~PackageManager.INSTALL_REPLACE_EXISTING;
|
boolean oldOnSd = isExternal(deletedPackage);
|
||||||
scanPackageLI(restoreFile, parseFlags, scanMode);
|
int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY |
|
||||||
|
(isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
|
||||||
|
(oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
|
||||||
|
int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE;
|
||||||
|
if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode) == null) {
|
||||||
|
Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Restore of old package succeeded. Update permissions.
|
||||||
synchronized (mPackages) {
|
synchronized (mPackages) {
|
||||||
updatePermissionsLP(deletedPackage.packageName, deletedPackage,
|
updatePermissionsLP(deletedPackage.packageName, deletedPackage,
|
||||||
true, false);
|
true, false);
|
||||||
mSettings.writeLP();
|
mSettings.writeLP();
|
||||||
}
|
}
|
||||||
if (restoreRes.returnCode != PackageManager.INSTALL_SUCCEEDED) {
|
Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
|
||||||
Slog.e(TAG, "Failed restoring pkg : " + pkgName + " after failed upgrade");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5691,15 +5680,7 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
updatedSettings = true;
|
updatedSettings = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
|
if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
|
||||||
//update signature on the new package setting
|
|
||||||
//this should always succeed, since we checked the
|
|
||||||
//signature earlier.
|
|
||||||
synchronized(mPackages) {
|
|
||||||
verifySignaturesLP(mSettings.mPackages.get(packageName), pkg,
|
|
||||||
parseFlags, true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Re installation failed. Restore old information
|
// Re installation failed. Restore old information
|
||||||
// Remove new pkg information
|
// Remove new pkg information
|
||||||
if (newPackage != null) {
|
if (newPackage != null) {
|
||||||
@@ -5781,7 +5762,7 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
|
boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
|
||||||
boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0);
|
boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0);
|
||||||
boolean replace = false;
|
boolean replace = false;
|
||||||
int scanMode = SCAN_MONITOR | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE
|
int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE
|
||||||
| (newInstall ? SCAN_NEW_INSTALL : 0);
|
| (newInstall ? SCAN_NEW_INSTALL : 0);
|
||||||
// Result object to be returned
|
// Result object to be returned
|
||||||
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
|
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
|
||||||
@@ -5911,6 +5892,10 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
return ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
|
return ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isExternal(PackageParser.Package pkg) {
|
||||||
|
return ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
private void extractPublicFiles(PackageParser.Package newPackage,
|
private void extractPublicFiles(PackageParser.Package newPackage,
|
||||||
File publicZipFile) throws IOException {
|
File publicZipFile) throws IOException {
|
||||||
final ZipOutputStream publicZipOutStream =
|
final ZipOutputStream publicZipOutStream =
|
||||||
@@ -7345,101 +7330,6 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* If any of the given 'sigs' is contained in the existing signatures,
|
|
||||||
* then completely replace the current signatures with the ones in
|
|
||||||
* 'sigs'. This is used for updating an existing package to a newly
|
|
||||||
* installed version.
|
|
||||||
*/
|
|
||||||
boolean updateSignatures(Signature[] sigs, boolean update) {
|
|
||||||
if (mSignatures == null) {
|
|
||||||
if (update) {
|
|
||||||
assignSignatures(sigs);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (sigs == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<sigs.length; i++) {
|
|
||||||
Signature sig = sigs[i];
|
|
||||||
for (int j=0; j<mSignatures.length; j++) {
|
|
||||||
if (mSignatures[j].equals(sig)) {
|
|
||||||
if (update) {
|
|
||||||
assignSignatures(sigs);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If any of the given 'sigs' is contained in the existing signatures,
|
|
||||||
* then add in any new signatures found in 'sigs'. This is used for
|
|
||||||
* including a new package into an existing shared user id.
|
|
||||||
*/
|
|
||||||
boolean mergeSignatures(Signature[] sigs, boolean update) {
|
|
||||||
if (mSignatures == null) {
|
|
||||||
if (update) {
|
|
||||||
assignSignatures(sigs);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (sigs == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Signature[] added = null;
|
|
||||||
int addedCount = 0;
|
|
||||||
boolean haveMatch = false;
|
|
||||||
for (int i=0; i<sigs.length; i++) {
|
|
||||||
Signature sig = sigs[i];
|
|
||||||
boolean found = false;
|
|
||||||
for (int j=0; j<mSignatures.length; j++) {
|
|
||||||
if (mSignatures[j].equals(sig)) {
|
|
||||||
found = true;
|
|
||||||
haveMatch = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
if (added == null) {
|
|
||||||
added = new Signature[sigs.length];
|
|
||||||
}
|
|
||||||
added[i] = sig;
|
|
||||||
addedCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!haveMatch) {
|
|
||||||
// Nothing matched -- reject the new signatures.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (added == null) {
|
|
||||||
// Completely matched -- nothing else to do.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add additional signatures in.
|
|
||||||
if (update) {
|
|
||||||
Signature[] total = new Signature[addedCount+mSignatures.length];
|
|
||||||
System.arraycopy(mSignatures, 0, total, 0, mSignatures.length);
|
|
||||||
int j = mSignatures.length;
|
|
||||||
for (int i=0; i<added.length; i++) {
|
|
||||||
if (added[i] != null) {
|
|
||||||
total[j] = added[i];
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mSignatures = total;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assignSignatures(Signature[] sigs) {
|
private void assignSignatures(Signature[] sigs) {
|
||||||
if (sigs == null) {
|
if (sigs == null) {
|
||||||
mSignatures = null;
|
mSignatures = null;
|
||||||
@@ -8227,6 +8117,15 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
if (pkg.mVersionCode != p.versionCode) {
|
if (pkg.mVersionCode != p.versionCode) {
|
||||||
p.versionCode = pkg.mVersionCode;
|
p.versionCode = pkg.mVersionCode;
|
||||||
}
|
}
|
||||||
|
// Update signatures if needed.
|
||||||
|
if (p.signatures.mSignatures == null) {
|
||||||
|
p.signatures.assignSignatures(pkg.mSignatures);
|
||||||
|
}
|
||||||
|
// If this app defines a shared user id initialize
|
||||||
|
// the shared user signatures as well.
|
||||||
|
if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) {
|
||||||
|
p.sharedUser.signatures.assignSignatures(pkg.mSignatures);
|
||||||
|
}
|
||||||
addPackageSettingLP(p, pkg.packageName, p.sharedUser);
|
addPackageSettingLP(p, pkg.packageName, p.sharedUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9655,22 +9554,12 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
// Parse package
|
// Parse package
|
||||||
int parseFlags = PackageParser.PARSE_CHATTY |
|
int parseFlags = PackageParser.PARSE_CHATTY |
|
||||||
PackageParser.PARSE_ON_SDCARD | mDefParseFlags;
|
PackageParser.PARSE_ON_SDCARD | mDefParseFlags;
|
||||||
PackageParser pp = new PackageParser(codePath);
|
|
||||||
pp.setSeparateProcesses(mSeparateProcesses);
|
|
||||||
final PackageParser.Package pkg = pp.parsePackage(new File(codePath),
|
|
||||||
codePath, mMetrics, parseFlags);
|
|
||||||
pp = null;
|
|
||||||
doGc = true;
|
doGc = true;
|
||||||
// Check for parse errors
|
|
||||||
if (pkg == null) {
|
|
||||||
Slog.e(TAG, "Parse error when installing install pkg : "
|
|
||||||
+ args.cid + " from " + args.cachePath);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
setApplicationInfoPaths(pkg, codePath, codePath);
|
|
||||||
synchronized (mInstallLock) {
|
synchronized (mInstallLock) {
|
||||||
|
final PackageParser.Package pkg = scanPackageLI(new File(codePath),
|
||||||
|
parseFlags, 0);
|
||||||
// Scan the package
|
// Scan the package
|
||||||
if (scanPackageLI(pkg, parseFlags, SCAN_MONITOR) != null) {
|
if (pkg != null) {
|
||||||
synchronized (mPackages) {
|
synchronized (mPackages) {
|
||||||
retCode = PackageManager.INSTALL_SUCCEEDED;
|
retCode = PackageManager.INSTALL_SUCCEEDED;
|
||||||
pkgList.add(pkg.packageName);
|
pkgList.add(pkg.packageName);
|
||||||
@@ -9678,8 +9567,8 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
args.doPostInstall(PackageManager.INSTALL_SUCCEEDED);
|
args.doPostInstall(PackageManager.INSTALL_SUCCEEDED);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Slog.i(TAG, "Failed to install pkg: " +
|
Slog.i(TAG, "Failed to install pkg from " +
|
||||||
pkg.packageName + " from sdcard");
|
codePath + " from sdcard");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user