Merge "Fixes incorrect app id cleanup on failure" into qt-dev

This commit is contained in:
TreeHugger Robot
2019-04-16 20:52:34 +00:00
committed by Android (Google) Code Review
2 changed files with 36 additions and 20 deletions

View File

@@ -9334,6 +9334,7 @@ public class PackageManagerService extends IPackageManager.Stub
| SCAN_UPDATE_SIGNATURE, currentTime, user); | SCAN_UPDATE_SIGNATURE, currentTime, user);
if (scanResult.success) { if (scanResult.success) {
synchronized (mPackages) { synchronized (mPackages) {
boolean appIdCreated = false;
try { try {
final String pkgName = scanResult.pkgSetting.name; final String pkgName = scanResult.pkgSetting.name;
final Map<String, ReconciledPackage> reconcileResult = reconcilePackagesLocked( final Map<String, ReconciledPackage> reconcileResult = reconcilePackagesLocked(
@@ -9346,11 +9347,12 @@ public class PackageManagerService extends IPackageManager.Stub
Collections.singletonMap(pkgName, Collections.singletonMap(pkgName,
getSharedLibLatestVersionSetting(scanResult))), getSharedLibLatestVersionSetting(scanResult))),
mSettings.mKeySetManagerService); mSettings.mKeySetManagerService);
prepareScanResultLocked(scanResult); appIdCreated = optimisticallyRegisterAppId(scanResult);
commitReconciledScanResultLocked( commitReconciledScanResultLocked(reconcileResult.get(pkgName));
reconcileResult.get(pkgName));
} catch (PackageManagerException e) { } catch (PackageManagerException e) {
unprepareScanResultLocked(scanResult); if (appIdCreated) {
cleanUpAppIdCreation(scanResult);
}
throw e; throw e;
} }
} }
@@ -10837,27 +10839,32 @@ public class PackageManagerService extends IPackageManager.Stub
} }
/** Prepares the system to commit a {@link ScanResult} in a way that will not fail. */ /**
private void prepareScanResultLocked(@NonNull ScanResult result) * Prepares the system to commit a {@link ScanResult} in a way that will not fail by registering
* the app ID required for reconcile.
* @return {@code true} if a new app ID was registered and will need to be cleaned up on
* failure.
*/
private boolean optimisticallyRegisterAppId(@NonNull ScanResult result)
throws PackageManagerException { throws PackageManagerException {
if (!result.existingSettingCopied) { if (!result.existingSettingCopied) {
// THROWS: when we can't allocate a user id. add call to check if there's // THROWS: when we can't allocate a user id. add call to check if there's
// enough space to ensure we won't throw; otherwise, don't modify state // enough space to ensure we won't throw; otherwise, don't modify state
mSettings.registerAppIdLPw(result.pkgSetting); return mSettings.registerAppIdLPw(result.pkgSetting);
} }
return false;
} }
/** /**
* Reverts any changes to the system that were made by * Reverts any app ID creation that were made by
* {@link #prepareScanResultLocked(ScanResult)} * {@link #optimisticallyRegisterAppId(ScanResult)}. Note: this is only necessary if the
* referenced method returned true.
*/ */
private void unprepareScanResultLocked(@NonNull ScanResult result) { private void cleanUpAppIdCreation(@NonNull ScanResult result) {
if (!result.existingSettingCopied) { // iff we've acquired an app ID for a new package setting, remove it so that it can be
// iff we've acquired an app ID for a new package setting, remove it so that it can be // acquired by another request.
// acquired by another request. if (result.pkgSetting.appId > 0) {
if (result.pkgSetting.appId > 0) { mSettings.removeAppIdLPw(result.pkgSetting.appId);
mSettings.removeAppIdLPw(result.pkgSetting.appId);
}
} }
} }
@@ -16701,6 +16708,7 @@ public class PackageManagerService extends IPackageManager.Stub
final Map<String, VersionInfo> versionInfos = new ArrayMap<>(requests.size()); final Map<String, VersionInfo> versionInfos = new ArrayMap<>(requests.size());
final Map<String, PackageSetting> lastStaticSharedLibSettings = final Map<String, PackageSetting> lastStaticSharedLibSettings =
new ArrayMap<>(requests.size()); new ArrayMap<>(requests.size());
final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
boolean success = false; boolean success = false;
try { try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI"); Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI");
@@ -16740,7 +16748,7 @@ public class PackageManagerService extends IPackageManager.Stub
+ " in multi-package install request."); + " in multi-package install request.");
return; return;
} }
prepareScanResultLocked(result); createdAppId.put(packageName, optimisticallyRegisterAppId(result));
versionInfos.put(result.pkgSetting.pkg.packageName, versionInfos.put(result.pkgSetting.pkg.packageName,
getSettingsVersionForPackage(result.pkgSetting.pkg)); getSettingsVersionForPackage(result.pkgSetting.pkg));
if (result.staticSharedLibraryInfo != null) { if (result.staticSharedLibraryInfo != null) {
@@ -16797,7 +16805,9 @@ public class PackageManagerService extends IPackageManager.Stub
} finally { } finally {
if (!success) { if (!success) {
for (ScanResult result : preparedScans.values()) { for (ScanResult result : preparedScans.values()) {
unprepareScanResultLocked(result); if (createdAppId.getOrDefault(result.request.pkg.packageName, false)) {
cleanUpAppIdCreation(result);
}
} }
} }
for (PrepareResult result : prepareResults.values()) { for (PrepareResult result : prepareResults.values()) {

View File

@@ -810,15 +810,20 @@ public final class Settings {
/** /**
* Registers a user ID with the system. Potentially allocates a new user ID. * Registers a user ID with the system. Potentially allocates a new user ID.
* @return {@code true} if a new app ID was created in the process. {@code false} can be
* returned in the case that a shared user ID already exists or the explicit app ID is
* already registered.
* @throws PackageManagerException If a user ID could not be allocated. * @throws PackageManagerException If a user ID could not be allocated.
*/ */
void registerAppIdLPw(PackageSetting p) throws PackageManagerException { boolean registerAppIdLPw(PackageSetting p) throws PackageManagerException {
final boolean createdNew;
if (p.appId == 0) { if (p.appId == 0) {
// Assign new user ID // Assign new user ID
p.appId = acquireAndRegisterNewAppIdLPw(p); p.appId = acquireAndRegisterNewAppIdLPw(p);
createdNew = true;
} else { } else {
// Add new setting to list of user IDs // Add new setting to list of user IDs
registerExistingAppIdLPw(p.appId, p, p.name); createdNew = registerExistingAppIdLPw(p.appId, p, p.name);
} }
if (p.appId < 0) { if (p.appId < 0) {
PackageManagerService.reportSettingsProblem(Log.WARN, PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -826,6 +831,7 @@ public final class Settings {
throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
"Package " + p.name + " could not be assigned a valid UID"); "Package " + p.name + " could not be assigned a valid UID");
} }
return createdNew;
} }
/** /**