Merge "Fixes incorrect app id cleanup on failure" into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
abf224e88f
@@ -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()) {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user