Skip to content

Commit c29b49f

Browse files
krutonAndroid (Google) Code Review
authored andcommitted
Merge "Handle addition of system apps during OTA" into jb-dev
2 parents 8a7eff1 + 208d341 commit c29b49f

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)