diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-05-08 14:46:41 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2009-05-08 14:46:41 -0700 |
commit | c39aae0ee060b4ff54ba0ab37fd1925ce191f013 (patch) | |
tree | 56cfce33540826a0027219487725a3387a751adc /services/java/com | |
parent | 7b59fe316e23e05ef33648a855c2280dd8fad981 (diff) | |
parent | c2af31f89bf3688db066c6eaee44d3b6bdc1d6ef (diff) | |
download | frameworks_base-c39aae0ee060b4ff54ba0ab37fd1925ce191f013.zip frameworks_base-c39aae0ee060b4ff54ba0ab37fd1925ce191f013.tar.gz frameworks_base-c39aae0ee060b4ff54ba0ab37fd1925ce191f013.tar.bz2 |
Merge change 1278 into donut
* changes:
Squashed commit of the following:
Diffstat (limited to 'services/java/com')
-rw-r--r-- | services/java/com/android/server/PackageManagerService.java | 152 |
1 files changed, 101 insertions, 51 deletions
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index 159bc76..a60f059 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -1761,8 +1761,7 @@ class PackageManagerService extends IPackageManager.Stub { PackageSetting ps; PackageSetting updatedPkg; synchronized (mPackages) { - ps = mSettings.peekPackageLP(pkg.packageName, - scanFile.toString()); + ps = mSettings.peekPackageLP(pkg.packageName); updatedPkg = mSettings.mDisabledSysPackages.get(pkg.packageName); } if (updatedPkg != null) { @@ -1771,13 +1770,21 @@ class PackageManagerService extends IPackageManager.Stub { } if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { // Check for updated system applications here - if ((updatedPkg != null) && (ps == null)) { - // The system package has been updated and the code path does not match - // Ignore entry. Just return - Log.w(TAG, "Package:" + pkg.packageName + - " has been updated. Ignoring the one from path:"+scanFile); - mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; - return null; + if (updatedPkg != null) { + if ((ps != null) && (!ps.codePath.getPath().equals(scanFile.getPath()))) { + if (pkg.mVersionCode <= ps.versionCode) { + // The system package has been updated and the code path does not match + // Ignore entry. Just return + Log.w(TAG, "Package:" + pkg.packageName + + " has been updated. Ignoring the one from path:"+scanFile); + mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; + return null; + } else { + // Delete the older apk pointed to by ps + deletePackageResourcesLI(ps.name, ps.codePathString, ps.resourcePathString); + mSettings.enableSystemPackageLP(ps.name); + } + } } } if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) { @@ -3341,23 +3348,23 @@ class PackageManagerService extends IPackageManager.Stub { String destFilePath, File destPackageFile, File destResourceFile, PackageParser.Package pkg, boolean forwardLocked, boolean newInstall, PackageInstalledInfo res) { - PackageParser.Package deletedPackage; + PackageParser.Package oldPackage; // First find the old package info and check signatures synchronized(mPackages) { - deletedPackage = mPackages.get(pkgName); - if(checkSignaturesLP(pkg, deletedPackage) != PackageManager.SIGNATURE_MATCH) { + oldPackage = mPackages.get(pkgName); + if(checkSignaturesLP(pkg, oldPackage) != PackageManager.SIGNATURE_MATCH) { res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; return; } } - boolean sysPkg = ((deletedPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0); + boolean sysPkg = ((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0); if(sysPkg) { - replaceSystemPackageLI(deletedPackage, + replaceSystemPackageLI(oldPackage, tmpPackageFile, destFilePath, destPackageFile, destResourceFile, pkg, forwardLocked, newInstall, res); } else { - replaceNonSystemPackageLI(deletedPackage, tmpPackageFile, destFilePath, + replaceNonSystemPackageLI(oldPackage, tmpPackageFile, destFilePath, destPackageFile, destResourceFile, pkg, forwardLocked, newInstall, res); } @@ -3996,7 +4003,7 @@ class PackageManagerService extends IPackageManager.Stub { * Tries to delete system package. */ private boolean deleteSystemPackageLI(PackageParser.Package p, - boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo) { + int flags, PackageRemovedInfo outInfo) { ApplicationInfo applicationInfo = p.applicationInfo; //applicable for non-partially installed applications only if (applicationInfo == null) { @@ -4018,6 +4025,19 @@ class PackageManagerService extends IPackageManager.Stub { } // Delete the updated package outInfo.isRemovedPackageSystemUpdate = true; + boolean deleteCodeAndResources = false; + if (ps.versionCode < p.mVersionCode) { + // Delete code and resources for downgrades + deleteCodeAndResources = true; + if ((flags & PackageManager.DONT_DELETE_DATA) == 0) { + flags &= ~PackageManager.DONT_DELETE_DATA; + } + } else { + // Preserve data by setting flag + if ((flags & PackageManager.DONT_DELETE_DATA) == 0) { + flags |= PackageManager.DONT_DELETE_DATA; + } + } boolean ret = deleteInstalledPackageLI(p, deleteCodeAndResources, flags, outInfo); if (!ret) { return false; @@ -4041,6 +4061,28 @@ class PackageManagerService extends IPackageManager.Stub { return true; } + private void deletePackageResourcesLI(String packageName, + String sourceDir, String publicSourceDir) { + File sourceFile = new File(sourceDir); + if (!sourceFile.exists()) { + Log.w(TAG, "Package source " + sourceDir + " does not exist."); + } + // Delete application's code and resources + sourceFile.delete(); + final File publicSourceFile = new File(publicSourceDir); + if (publicSourceFile.exists()) { + publicSourceFile.delete(); + } + if (mInstaller != null) { + int retCode = mInstaller.rmdex(sourceFile.toString()); + if (retCode < 0) { + Log.w(TAG, "Couldn't remove dex file for package: " + + packageName + " at location " + sourceFile.toString() + ", retcode=" + retCode); + // we don't consider this to be a failure of the core package deletion + } + } + } + private boolean deleteInstalledPackageLI(PackageParser.Package p, boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo) { ApplicationInfo applicationInfo = p.applicationInfo; @@ -4048,11 +4090,6 @@ class PackageManagerService extends IPackageManager.Stub { Log.w(TAG, "Package " + p.packageName + " has no applicationInfo."); return false; } - // Delete application's source directory - File sourceFile = new File(applicationInfo.sourceDir); - if (!sourceFile.exists()) { - Log.w(TAG, "Package source " + applicationInfo.sourceDir + " does not exist."); - } outInfo.uid = applicationInfo.uid; // Delete package data from internal structures and also remove data if flag is set @@ -4060,19 +4097,8 @@ class PackageManagerService extends IPackageManager.Stub { // Delete application code and resources if (deleteCodeAndResources) { - sourceFile.delete(); - final File publicSourceFile = new File(applicationInfo.publicSourceDir); - if (publicSourceFile.exists()) { - publicSourceFile.delete(); - } - if (mInstaller != null) { - int retCode = mInstaller.rmdex(sourceFile.toString()); - if (retCode < 0) { - Log.w(TAG, "Couldn't remove dex file for package: " - + p.packageName + " at location " + sourceFile.toString() + ", retcode=" + retCode); - // we don't consider this to be a failure of the core package deletion - } - } + deletePackageResourcesLI(applicationInfo.packageName, + applicationInfo.sourceDir, applicationInfo.publicSourceDir); } return true; } @@ -4120,7 +4146,7 @@ class PackageManagerService extends IPackageManager.Stub { Log.i(TAG, "Removing system package:"+p.packageName); // When an updated system application is deleted we delete the existing resources as well and // fall back to existing code in system partition - return deleteSystemPackageLI(p, true, flags, outInfo); + return deleteSystemPackageLI(p, flags, outInfo); } Log.i(TAG, "Removing non-system package:"+p.packageName); return deleteInstalledPackageLI (p, deleteCodeAndResources, flags, outInfo); @@ -5152,6 +5178,7 @@ class PackageManagerService extends IPackageManager.Stub { final String resourcePathString; private long timeStamp; private String timeStampString = "0"; + final int versionCode; PackageSignatures signatures = new PackageSignatures(); @@ -5165,13 +5192,14 @@ class PackageManagerService extends IPackageManager.Stub { int installStatus = PKG_INSTALL_COMPLETE; PackageSettingBase(String name, File codePath, File resourcePath, - int pkgFlags) { + int pVersionCode, int pkgFlags) { super(pkgFlags); this.name = name; this.codePath = codePath; this.codePathString = codePath.toString(); this.resourcePath = resourcePath; this.resourcePathString = resourcePath.toString(); + this.versionCode = pVersionCode; } public void setInstallStatus(int newStatus) { @@ -5252,8 +5280,8 @@ class PackageManagerService extends IPackageManager.Stub { SharedUserSetting sharedUser; PackageSetting(String name, File codePath, File resourcePath, - int pkgFlags) { - super(name, codePath, resourcePath, pkgFlags); + int pVersionCode, int pkgFlags) { + super(name, codePath, resourcePath, pVersionCode, pkgFlags); } @Override @@ -5351,8 +5379,8 @@ class PackageManagerService extends IPackageManager.Stub { final int sharedId; PendingPackage(String name, File codePath, File resourcePath, - int sharedId, int pkgFlags) { - super(name, codePath, resourcePath, pkgFlags); + int sharedId, int pVersionCode, int pkgFlags) { + super(name, codePath, resourcePath, pVersionCode, pkgFlags); this.sharedId = sharedId; } } @@ -5376,7 +5404,7 @@ class PackageManagerService extends IPackageManager.Stub { int pkgFlags, boolean create, boolean add) { final String name = pkg.packageName; PackageSetting p = getPackageLP(name, sharedUser, codePath, - resourcePath, pkgFlags, create, add); + resourcePath, pkg.mVersionCode, pkgFlags, create, add); if (p != null) { p.pkg = pkg; @@ -5384,12 +5412,15 @@ class PackageManagerService extends IPackageManager.Stub { return p; } - PackageSetting peekPackageLP(String name, String codePath) { + PackageSetting peekPackageLP(String name) { + return mPackages.get(name); + /* PackageSetting p = mPackages.get(name); if (p != null && p.codePath.getPath().equals(codePath)) { return p; } return null; + */ } void setInstallStatus(String pkgName, int status) { @@ -5461,13 +5492,13 @@ class PackageManagerService extends IPackageManager.Stub { p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; } PackageSetting ret = addPackageLP(name, p.codePath, - p.resourcePath, p.userId, p.pkgFlags); + p.resourcePath, p.userId, p.versionCode, p.pkgFlags); mDisabledSysPackages.remove(name); return ret; } PackageSetting addPackageLP(String name, File codePath, - File resourcePath, int uid, int pkgFlags) { + File resourcePath, int uid, int vc, int pkgFlags) { PackageSetting p = mPackages.get(name); if (p != null) { if (p.userId == uid) { @@ -5477,7 +5508,7 @@ class PackageManagerService extends IPackageManager.Stub { "Adding duplicate package, keeping first: " + name); return null; } - p = new PackageSetting(name, codePath, resourcePath, pkgFlags); + p = new PackageSetting(name, codePath, resourcePath, vc, pkgFlags); p.userId = uid; if (addUserIdLP(uid, p, name)) { mPackages.put(name, p); @@ -5507,7 +5538,7 @@ class PackageManagerService extends IPackageManager.Stub { private PackageSetting getPackageLP(String name, SharedUserSetting sharedUser, File codePath, File resourcePath, - int pkgFlags, boolean create, boolean add) { + int vc, int pkgFlags, boolean create, boolean add) { PackageSetting p = mPackages.get(name); if (p != null) { if (!p.codePath.equals(codePath)) { @@ -5549,7 +5580,7 @@ class PackageManagerService extends IPackageManager.Stub { if (!create) { return null; } - p = new PackageSetting(name, codePath, resourcePath, pkgFlags); + p = new PackageSetting(name, codePath, resourcePath, vc, pkgFlags); p.setTimeStamp(codePath.lastModified()); if (sharedUser != null) { p.userId = sharedUser.userId; @@ -5816,6 +5847,7 @@ class PackageManagerService extends IPackageManager.Stub { serializer.attribute(null, "name", pkg.name); serializer.attribute(null, "codePath", pkg.codePathString); serializer.attribute(null, "ts", pkg.getTimeStampStr()); + serializer.attribute(null, "version", String.valueOf(pkg.versionCode)); if (!pkg.resourcePathString.equals(pkg.codePathString)) { serializer.attribute(null, "resourcePath", pkg.resourcePathString); } @@ -5859,6 +5891,7 @@ class PackageManagerService extends IPackageManager.Stub { (pkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 ? "true" : "false"); serializer.attribute(null, "ts", pkg.getTimeStampStr()); + serializer.attribute(null, "version", String.valueOf(pkg.versionCode)); if (pkg.sharedUser == null) { serializer.attribute(null, "userId", Integer.toString(pkg.userId)); @@ -6050,7 +6083,7 @@ class PackageManagerService extends IPackageManager.Stub { if (idObj != null && idObj instanceof SharedUserSetting) { PackageSetting p = getPackageLP(pp.name, (SharedUserSetting)idObj, pp.codePath, pp.resourcePath, - pp.pkgFlags, true, true); + pp.versionCode, pp.pkgFlags, true, true); if (p == null) { Log.w(TAG, "Unable to create application package for " + pp.name); @@ -6169,12 +6202,20 @@ class PackageManagerService extends IPackageManager.Stub { if(resourcePathStr == null) { resourcePathStr = codePathStr; } + String version = parser.getAttributeValue(null, "version"); + int versionCode = 0; + if (version != null) { + try { + versionCode = Integer.parseInt(version); + } catch (NumberFormatException e) { + } + } int pkgFlags = 0; pkgFlags |= ApplicationInfo.FLAG_SYSTEM; PackageSetting ps = new PackageSetting(name, new File(codePathStr), - new File(resourcePathStr), pkgFlags); + new File(resourcePathStr), versionCode, pkgFlags); String timeStampStr = parser.getAttributeValue(null, "ts"); if (timeStampStr != null) { try { @@ -6225,12 +6266,21 @@ class PackageManagerService extends IPackageManager.Stub { String timeStampStr; long timeStamp = 0; PackageSettingBase packageSetting = null; + String version = null; + int versionCode = 0; try { name = parser.getAttributeValue(null, "name"); idStr = parser.getAttributeValue(null, "userId"); sharedIdStr = parser.getAttributeValue(null, "sharedUserId"); codePathStr = parser.getAttributeValue(null, "codePath"); resourcePathStr = parser.getAttributeValue(null, "resourcePath"); + version = parser.getAttributeValue(null, "version"); + if (version != null) { + try { + versionCode = Integer.parseInt(version); + } catch (NumberFormatException e) { + } + } systemStr = parser.getAttributeValue(null, "system"); if (systemStr != null) { if ("true".equals(systemStr)) { @@ -6264,7 +6314,7 @@ class PackageManagerService extends IPackageManager.Stub { + parser.getPositionDescription()); } else if (userId > 0) { packageSetting = addPackageLP(name.intern(), new File(codePathStr), - new File(resourcePathStr), userId, pkgFlags); + new File(resourcePathStr), userId, versionCode, pkgFlags); if (DEBUG_SETTINGS) Log.i(TAG, "Reading package " + name + ": userId=" + userId + " pkg=" + packageSetting); if (packageSetting == null) { @@ -6280,7 +6330,7 @@ class PackageManagerService extends IPackageManager.Stub { ? Integer.parseInt(sharedIdStr) : 0; if (userId > 0) { packageSetting = new PendingPackage(name.intern(), new File(codePathStr), - new File(resourcePathStr), userId, pkgFlags); + new File(resourcePathStr), userId, versionCode, pkgFlags); packageSetting.setTimeStamp(timeStamp, timeStampStr); mPendingPackages.add((PendingPackage) packageSetting); if (DEBUG_SETTINGS) Log.i(TAG, "Reading package " + name |