Skip to content

Commit 208d341

Browse files
committed
Handle addition of system apps during OTA
If there were apps already installed that were added in a later system OTA, bad things would happen. If the previously installed application is an older version, simply delete the installed application. If the system app is older than the previously installed one, mark it as a disabled system app and use the previoulsy installed application. Additionally, the application will now have the correct granted permissions. Bug: 6251602 Change-Id: Iea444b6acac460fca1e08d4e2cbf68a258214ca6
1 parent 59f3f58 commit 208d341

File tree

1 file changed

+103
-8
lines changed

1 file changed

+103
-8
lines changed

services/java/com/android/server/pm/PackageManagerService.java

Lines changed: 103 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,7 @@ public PackageManagerService(Context context, boolean factoryTest, boolean onlyC
10501050
mSystemInstallObserver.startWatching();
10511051
scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
10521052
| PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
1053-
1053+
10541054
// Collect all vendor packages.
10551055
mVendorAppDir = new File("/vendor/app");
10561056
mVendorInstallObserver = new AppDirObserver(
@@ -1068,8 +1068,30 @@ public PackageManagerService(Context context, boolean factoryTest, boolean onlyC
10681068
Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
10691069
while (psit.hasNext()) {
10701070
PackageSetting ps = psit.next();
1071-
if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
1072-
|| mPackages.containsKey(ps.name)) {
1071+
1072+
/*
1073+
* If this is not a system app, it can't be a
1074+
* disable system app.
1075+
*/
1076+
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1077+
continue;
1078+
}
1079+
1080+
/*
1081+
* If the package is scanned, it's not erased.
1082+
*/
1083+
if (mPackages.containsKey(ps.name)) {
1084+
/*
1085+
* If the system app is both scanned and in the
1086+
* disabled packages list, then it must have been
1087+
* added via OTA. Remove it from the currently
1088+
* scanned package so the previously user-installed
1089+
* application can be scanned.
1090+
*/
1091+
if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
1092+
mPackages.remove(ps.name);
1093+
}
1094+
10731095
continue;
10741096
}
10751097

@@ -3096,22 +3118,71 @@ private PackageParser.Package scanPackageLI(File scanFile,
30963118
+ "reverting from " + ps.codePathString
30973119
+ ": new version " + pkg.mVersionCode
30983120
+ " better than installed " + ps.versionCode);
3099-
InstallArgs args = new FileInstallArgs(ps.codePathString,
3121+
InstallArgs args = createInstallArgs(ps.pkgFlags, ps.codePathString,
31003122
ps.resourcePathString, ps.nativeLibraryPathString);
3101-
args.cleanUpResourcesLI();
3102-
mSettings.enableSystemPackageLPw(ps.name);
3123+
synchronized (mInstaller) {
3124+
args.cleanUpResourcesLI();
3125+
}
3126+
synchronized (mPackages) {
3127+
mSettings.enableSystemPackageLPw(ps.name);
3128+
}
31033129
}
31043130
}
31053131
}
3132+
31063133
if (updatedPkg != null) {
3107-
// An updated system app will not have the PARSE_IS_SYSTEM flag set initially
3134+
// An updated system app will not have the PARSE_IS_SYSTEM flag set
3135+
// initially
31083136
parseFlags |= PackageParser.PARSE_IS_SYSTEM;
31093137
}
31103138
// Verify certificates against what was last scanned
31113139
if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
31123140
Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
31133141
return null;
31143142
}
3143+
3144+
/*
3145+
* A new system app appeared, but we already had a non-system one of the
3146+
* same name installed earlier.
3147+
*/
3148+
boolean shouldHideSystemApp = false;
3149+
if (updatedPkg == null && ps != null
3150+
&& (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
3151+
/*
3152+
* Check to make sure the signatures match first. If they don't,
3153+
* wipe the installed application and its data.
3154+
*/
3155+
if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
3156+
!= PackageManager.SIGNATURE_MATCH) {
3157+
deletePackageLI(pkg.packageName, true, 0, null, false);
3158+
ps = null;
3159+
} else {
3160+
/*
3161+
* If the newly-added system app is an older version than the
3162+
* already installed version, hide it. It will be scanned later
3163+
* and re-added like an update.
3164+
*/
3165+
if (pkg.mVersionCode < ps.versionCode) {
3166+
shouldHideSystemApp = true;
3167+
} else {
3168+
/*
3169+
* The newly found system app is a newer version that the
3170+
* one previously installed. Simply remove the
3171+
* already-installed application and replace it with our own
3172+
* while keeping the application data.
3173+
*/
3174+
Slog.w(TAG, "Package " + ps.name + " at " + scanFile + "reverting from "
3175+
+ ps.codePathString + ": new version " + pkg.mVersionCode
3176+
+ " better than installed " + ps.versionCode);
3177+
InstallArgs args = createInstallArgs(ps.pkgFlags, ps.codePathString,
3178+
ps.resourcePathString, ps.nativeLibraryPathString);
3179+
synchronized (mInstaller) {
3180+
args.cleanUpResourcesLI();
3181+
}
3182+
}
3183+
}
3184+
}
3185+
31153186
// The apk is forward locked (not public) if its code and resources
31163187
// are kept in different files.
31173188
// TODO grab this value from PackageSettings
@@ -3135,7 +3206,27 @@ private PackageParser.Package scanPackageLI(File scanFile,
31353206
// Set application objects path explicitly.
31363207
setApplicationInfoPaths(pkg, codePath, resPath);
31373208
// Note that we invoke the following method only if we are about to unpack an application
3138-
return scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime);
3209+
PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
3210+
| SCAN_UPDATE_SIGNATURE, currentTime);
3211+
3212+
/*
3213+
* If the system app should be overridden by a previously installed
3214+
* data, hide the system app now and let the /data/app scan pick it up
3215+
* again.
3216+
*/
3217+
if (shouldHideSystemApp) {
3218+
synchronized (mPackages) {
3219+
/*
3220+
* We have to grant systems permissions before we hide, because
3221+
* grantPermissions will assume the package update is trying to
3222+
* expand its permissions.
3223+
*/
3224+
grantPermissionsLPw(pkg, true);
3225+
mSettings.disableSystemPackageLPw(pkg.packageName);
3226+
}
3227+
}
3228+
3229+
return scannedPkg;
31393230
}
31403231

31413232
private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath,
@@ -7177,6 +7268,10 @@ private static boolean isSystemApp(ApplicationInfo info) {
71777268
return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
71787269
}
71797270

7271+
private static boolean isSystemApp(PackageSetting ps) {
7272+
return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
7273+
}
7274+
71807275
private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
71817276
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
71827277
}

0 commit comments

Comments
 (0)