summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Songchun Fan <schfan@google.com> 2022-10-06 19:45:06 -0700
committer Songchun Fan <schfan@google.com> 2022-10-24 21:19:35 -0700
commit378c4815671736de334cde8fd42e742e8e83b681 (patch)
treef4c0d3786d4b90abce364d473dc594d0eee037f6
parent4f1033f742553979d333415b6e75e51d3b039777 (diff)
[pm] merge CommitRequest, PrepareResult, ReconcileRequest into InstallRequest
BUG: 238678399 Test: atest com.android.server.pm.ScanTests Change-Id: I9f7d17d458318da89a6e47cdf9a0989825b1dbe5
-rw-r--r--services/core/java/com/android/server/pm/CommitRequest.java35
-rw-r--r--services/core/java/com/android/server/pm/InitAppsHelper.java3
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java349
-rw-r--r--services/core/java/com/android/server/pm/InstallRequest.java377
-rw-r--r--services/core/java/com/android/server/pm/InstallingSession.java29
-rw-r--r--services/core/java/com/android/server/pm/PrepareResult.java54
-rw-r--r--services/core/java/com/android/server/pm/ReconcilePackageUtils.java95
-rw-r--r--services/core/java/com/android/server/pm/ReconcileRequest.java59
-rw-r--r--services/core/java/com/android/server/pm/ReconciledPackage.java32
-rw-r--r--services/core/java/com/android/server/pm/ScanPackageUtils.java2
-rw-r--r--services/core/java/com/android/server/pm/ScanResult.java8
-rw-r--r--services/core/java/com/android/server/pm/SharedLibrariesImpl.java44
-rw-r--r--services/core/java/com/android/server/pm/StorageEventHelper.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt16
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ScanTests.java1
15 files changed, 590 insertions, 516 deletions
diff --git a/services/core/java/com/android/server/pm/CommitRequest.java b/services/core/java/com/android/server/pm/CommitRequest.java
deleted file mode 100644
index d1a6002590f2..000000000000
--- a/services/core/java/com/android/server/pm/CommitRequest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm;
-
-import android.annotation.NonNull;
-
-import java.util.Map;
-
-/**
- * Package state to commit to memory and disk after reconciliation has completed.
- */
-final class CommitRequest {
- final Map<String, ReconciledPackage> mReconciledPackages;
- @NonNull final int[] mAllUsers;
-
- CommitRequest(Map<String, ReconciledPackage> reconciledPackages,
- @NonNull int[] allUsers) {
- mReconciledPackages = reconciledPackages;
- mAllUsers = allUsers;
- }
-}
diff --git a/services/core/java/com/android/server/pm/InitAppsHelper.java b/services/core/java/com/android/server/pm/InitAppsHelper.java
index f6472a739979..6f5909615db2 100644
--- a/services/core/java/com/android/server/pm/InitAppsHelper.java
+++ b/services/core/java/com/android/server/pm/InitAppsHelper.java
@@ -352,8 +352,7 @@ final class InitAppsHelper {
}
@GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
- private void scanDirTracedLI(File scanDir,
- int parseFlags, int scanFlags,
+ private void scanDirTracedLI(File scanDir, int parseFlags, int scanFlags,
PackageParser2 packageParser, ExecutorService executorService) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
try {
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 30ecc1cb4e8f..9d007c92bcc5 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -245,50 +245,42 @@ final class InstallPackageHelper {
@GuardedBy("mPm.mLock")
public AndroidPackage commitReconciledScanResultLocked(
@NonNull ReconciledPackage reconciledPkg, int[] allUsers) {
- final ScanResult result = reconciledPkg.mScanResult;
- final ScanRequest request = result.mRequest;
+ final InstallRequest request = reconciledPkg.mInstallRequest;
// TODO(b/135203078): Move this even further away
- ParsedPackage parsedPackage = request.mParsedPackage;
- if ("android".equals(parsedPackage.getPackageName())) {
+ ParsedPackage parsedPackage = request.getParsedPackage();
+ if (parsedPackage != null && "android".equals(parsedPackage.getPackageName())) {
// TODO(b/135203078): Move this to initial parse
parsedPackage.setVersionCode(mPm.getSdkVersion())
.setVersionCodeMajor(0);
}
- final AndroidPackage oldPkg = request.mOldPkg;
- final @ParsingPackageUtils.ParseFlags int parseFlags = request.mParseFlags;
- final @PackageManagerService.ScanFlags int scanFlags = request.mScanFlags;
- final PackageSetting oldPkgSetting = request.mOldPkgSetting;
- final PackageSetting originalPkgSetting = request.mOriginalPkgSetting;
- final UserHandle user = request.mUser;
- final String realPkgName = request.mRealPkgName;
- final List<String> changedAbiCodePath = result.mChangedAbiCodePath;
+ final @PackageManagerService.ScanFlags int scanFlags = request.getScanFlags();
+ final PackageSetting oldPkgSetting = request.getScanRequestOldPackageSetting();
+ final PackageSetting originalPkgSetting = request.getScanRequestOriginalPackageSetting();
+ final String realPkgName = request.getRealPackageName();
+ final List<String> changedAbiCodePath = request.getChangedAbiCodePath();
final PackageSetting pkgSetting;
- if (request.mPkgSetting != null) {
+ if (request.getScanRequestPackageSetting() != null) {
SharedUserSetting requestSharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(
- request.mPkgSetting);
+ request.getScanRequestPackageSetting());
SharedUserSetting resultSharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(
- result.mPkgSetting);
+ request.getScanRequestPackageSetting());
if (requestSharedUserSetting != null
&& requestSharedUserSetting != resultSharedUserSetting) {
// shared user changed, remove from old shared user
- requestSharedUserSetting.removePackage(request.mPkgSetting);
+ requestSharedUserSetting.removePackage(request.getScanRequestPackageSetting());
// Prune unused SharedUserSetting
if (mPm.mSettings.checkAndPruneSharedUserLPw(requestSharedUserSetting, false)) {
// Set the app ID in removed info for UID_REMOVED broadcasts
- if (reconciledPkg.mInstallRequest != null
- && reconciledPkg.mInstallRequest.getRemovedInfo() != null) {
- reconciledPkg.mInstallRequest.getRemovedInfo().mRemovedAppId =
- requestSharedUserSetting.mAppId;
- }
+ request.setRemovedAppId(requestSharedUserSetting.mAppId);
}
}
}
- if (result.mExistingSettingCopied) {
- pkgSetting = request.mPkgSetting;
- pkgSetting.updateFrom(result.mPkgSetting);
+ if (request.isExistingSettingCopied()) {
+ pkgSetting = request.getScanRequestPackageSetting();
+ pkgSetting.updateFrom(request.getScannedPackageSetting());
} else {
- pkgSetting = result.mPkgSetting;
+ pkgSetting = request.getScannedPackageSetting();
if (originalPkgSetting != null) {
mPm.mSettings.addRenamedPackageLPw(
AndroidPackageUtils.getRealPackageOrNull(parsedPackage),
@@ -308,26 +300,23 @@ final class InstallPackageHelper {
mPm.mSettings.convertSharedUserSettingsLPw(sharedUserSetting);
}
}
- if (reconciledPkg.mInstallRequest != null
- && reconciledPkg.mInstallRequest.isForceQueryableOverride()) {
+ if (request.isForceQueryableOverride()) {
pkgSetting.setForceQueryableOverride(true);
}
// If this is part of a standard install, set the initiating package name, else rely on
// previous device state.
- if (reconciledPkg.mInstallRequest != null) {
- InstallSource installSource = reconciledPkg.mInstallRequest.getInstallSource();
- if (installSource != null) {
- if (installSource.initiatingPackageName != null) {
- final PackageSetting ips = mPm.mSettings.getPackageLPr(
- installSource.initiatingPackageName);
- if (ips != null) {
- installSource = installSource.setInitiatingPackageSignatures(
- ips.getSignatures());
- }
+ InstallSource installSource = request.getInstallSource();
+ if (installSource != null) {
+ if (installSource.initiatingPackageName != null) {
+ final PackageSetting ips = mPm.mSettings.getPackageLPr(
+ installSource.initiatingPackageName);
+ if (ips != null) {
+ installSource = installSource.setInitiatingPackageSignatures(
+ ips.getSignatures());
}
- pkgSetting.setInstallSource(installSource);
}
+ pkgSetting.setInstallSource(installSource);
}
if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
@@ -382,10 +371,9 @@ final class InstallPackageHelper {
}
}
- final int userId = user == null ? 0 : user.getIdentifier();
+ final int userId = request.getUserId();
// Modify state for the given package setting
- commitPackageSettings(pkg, oldPkg, pkgSetting, oldPkgSetting, scanFlags,
- (parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg);
+ commitPackageSettings(pkg, pkgSetting, oldPkgSetting, reconciledPkg);
if (pkgSetting.getInstantApp(userId)) {
mPm.mInstantAppRegistry.addInstantApp(userId, pkgSetting.getAppId());
}
@@ -401,11 +389,14 @@ final class InstallPackageHelper {
* Adds a scanned package to the system. When this method is finished, the package will
* be available for query, resolution, etc...
*/
- private void commitPackageSettings(@NonNull AndroidPackage pkg, @Nullable AndroidPackage oldPkg,
+ private void commitPackageSettings(@NonNull AndroidPackage pkg,
@NonNull PackageSetting pkgSetting, @Nullable PackageSetting oldPkgSetting,
- final @PackageManagerService.ScanFlags int scanFlags, boolean chatty,
ReconciledPackage reconciledPkg) {
final String pkgName = pkg.getPackageName();
+ final InstallRequest request = reconciledPkg.mInstallRequest;
+ final AndroidPackage oldPkg = request.getScanRequestOldPackage();
+ final int scanFlags = request.getScanFlags();
+ final boolean chatty = (request.getParseFlags() & ParsingPackageUtils.PARSE_CHATTY) != 0;
if (mPm.mCustomResolverComponentName != null
&& mPm.mCustomResolverComponentName.getPackageName().equals(pkg.getPackageName())) {
mPm.setUpCustomResolverActivity(pkg, pkgSetting);
@@ -421,9 +412,7 @@ final class InstallPackageHelper {
reconciledPkg.mAllowedSharedLibraryInfos,
reconciledPkg.getCombinedAvailablePackages(), scanFlags);
- if (reconciledPkg.mInstallRequest != null) {
- reconciledPkg.mInstallRequest.setLibraryConsumers(clientLibPkgs);
- }
+ request.setLibraryConsumers(clientLibPkgs);
if ((scanFlags & SCAN_BOOTING) != 0) {
// No apps can run during boot scan, so they don't need to be frozen
@@ -438,8 +427,7 @@ final class InstallPackageHelper {
mPm.snapshotComputer().checkPackageFrozen(pkgName);
}
- final boolean isReplace =
- reconciledPkg.mPrepareResult != null && reconciledPkg.mPrepareResult.mReplace;
+ final boolean isReplace = request.isReplace();
// Also need to kill any apps that are dependent on the library, except the case of
// installation of new version static shared library.
if (clientLibPkgs != null) {
@@ -705,6 +693,9 @@ final class InstallPackageHelper {
* Returns whether the restore successfully completed.
*/
private boolean performBackupManagerRestore(int userId, int token, InstallRequest request) {
+ if (request.getPkg() == null) {
+ return false;
+ }
IBackupManager iBackupManager = mInjector.getIBackupManager();
if (iBackupManager != null) {
// For backwards compatibility as USER_ALL previously routed directly to USER_SYSTEM
@@ -743,6 +734,9 @@ final class InstallPackageHelper {
* Returns whether the restore successfully completed.
*/
private boolean performRollbackManagerRestore(int userId, int token, InstallRequest request) {
+ if (request.getPkg() == null) {
+ return false;
+ }
final String packageName = request.getPkg().getPackageName();
final int[] allUsers = mPm.mUserManager.getUserIds();
final int[] installedUsers;
@@ -810,22 +804,16 @@ final class InstallPackageHelper {
*/
@GuardedBy("mPm.mInstallLock")
private void installPackagesLI(List<InstallRequest> requests) {
- final Map<String, ScanResult> preparedScans = new ArrayMap<>(requests.size());
- final Map<String, PrepareResult> prepareResults = new ArrayMap<>(requests.size());
- final Map<String, InstallRequest> installRequests = new ArrayMap<>(requests.size());
+ final Set<String> scannedPackages = new ArraySet<>(requests.size());
final Map<String, Settings.VersionInfo> versionInfos = new ArrayMap<>(requests.size());
final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
boolean success = false;
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI");
for (InstallRequest request : requests) {
- // TODO(b/109941548): remove this once we've pulled everything from it and into
- // scan, reconcile or commit.
- final PrepareResult prepareResult;
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
- prepareResult =
- preparePackageLI(request);
+ preparePackageLI(request);
} catch (PrepareFailure prepareFailure) {
request.setError(prepareFailure.error,
prepareFailure.getMessage());
@@ -835,28 +823,31 @@ final class InstallPackageHelper {
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
- request.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
- request.setInstallerPackageName(request.getSourceInstallerPackageName());
- final String packageName = prepareResult.mPackageToScan.getPackageName();
- prepareResults.put(packageName, prepareResult);
- installRequests.put(packageName, request);
+ final ParsedPackage packageToScan = request.getParsedPackage();
+ if (packageToScan == null) {
+ request.setError(INSTALL_FAILED_SESSION_INVALID,
+ "Failed to obtain package to scan");
+ return;
+ }
+ request.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
+ final String packageName = packageToScan.getPackageName();
try {
- final ScanResult result = scanPackageTracedLI(
- prepareResult.mPackageToScan, prepareResult.mParseFlags,
- prepareResult.mScanFlags, System.currentTimeMillis(),
- request.getUser(), request.getAbiOverride());
- if (null != preparedScans.put(result.mPkgSetting.getPkg().getPackageName(),
- result)) {
+ final ScanResult scanResult = scanPackageTracedLI(request.getParsedPackage(),
+ request.getParseFlags(), request.getScanFlags(),
+ System.currentTimeMillis(), request.getUser(),
+ request.getAbiOverride());
+ request.setScanResult(scanResult);
+ if (!scannedPackages.add(packageName)) {
request.setError(
PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE,
"Duplicate package "
- + result.mPkgSetting.getPkg().getPackageName()
+ + packageName
+ " in multi-package install request.");
return;
}
if (!checkNoAppStorageIsConsistent(
- result.mRequest.mOldPkg, result.mPkgSetting.getPkg())) {
+ request.getScanRequestOldPackage(), packageToScan)) {
// TODO: INSTALL_FAILED_UPDATE_INCOMPATIBLE is about incomptabible
// signatures. Is there a better error code?
request.setError(
@@ -865,31 +856,28 @@ final class InstallPackageHelper {
+ PackageManager.PROPERTY_NO_APP_DATA_STORAGE);
return;
}
- final boolean isApex = (result.mRequest.mScanFlags & SCAN_AS_APEX) != 0;
+ final boolean isApex = (request.getScanFlags() & SCAN_AS_APEX) != 0;
if (!isApex) {
- createdAppId.put(packageName, optimisticallyRegisterAppId(result));
+ createdAppId.put(packageName, optimisticallyRegisterAppId(request));
} else {
- result.mPkgSetting.setAppId(Process.INVALID_UID);
+ request.getScannedPackageSetting().setAppId(Process.INVALID_UID);
}
- versionInfos.put(result.mPkgSetting.getPkg().getPackageName(),
- mPm.getSettingsVersionForPackage(result.mPkgSetting.getPkg()));
+ versionInfos.put(packageName,
+ mPm.getSettingsVersionForPackage(packageToScan));
} catch (PackageManagerException e) {
request.setError("Scanning Failed.", e);
return;
}
}
- CommitRequest commitRequest;
+ Map<String, ReconciledPackage> reconciledPackages;
synchronized (mPm.mLock) {
- ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans,
- installRequests, prepareResults,
- Collections.unmodifiableMap(mPm.mPackages), versionInfos);
- Map<String, ReconciledPackage> reconciledPackages;
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
reconciledPackages = ReconcilePackageUtils.reconcilePackages(
- reconcileRequest, mSharedLibraries,
- mPm.mSettings.getKeySetManagerService(), mPm.mSettings);
+ requests, Collections.unmodifiableMap(mPm.mPackages),
+ versionInfos, mSharedLibraries, mPm.mSettings.getKeySetManagerService(),
+ mPm.mSettings);
} catch (ReconcileFailure e) {
for (InstallRequest request : requests) {
request.setError("Reconciliation failed...", e);
@@ -900,15 +888,13 @@ final class InstallPackageHelper {
}
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "commitPackages");
- commitRequest = new CommitRequest(reconciledPackages,
- mPm.mUserManager.getUserIds());
- commitPackagesLocked(commitRequest);
+ commitPackagesLocked(reconciledPackages, mPm.mUserManager.getUserIds());
success = true;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
- executePostCommitStepsLIF(commitRequest);
+ executePostCommitStepsLIF(reconciledPackages);
} finally {
if (success) {
for (InstallRequest request : requests) {
@@ -932,10 +918,10 @@ final class InstallPackageHelper {
request.getDataLoaderType(), request.getUser(), mContext);
}
} else {
- for (ScanResult result : preparedScans.values()) {
- if (createdAppId.getOrDefault(result.mRequest.mParsedPackage.getPackageName(),
- false)) {
- cleanUpAppIdCreation(result);
+ for (InstallRequest installRequest : requests) {
+ if (installRequest.getParsedPackage() != null && createdAppId.getOrDefault(
+ installRequest.getParsedPackage().getPackageName(), false)) {
+ cleanUpAppIdCreation(installRequest);
}
}
// TODO(b/194319951): create a more descriptive reason than unknown
@@ -968,8 +954,7 @@ final class InstallPackageHelper {
}
@GuardedBy("mPm.mInstallLock")
- private PrepareResult preparePackageLI(InstallRequest request)
- throws PrepareFailure {
+ private void preparePackageLI(InstallRequest request) throws PrepareFailure {
final int installFlags = request.getInstallFlags();
final boolean onExternal = request.getVolumeUuid() != null;
final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
@@ -1550,8 +1535,7 @@ final class InstallPackageHelper {
// don't allow an upgrade from full to ephemeral
if (isInstantApp) {
- if (request.getUser() == null
- || request.getUserId() == UserHandle.USER_ALL) {
+ if (request.getUserId() == UserHandle.USER_ALL) {
for (int currentUser : allUsers) {
if (!ps.getInstantApp(currentUser)) {
// can't downgrade from full to instant
@@ -1624,7 +1608,6 @@ final class InstallPackageHelper {
targetParseFlags = systemParseFlags;
targetScanFlags = systemScanFlags;
} else { // non system replace
- replace = true;
if (DEBUG_INSTALL) {
Slog.d(TAG,
"replaceNonSystemPackageLI: new=" + parsedPackage + ", old="
@@ -1634,7 +1617,6 @@ final class InstallPackageHelper {
} else { // new package install
ps = null;
disabledPs = null;
- replace = false;
oldPackage = null;
// Remember this for later, in case we need to rollback this install
String pkgName1 = parsedPackage.getPackageName();
@@ -1665,7 +1647,7 @@ final class InstallPackageHelper {
// we're passing the freezer back to be closed in a later phase of install
shouldCloseFreezerBeforeReturn = false;
- return new PrepareResult(replace, targetScanFlags, targetParseFlags,
+ request.setPrepareResult(replace, targetScanFlags, targetParseFlags,
oldPackage, parsedPackage, replace /* clearCodeCache */, sysPkg,
ps, disabledPs);
} finally {
@@ -1894,19 +1876,18 @@ final class InstallPackageHelper {
}
@GuardedBy("mPm.mLock")
- private void commitPackagesLocked(final CommitRequest request) {
+ private void commitPackagesLocked(Map<String, ReconciledPackage> reconciledPackages,
+ @NonNull int[] allUsers) {
// TODO: remove any expected failures from this method; this should only be able to fail due
// to unavoidable errors (I/O, etc.)
- for (ReconciledPackage reconciledPkg : request.mReconciledPackages.values()) {
- final ScanResult scanResult = reconciledPkg.mScanResult;
- final ScanRequest scanRequest = scanResult.mRequest;
- final ParsedPackage parsedPackage = scanRequest.mParsedPackage;
- final String packageName = parsedPackage.getPackageName();
+ for (ReconciledPackage reconciledPkg : reconciledPackages.values()) {
final InstallRequest installRequest = reconciledPkg.mInstallRequest;
+ final ParsedPackage parsedPackage = installRequest.getParsedPackage();
+ final String packageName = parsedPackage.getPackageName();
final RemovePackageHelper removePackageHelper = new RemovePackageHelper(mPm);
final DeletePackageHelper deletePackageHelper = new DeletePackageHelper(mPm);
- if (reconciledPkg.mPrepareResult.mReplace) {
+ if (installRequest.isReplace()) {
AndroidPackage oldPackage = mPm.mPackages.get(packageName);
// Set the update and install times
@@ -1914,15 +1895,16 @@ final class InstallPackageHelper {
.getPackageStateInternal(oldPackage.getPackageName());
// TODO(b/225756739): For rebootless APEX, consider using lastUpdateMillis provided
// by apexd to be more accurate.
- reconciledPkg.mPkgSetting
- .setFirstInstallTimeFromReplaced(deletedPkgSetting, request.mAllUsers)
- .setLastUpdateTime(System.currentTimeMillis());
+ installRequest.setScannedPackageSettingFirstInstallTimeFromReplaced(
+ deletedPkgSetting, allUsers);
+ installRequest.setScannedPackageSettingLastUpdateTime(
+ System.currentTimeMillis());
installRequest.getRemovedInfo().mBroadcastAllowList =
mPm.mAppsFilter.getVisibilityAllowList(mPm.snapshotComputer(),
- reconciledPkg.mPkgSetting, request.mAllUsers,
- mPm.mSettings.getPackagesLocked());
- if (reconciledPkg.mPrepareResult.mSystem) {
+ installRequest.getScannedPackageSetting(),
+ allUsers, mPm.mSettings.getPackagesLocked());
+ if (installRequest.isSystem()) {
// Remove existing system package
removePackageHelper.removePackage(oldPackage, true);
if (!disableSystemPackageLPw(oldPackage)) {
@@ -1942,7 +1924,7 @@ final class InstallPackageHelper {
// Settings will be written during the call to updateSettingsLI().
deletePackageHelper.executeDeletePackage(
reconciledPkg.mDeletePackageAction, packageName,
- true, request.mAllUsers, false);
+ true, allUsers, false);
} catch (SystemDeleteException e) {
if (mPm.mIsEngBuild) {
throw new RuntimeException("Unexpected failure", e);
@@ -1952,7 +1934,7 @@ final class InstallPackageHelper {
// Successfully deleted the old package; proceed with replace.
// Update the in-memory copy of the previous code paths.
PackageSetting ps1 = mPm.mSettings.getPackageLPr(
- reconciledPkg.mPrepareResult.mExistingPackage.getPackageName());
+ installRequest.getExistingPackageName());
if ((installRequest.getInstallFlags() & PackageManager.DONT_KILL_APP)
== 0) {
Set<String> oldCodePaths = ps1.getOldCodePaths();
@@ -1977,9 +1959,8 @@ final class InstallPackageHelper {
}
}
- AndroidPackage pkg = commitReconciledScanResultLocked(
- reconciledPkg, request.mAllUsers);
- updateSettingsLI(pkg, reconciledPkg, request.mAllUsers, installRequest);
+ AndroidPackage pkg = commitReconciledScanResultLocked(reconciledPkg, allUsers);
+ updateSettingsLI(pkg, allUsers, installRequest);
final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName);
if (ps != null) {
@@ -2000,12 +1981,12 @@ final class InstallPackageHelper {
return mPm.mSettings.disableSystemPackageLPw(oldPkg.getPackageName(), true);
}
- private void updateSettingsLI(AndroidPackage newPackage, ReconciledPackage reconciledPkg,
+ private void updateSettingsLI(AndroidPackage newPackage,
int[] allUsers, InstallRequest installRequest) {
- updateSettingsInternalLI(newPackage, reconciledPkg, allUsers, installRequest);
+ updateSettingsInternalLI(newPackage, allUsers, installRequest);
}
- private void updateSettingsInternalLI(AndroidPackage pkg, ReconciledPackage reconciledPkg,
+ private void updateSettingsInternalLI(AndroidPackage pkg,
int[] allUsers, InstallRequest installRequest) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
@@ -2175,8 +2156,7 @@ final class InstallPackageHelper {
}
final int autoRevokePermissionsMode = installRequest.getAutoRevokePermissionsMode();
permissionParamsBuilder.setAutoRevokePermissionsMode(autoRevokePermissionsMode);
- final ScanResult scanResult = reconciledPkg.mScanResult;
- mPm.mPermissionManager.onPackageInstalled(pkg, scanResult.mPreviousAppId,
+ mPm.mPermissionManager.onPackageInstalled(pkg, installRequest.getPreviousAppId(),
permissionParamsBuilder.build(), userId);
// Apply restricted settings on potentially dangerous packages.
if (installRequest.getPackageSource() == PackageInstaller.PACKAGE_SOURCE_LOCAL_FILE
@@ -2216,14 +2196,13 @@ final class InstallPackageHelper {
* locks on {@link com.android.server.pm.PackageManagerService.mLock}.
*/
@GuardedBy("mPm.mInstallLock")
- private void executePostCommitStepsLIF(CommitRequest commitRequest) {
+ private void executePostCommitStepsLIF(Map<String, ReconciledPackage> reconciledPackages) {
final ArraySet<IncrementalStorage> incrementalStorages = new ArraySet<>();
- for (ReconciledPackage reconciledPkg : commitRequest.mReconciledPackages.values()) {
- final boolean instantApp = ((reconciledPkg.mScanResult.mRequest.mScanFlags
- & SCAN_AS_INSTANT_APP) != 0);
- final boolean isApex = ((reconciledPkg.mScanResult.mRequest.mScanFlags
- & SCAN_AS_APEX) != 0);
- final AndroidPackage pkg = reconciledPkg.mPkgSetting.getPkg();
+ for (ReconciledPackage reconciledPkg : reconciledPackages.values()) {
+ final InstallRequest installRequest = reconciledPkg.mInstallRequest;
+ final boolean instantApp = ((installRequest.getScanFlags() & SCAN_AS_INSTANT_APP) != 0);
+ final boolean isApex = ((installRequest.getScanFlags() & SCAN_AS_APEX) != 0);
+ final AndroidPackage pkg = installRequest.getScannedPackageSetting().getPkg();
final String packageName = pkg.getPackageName();
final String codePath = pkg.getPath();
final boolean onIncremental = mIncrementalManager != null
@@ -2238,12 +2217,12 @@ final class InstallPackageHelper {
}
// Hardcode previousAppId to 0 to disable any data migration (http://b/221088088)
mAppDataHelper.prepareAppDataPostCommitLIF(pkg, 0);
- if (reconciledPkg.mPrepareResult.mClearCodeCache) {
+ if (installRequest.isClearCodeCache()) {
mAppDataHelper.clearAppDataLIF(pkg, UserHandle.USER_ALL,
FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
| Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
- if (reconciledPkg.mPrepareResult.mReplace) {
+ if (installRequest.isReplace()) {
mDexManager.notifyPackageUpdated(pkg.getPackageName(),
pkg.getBaseApkPath(), pkg.getSplitCodePaths());
}
@@ -2252,14 +2231,13 @@ final class InstallPackageHelper {
// This needs to be done before invoking dexopt so that any install-time profile
// can be used for optimizations.
mArtManagerService.prepareAppProfiles(
- pkg,
- mPm.resolveUserIds(reconciledPkg.mInstallRequest.getUserId()),
+ pkg, mPm.resolveUserIds(installRequest.getUserId()),
/* updateReferenceProfileContent= */ true);
// Compute the compilation reason from the installation scenario.
final int compilationReason =
mDexManager.getCompilationReasonForInstallScenario(
- reconciledPkg.mInstallRequest.getInstallScenario());
+ installRequest.getInstallScenario());
// Construct the DexoptOptions early to see if we should skip running dexopt.
//
@@ -2268,10 +2246,8 @@ final class InstallPackageHelper {
//
// Also, don't fail application installs if the dexopt step fails.
final boolean isBackupOrRestore =
- reconciledPkg.mInstallRequest.getInstallReason()
- == INSTALL_REASON_DEVICE_RESTORE
- || reconciledPkg.mInstallRequest.getInstallReason()
- == INSTALL_REASON_DEVICE_SETUP;
+ installRequest.getInstallReason() == INSTALL_REASON_DEVICE_RESTORE
+ || installRequest.getInstallReason() == INSTALL_REASON_DEVICE_SETUP;
final int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE
| DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE
@@ -2323,22 +2299,14 @@ final class InstallPackageHelper {
}
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
- ScanResult result = reconciledPkg.mScanResult;
// This mirrors logic from commitReconciledScanResultLocked, where the library files
// needed for dexopt are assigned.
- // TODO: Fix this to have 1 mutable PackageSetting for scan/install. If the previous
- // setting needs to be passed to have a comparison, hide it behind an immutable
- // interface. There's no good reason to have 3 different ways to access the real
- // PackageSetting object, only one of which is actually correct.
- PackageSetting realPkgSetting = result.mExistingSettingCopied
- ? result.mRequest.mPkgSetting : result.mPkgSetting;
- if (realPkgSetting == null) {
- realPkgSetting = reconciledPkg.mPkgSetting;
- }
+ PackageSetting realPkgSetting = installRequest.getRealPackageSetting();
// Unfortunately, the updated system app flag is only tracked on this PackageSetting
- boolean isUpdatedSystemApp = reconciledPkg.mPkgSetting.getPkgState()
+ boolean isUpdatedSystemApp =
+ installRequest.getScannedPackageSetting().getPkgState()
.isUpdatedSystemApp();
realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp);
@@ -3059,7 +3027,7 @@ final class InstallPackageHelper {
final RemovePackageHelper removePackageHelper = new RemovePackageHelper(mPm);
removePackageHelper.removePackage(stubPkg, true /*chatty*/);
try {
- return scanSystemPackageTracedLI(scanFile, parseFlags, scanFlags, null);
+ return scanSystemPackageTracedLI(scanFile, parseFlags, scanFlags);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(),
e);
@@ -3191,7 +3159,7 @@ final class InstallPackageHelper {
| ParsingPackageUtils.PARSE_IS_SYSTEM_DIR;
@PackageManagerService.ScanFlags int scanFlags = mPm.getSystemPackageScanFlags(codePath);
final AndroidPackage pkg = scanSystemPackageTracedLI(
- codePath, parseFlags, scanFlags, null);
+ codePath, parseFlags, scanFlags);
synchronized (mPm.mLock) {
PackageSetting pkgSetting = mPm.mSettings.getPackageLPr(pkg.getPackageName());
@@ -3371,7 +3339,7 @@ final class InstallPackageHelper {
try {
final File codePath = new File(pkg.getPath());
synchronized (mPm.mInstallLock) {
- scanSystemPackageTracedLI(codePath, 0, scanFlags, null);
+ scanSystemPackageTracedLI(codePath, 0, scanFlags);
}
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse updated, ex-system package: "
@@ -3521,7 +3489,7 @@ final class InstallPackageHelper {
}
try {
addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,
- null);
+ new UserHandle(UserHandle.USER_SYSTEM));
} catch (PackageManagerException e) {
errorCode = e.error;
errorMsg = "Failed to scan " + parseResult.scanFile + ": " + e.getMessage();
@@ -3584,7 +3552,7 @@ final class InstallPackageHelper {
try {
synchronized (mPm.mInstallLock) {
final AndroidPackage newPkg = scanSystemPackageTracedLI(
- scanFile, reparseFlags, rescanFlags, null);
+ scanFile, reparseFlags, rescanFlags);
// We rescanned a stub, add it to the list of stubbed system packages
if (newPkg.isStub()) {
stubSystemApps.add(packageName);
@@ -3603,10 +3571,10 @@ final class InstallPackageHelper {
*/
@GuardedBy("mPm.mInstallLock")
public AndroidPackage scanSystemPackageTracedLI(File scanFile, final int parseFlags,
- int scanFlags, UserHandle user) throws PackageManagerException {
+ int scanFlags) throws PackageManagerException {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
try {
- return scanSystemPackageLI(scanFile, parseFlags, scanFlags, user);
+ return scanSystemPackageLI(scanFile, parseFlags, scanFlags);
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
@@ -3617,8 +3585,8 @@ final class InstallPackageHelper {
* Returns {@code null} in case of errors and the error code is stored in mLastScanError
*/
@GuardedBy("mPm.mInstallLock")
- private AndroidPackage scanSystemPackageLI(File scanFile, int parseFlags, int scanFlags,
- UserHandle user) throws PackageManagerException {
+ private AndroidPackage scanSystemPackageLI(File scanFile, int parseFlags, int scanFlags)
+ throws PackageManagerException {
if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
@@ -3634,7 +3602,8 @@ final class InstallPackageHelper {
PackageManagerService.renameStaticSharedLibraryPackage(parsedPackage);
}
- return addForInitLI(parsedPackage, parseFlags, scanFlags, user);
+ return addForInitLI(parsedPackage, parseFlags, scanFlags,
+ new UserHandle(UserHandle.USER_SYSTEM));
}
/**
@@ -3660,33 +3629,32 @@ final class InstallPackageHelper {
parsedPackage, parseFlags, scanFlags, user);
final ScanResult scanResult = scanResultPair.first;
boolean shouldHideSystemApp = scanResultPair.second;
- if (scanResult.mSuccess) {
- synchronized (mPm.mLock) {
- boolean appIdCreated = false;
- try {
- final String pkgName = scanResult.mPkgSetting.getPackageName();
- final ReconcileRequest reconcileRequest = new ReconcileRequest(
- Collections.singletonMap(pkgName, scanResult),
- mPm.mPackages,
- Collections.singletonMap(pkgName,
- mPm.getSettingsVersionForPackage(parsedPackage)));
- final Map<String, ReconciledPackage> reconcileResult =
- ReconcilePackageUtils.reconcilePackages(reconcileRequest,
- mSharedLibraries, mPm.mSettings.getKeySetManagerService(),
- mPm.mSettings);
- if ((scanFlags & SCAN_AS_APEX) == 0) {
- appIdCreated = optimisticallyRegisterAppId(scanResult);
- } else {
- scanResult.mPkgSetting.setAppId(Process.INVALID_UID);
- }
- commitReconciledScanResultLocked(reconcileResult.get(pkgName),
- mPm.mUserManager.getUserIds());
- } catch (PackageManagerException e) {
- if (appIdCreated) {
- cleanUpAppIdCreation(scanResult);
- }
- throw e;
+ final InstallRequest installRequest = new InstallRequest(
+ parsedPackage, parseFlags, scanFlags, user, scanResult);
+
+ synchronized (mPm.mLock) {
+ boolean appIdCreated = false;
+ try {
+ final String pkgName = scanResult.mPkgSetting.getPackageName();
+ final Map<String, ReconciledPackage> reconcileResult =
+ ReconcilePackageUtils.reconcilePackages(
+ Collections.singletonList(installRequest),
+ mPm.mPackages, Collections.singletonMap(pkgName,
+ mPm.getSettingsVersionForPackage(parsedPackage)),
+ mSharedLibraries, mPm.mSettings.getKeySetManagerService(),
+ mPm.mSettings);
+ if ((scanFlags & SCAN_AS_APEX) == 0) {
+ appIdCreated = optimisticallyRegisterAppId(installRequest);
+ } else {
+ installRequest.setScannedPackageSettingAppId(Process.INVALID_UID);
}
+ commitReconciledScanResultLocked(reconcileResult.get(pkgName),
+ mPm.mUserManager.getUserIds());
+ } catch (PackageManagerException e) {
+ if (appIdCreated) {
+ cleanUpAppIdCreation(installRequest);
+ }
+ throw e;
}
}
@@ -3711,13 +3679,14 @@ final class InstallPackageHelper {
* @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)
+ private boolean optimisticallyRegisterAppId(@NonNull InstallRequest installRequest)
throws PackageManagerException {
- if (!result.mExistingSettingCopied || result.needsNewAppId()) {
+ if (!installRequest.isExistingSettingCopied() || installRequest.needsNewAppId()) {
synchronized (mPm.mLock) {
// 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
- return mPm.mSettings.registerAppIdLPw(result.mPkgSetting, result.needsNewAppId());
+ return mPm.mSettings.registerAppIdLPw(installRequest.getScannedPackageSetting(),
+ installRequest.needsNewAppId());
}
}
return false;
@@ -3725,15 +3694,16 @@ final class InstallPackageHelper {
/**
* Reverts any app ID creation that were made by
- * {@link #optimisticallyRegisterAppId(ScanResult)}. Note: this is only necessary if the
+ * {@link #optimisticallyRegisterAppId(InstallRequest)}. Note: this is only necessary if the
* referenced method returned true.
*/
- private void cleanUpAppIdCreation(@NonNull ScanResult result) {
+ private void cleanUpAppIdCreation(@NonNull InstallRequest installRequest) {
// iff we've acquired an app ID for a new package setting, remove it so that it can be
// acquired by another request.
- if (result.mPkgSetting.getAppId() > 0) {
+ if (installRequest.getScannedPackageSetting() != null
+ && installRequest.getScannedPackageSetting().getAppId() > 0) {
synchronized (mPm.mLock) {
- mPm.mSettings.removeAppIdLPw(result.mPkgSetting.getAppId());
+ mPm.mSettings.removeAppIdLPw(installRequest.getScannedPackageSetting().getAppId());
}
}
}
@@ -3857,7 +3827,6 @@ final class InstallPackageHelper {
}
}
- @GuardedBy("mPm.mInstallLock")
private Pair<ScanResult, Boolean> scanSystemPackageLI(ParsedPackage parsedPackage,
@ParsingPackageUtils.ParseFlags int parseFlags,
@PackageManagerService.ScanFlags int scanFlags,
diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java
index 36bbf41bffe6..573082a58255 100644
--- a/services/core/java/com/android/server/pm/InstallRequest.java
+++ b/services/core/java/com/android/server/pm/InstallRequest.java
@@ -18,6 +18,7 @@ package com.android.server.pm;
import static android.content.pm.PackageManager.INSTALL_REASON_UNKNOWN;
import static android.content.pm.PackageManager.INSTALL_SCENARIO_DEFAULT;
+import static android.os.Process.INVALID_UID;
import static com.android.server.pm.PackageManagerService.TAG;
@@ -29,13 +30,19 @@ import android.content.pm.DataLoaderType;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
+import android.content.pm.SharedLibraryInfo;
import android.content.pm.SigningDetails;
import android.net.Uri;
+import android.os.Build;
+import android.os.Process;
import android.os.UserHandle;
import android.util.ExceptionUtils;
import android.util.Slog;
+import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.pkg.AndroidPackage;
+import com.android.server.pm.pkg.PackageStateInternal;
+import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
import java.io.File;
import java.util.ArrayList;
@@ -45,13 +52,59 @@ final class InstallRequest {
private final int mUserId;
@Nullable
private final InstallArgs mInstallArgs;
- @NonNull
- private final PackageInstalledInfo mInstalledInfo;
@Nullable
private Runnable mPostInstallRunnable;
@Nullable
private PackageRemovedInfo mRemovedInfo;
+ private @PackageManagerService.ScanFlags int mScanFlags;
+ private @ParsingPackageUtils.ParseFlags int mParseFlags;
+ private boolean mReplace;
+
+ @Nullable /* The original Package if it is being replaced, otherwise {@code null} */
+ private AndroidPackage mExistingPackage;
+ /** parsed package to be scanned */
+ @Nullable
+ private ParsedPackage mParsedPackage;
+ private boolean mClearCodeCache;
+ private boolean mSystem;
+ @Nullable
+ private PackageSetting mOriginalPs;
+ @Nullable
+ private PackageSetting mDisabledPs;
+
+ /** Package Installed Info */
+ @Nullable
+ private String mName;
+ private int mUid = -1;
+ // The set of users that originally had this package installed.
+ @Nullable
+ private int[] mOrigUsers;
+ // The set of users that now have this package installed.
+ @Nullable
+ private int[] mNewUsers;
+ @Nullable
+ private AndroidPackage mPkg;
+ private int mReturnCode;
+ @Nullable
+ private String mReturnMsg;
+ // The set of packages consuming this shared library or null if no consumers exist.
+ @Nullable
+ private ArrayList<AndroidPackage> mLibraryConsumers;
+ @Nullable
+ private PackageFreezer mFreezer;
+ /** The package this package replaces */
+ @Nullable
+ private String mOrigPackage;
+ @Nullable
+ private String mOrigPermission;
+ // The ApexInfo returned by ApexManager#installPackage, used by rebootless APEX install
+ @Nullable
+ private ApexInfo mApexInfo;
+
+ @Nullable
+ private ScanResult mScanResult;
+
// New install
InstallRequest(InstallingSession params) {
mUserId = params.getUser().getIdentifier();
@@ -63,7 +116,6 @@ final class InstallRequest {
params.mTraceMethod, params.mTraceCookie, params.mSigningDetails,
params.mInstallReason, params.mInstallScenario, params.mForceQueryableOverride,
params.mDataLoaderType, params.mPackageSource);
- mInstalledInfo = new PackageInstalledInfo();
}
// Install existing package as user
@@ -71,56 +123,56 @@ final class InstallRequest {
Runnable runnable) {
mUserId = userId;
mInstallArgs = null;
- mInstalledInfo = new PackageInstalledInfo();
- mInstalledInfo.mReturnCode = returnCode;
- mInstalledInfo.mPkg = pkg;
- mInstalledInfo.mNewUsers = newUsers;
+ mReturnCode = returnCode;
+ mPkg = pkg;
+ mNewUsers = newUsers;
mPostInstallRunnable = runnable;
}
- private static class PackageInstalledInfo {
- String mName;
- int mUid = -1;
- // The set of users that originally had this package installed.
- int[] mOrigUsers;
- // The set of users that now have this package installed.
- int[] mNewUsers;
- AndroidPackage mPkg;
- int mReturnCode;
- String mReturnMsg;
- String mInstallerPackageName;
- // The set of packages consuming this shared library or null if no consumers exist.
- ArrayList<AndroidPackage> mLibraryConsumers;
- PackageFreezer mFreezer;
- // In some error cases we want to convey more info back to the observer
- String mOrigPackage;
- String mOrigPermission;
- // The ApexInfo returned by ApexManager#installPackage, used by rebootless APEX install
- ApexInfo mApexInfo;
+ // addForInit
+ InstallRequest(ParsedPackage parsedPackage, int parseFlags, int scanFlags,
+ @Nullable UserHandle user, ScanResult scanResult) {
+ if (user != null) {
+ mUserId = user.getIdentifier();
+ } else {
+ // APEX
+ mUserId = INVALID_UID;
+ }
+ mInstallArgs = null;
+ mParsedPackage = parsedPackage;
+ mParseFlags = parseFlags;
+ mScanFlags = scanFlags;
+ mScanResult = scanResult;
}
+ @Nullable
public String getName() {
- return mInstalledInfo.mName;
+ return mName;
}
+ @Nullable
public String getReturnMsg() {
- return mInstalledInfo.mReturnMsg;
+ return mReturnMsg;
}
+ @Nullable
public OriginInfo getOriginInfo() {
return mInstallArgs == null ? null : mInstallArgs.mOriginInfo;
}
+ @Nullable
public PackageRemovedInfo getRemovedInfo() {
return mRemovedInfo;
}
+ @Nullable
public String getOrigPackage() {
- return mInstalledInfo.mOrigPackage;
+ return mOrigPackage;
}
+ @Nullable
public String getOrigPermission() {
- return mInstalledInfo.mOrigPermission;
+ return mOrigPermission;
}
@Nullable
@@ -140,7 +192,7 @@ final class InstallRequest {
}
public int getReturnCode() {
- return mInstalledInfo.mReturnCode;
+ return mReturnCode;
}
@Nullable
@@ -160,13 +212,13 @@ final class InstallRequest {
@Nullable
public String getMovePackageName() {
- return (mInstallArgs != null && mInstallArgs.mMoveInfo != null)
+ return (mInstallArgs != null && mInstallArgs.mMoveInfo != null)
? mInstallArgs.mMoveInfo.mPackageName : null;
}
@Nullable
public String getMoveFromCodePath() {
- return (mInstallArgs != null && mInstallArgs.mMoveInfo != null)
+ return (mInstallArgs != null && mInstallArgs.mMoveInfo != null)
? mInstallArgs.mMoveInfo.mFromCodePath : null;
}
@@ -203,8 +255,9 @@ final class InstallRequest {
return mInstallArgs == null ? null : mInstallArgs.mVolumeUuid;
}
+ @Nullable
public AndroidPackage getPkg() {
- return mInstalledInfo.mPkg;
+ return mPkg;
}
@Nullable
@@ -256,13 +309,15 @@ final class InstallRequest {
@Nullable
public Uri getOriginUri() {
- return mInstallArgs == null ? null : Uri.fromFile(mInstallArgs.mOriginInfo.mResolvedFile);
+ return mInstallArgs == null ? null : Uri.fromFile(mInstallArgs.mOriginInfo.mResolvedFile);
}
+ @Nullable
public ApexInfo getApexInfo() {
- return mInstalledInfo.mApexInfo;
+ return mApexInfo;
}
+ @Nullable
public String getSourceInstallerPackageName() {
return mInstallArgs.mInstallSource.installerPackageName;
}
@@ -272,25 +327,33 @@ final class InstallRequest {
&& mInstallArgs.mInstallReason == PackageManager.INSTALL_REASON_ROLLBACK;
}
+ @Nullable
public int[] getNewUsers() {
- return mInstalledInfo.mNewUsers;
+ return mNewUsers;
}
+ @Nullable
public int[] getOriginUsers() {
- return mInstalledInfo.mOrigUsers;
+ return mOrigUsers;
}
public int getUid() {
- return mInstalledInfo.mUid;
+ return mUid;
}
@Nullable
public String[] getInstallGrantPermissions() {
- return mInstallArgs == null ? null : mInstallArgs.mInstallGrantPermissions;
+ return mInstallArgs == null ? null : mInstallArgs.mInstallGrantPermissions;
}
+ @Nullable
public ArrayList<AndroidPackage> getLibraryConsumers() {
- return mInstalledInfo.mLibraryConsumers;
+ return mLibraryConsumers;
+ }
+
+ @Nullable
+ public AndroidPackage getExistingPackage() {
+ return mExistingPackage;
}
@Nullable
@@ -312,13 +375,170 @@ final class InstallRequest {
return mInstallArgs == null ? INSTALL_SCENARIO_DEFAULT : mInstallArgs.mInstallScenario;
}
+ @Nullable
+ public ParsedPackage getParsedPackage() {
+ return mParsedPackage;
+ }
+
+ public @ParsingPackageUtils.ParseFlags int getParseFlags() {
+ return mParseFlags;
+ }
+
+ public @PackageManagerService.ScanFlags int getScanFlags() {
+ return mScanFlags;
+ }
+
+ @Nullable
+ public String getExistingPackageName() {
+ if (mExistingPackage != null) {
+ return mExistingPackage.getPackageName();
+ }
+ return null;
+ }
+
+ @Nullable
+ public AndroidPackage getScanRequestOldPackage() {
+ assertScanResultExists();
+ return mScanResult.mRequest.mOldPkg;
+ }
+
+ public boolean isClearCodeCache() {
+ return mClearCodeCache;
+ }
+
+ public boolean isReplace() {
+ return mReplace;
+ }
+
+ public boolean isSystem() {
+ return mSystem;
+ }
+
+ @Nullable
+ public PackageSetting getOriginalPackageSetting() {
+ return mOriginalPs;
+ }
+
+ @Nullable
+ public PackageSetting getDisabledPackageSetting() {
+ return mDisabledPs;
+ }
+
+ @Nullable
+ public PackageSetting getScanRequestOldPackageSetting() {
+ assertScanResultExists();
+ return mScanResult.mRequest.mOldPkgSetting;
+ }
+
+ @Nullable
+ public PackageSetting getScanRequestOriginalPackageSetting() {
+ assertScanResultExists();
+ return mScanResult.mRequest.mOriginalPkgSetting;
+ }
+
+ @Nullable
+ public PackageSetting getScanRequestPackageSetting() {
+ assertScanResultExists();
+ return mScanResult.mRequest.mPkgSetting;
+ }
+
+ @Nullable
+ public String getRealPackageName() {
+ assertScanResultExists();
+ return mScanResult.mRequest.mRealPkgName;
+ }
+
+ @Nullable
+ public List<String> getChangedAbiCodePath() {
+ assertScanResultExists();
+ return mScanResult.mChangedAbiCodePath;
+ }
+
public boolean isForceQueryableOverride() {
return mInstallArgs != null && mInstallArgs.mForceQueryableOverride;
}
+ @Nullable
+ public SharedLibraryInfo getSdkSharedLibraryInfo() {
+ assertScanResultExists();
+ return mScanResult.mSdkSharedLibraryInfo;
+ }
+
+ @Nullable
+ public SharedLibraryInfo getStaticSharedLibraryInfo() {
+ assertScanResultExists();
+ return mScanResult.mStaticSharedLibraryInfo;
+ }
+
+ @Nullable
+ public List<SharedLibraryInfo> getDynamicSharedLibraryInfos() {
+ assertScanResultExists();
+ return mScanResult.mDynamicSharedLibraryInfos;
+ }
+
+ @Nullable
+ public PackageSetting getScannedPackageSetting() {
+ assertScanResultExists();
+ return mScanResult.mPkgSetting;
+ }
+
+ @Nullable
+ public PackageSetting getRealPackageSetting() {
+ // TODO: Fix this to have 1 mutable PackageSetting for scan/install. If the previous
+ // setting needs to be passed to have a comparison, hide it behind an immutable
+ // interface. There's no good reason to have 3 different ways to access the real
+ // PackageSetting object, only one of which is actually correct.
+ PackageSetting realPkgSetting = isExistingSettingCopied()
+ ? getScanRequestPackageSetting() : getScannedPackageSetting();
+ if (realPkgSetting == null) {
+ realPkgSetting = getScannedPackageSetting();
+ }
+ return realPkgSetting;
+ }
+
+ public boolean isExistingSettingCopied() {
+ assertScanResultExists();
+ return mScanResult.mExistingSettingCopied;
+ }
+
+ /**
+ * Whether the original PackageSetting needs to be updated with
+ * a new app ID. Useful when leaving a sharedUserId.
+ */
+ public boolean needsNewAppId() {
+ assertScanResultExists();
+ return mScanResult.mPreviousAppId != Process.INVALID_UID;
+ }
+
+ public int getPreviousAppId() {
+ assertScanResultExists();
+ return mScanResult.mPreviousAppId;
+ }
+
+ public boolean isPlatformPackage() {
+ assertScanResultExists();
+ return mScanResult.mRequest.mIsPlatformPackage;
+ }
+
+ public void assertScanResultExists() {
+ if (mScanResult == null) {
+ // Should not happen. This indicates a bug in the installation code flow
+ if (Build.IS_USERDEBUG || Build.IS_ENG) {
+ throw new IllegalStateException("ScanResult cannot be null.");
+ } else {
+ Slog.e(TAG, "ScanResult is null and it should not happen");
+ }
+ }
+
+ }
+
+ public void setScanFlags(int scanFlags) {
+ mScanFlags = scanFlags;
+ }
+
public void closeFreezer() {
- if (mInstalledInfo.mFreezer != null) {
- mInstalledInfo.mFreezer.close();
+ if (mFreezer != null) {
+ mFreezer.close();
}
}
@@ -341,57 +561,53 @@ final class InstallRequest {
}
public void setError(String msg, PackageManagerException e) {
- mInstalledInfo.mReturnCode = e.error;
+ mReturnCode = e.error;
setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
Slog.w(TAG, msg, e);
}
public void setReturnCode(int returnCode) {
- mInstalledInfo.mReturnCode = returnCode;
+ mReturnCode = returnCode;
}
public void setReturnMessage(String returnMsg) {
- mInstalledInfo.mReturnMsg = returnMsg;
+ mReturnMsg = returnMsg;
}
public void setApexInfo(ApexInfo apexInfo) {
- mInstalledInfo.mApexInfo = apexInfo;
+ mApexInfo = apexInfo;
}
public void setPkg(AndroidPackage pkg) {
- mInstalledInfo.mPkg = pkg;
+ mPkg = pkg;
}
public void setUid(int uid) {
- mInstalledInfo.mUid = uid;
+ mUid = uid;
}
public void setNewUsers(int[] newUsers) {
- mInstalledInfo.mNewUsers = newUsers;
+ mNewUsers = newUsers;
}
public void setOriginPackage(String originPackage) {
- mInstalledInfo.mOrigPackage = originPackage;
+ mOrigPackage = originPackage;
}
public void setOriginPermission(String originPermission) {
- mInstalledInfo.mOrigPermission = originPermission;
- }
-
- public void setInstallerPackageName(String installerPackageName) {
- mInstalledInfo.mInstallerPackageName = installerPackageName;
+ mOrigPermission = originPermission;
}
public void setName(String packageName) {
- mInstalledInfo.mName = packageName;
+ mName = packageName;
}
public void setOriginUsers(int[] userIds) {
- mInstalledInfo.mOrigUsers = userIds;
+ mOrigUsers = userIds;
}
public void setFreezer(PackageFreezer freezer) {
- mInstalledInfo.mFreezer = freezer;
+ mFreezer = freezer;
}
public void setRemovedInfo(PackageRemovedInfo removedInfo) {
@@ -399,6 +615,47 @@ final class InstallRequest {
}
public void setLibraryConsumers(ArrayList<AndroidPackage> libraryConsumers) {
- mInstalledInfo.mLibraryConsumers = libraryConsumers;
+ mLibraryConsumers = libraryConsumers;
+ }
+
+ public void setPrepareResult(boolean replace, int scanFlags,
+ int parseFlags, AndroidPackage existingPackage,
+ ParsedPackage packageToScan, boolean clearCodeCache, boolean system,
+ PackageSetting originalPs, PackageSetting disabledPs) {
+ mReplace = replace;
+ mScanFlags = scanFlags;
+ mParseFlags = parseFlags;
+ mExistingPackage = existingPackage;
+ mParsedPackage = packageToScan;
+ mClearCodeCache = clearCodeCache;
+ mSystem = system;
+ mOriginalPs = originalPs;
+ mDisabledPs = disabledPs;
+ }
+
+ public void setScanResult(@NonNull ScanResult scanResult) {
+ mScanResult = scanResult;
+ }
+
+ public void setScannedPackageSettingAppId(int appId) {
+ assertScanResultExists();
+ mScanResult.mPkgSetting.setAppId(appId);
+ }
+
+ public void setScannedPackageSettingFirstInstallTimeFromReplaced(
+ @Nullable PackageStateInternal replacedPkgSetting, int[] userId) {
+ assertScanResultExists();
+ mScanResult.mPkgSetting.setFirstInstallTimeFromReplaced(replacedPkgSetting, userId);
+ }
+
+ public void setScannedPackageSettingLastUpdateTime(long lastUpdateTim) {
+ assertScanResultExists();
+ mScanResult.mPkgSetting.setLastUpdateTime(lastUpdateTim);
+ }
+
+ public void setRemovedAppId(int appId) {
+ if (mRemovedInfo != null) {
+ mRemovedInfo.mRemovedAppId = appId;
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/InstallingSession.java b/services/core/java/com/android/server/pm/InstallingSession.java
index 8d5a5e156e71..16b3a815c075 100644
--- a/services/core/java/com/android/server/pm/InstallingSession.java
+++ b/services/core/java/com/android/server/pm/InstallingSession.java
@@ -42,7 +42,7 @@ import android.content.pm.parsing.PackageLite;
import android.os.Environment;
import android.os.Trace;
import android.os.UserHandle;
-import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.Pair;
import android.util.Slog;
@@ -60,7 +60,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
+import java.util.Set;
class InstallingSession {
final OriginInfo mOriginInfo;
@@ -599,7 +599,7 @@ class InstallingSession {
*/
private class MultiPackageInstallingSession {
private final List<InstallingSession> mChildInstallingSessions;
- private final Map<InstallRequest, Integer> mCurrentState;
+ private final Set<InstallRequest> mCurrentInstallRequests;
@NonNull
final PackageManagerService mPm;
final UserHandle mUser;
@@ -618,7 +618,7 @@ class InstallingSession {
final InstallingSession childInstallingSession = childInstallingSessions.get(i);
childInstallingSession.mParentInstallingSession = this;
}
- this.mCurrentState = new ArrayMap<>(mChildInstallingSessions.size());
+ mCurrentInstallRequests = new ArraySet<>(mChildInstallingSessions.size());
}
public void start() {
@@ -636,23 +636,24 @@ class InstallingSession {
}
public void tryProcessInstallRequest(InstallRequest request) {
- mCurrentState.put(request, request.getReturnCode());
- if (mCurrentState.size() != mChildInstallingSessions.size()) {
+ mCurrentInstallRequests.add(request);
+ if (mCurrentInstallRequests.size() != mChildInstallingSessions.size()) {
return;
}
int completeStatus = PackageManager.INSTALL_SUCCEEDED;
- for (Integer status : mCurrentState.values()) {
- if (status == PackageManager.INSTALL_UNKNOWN) {
+ for (InstallRequest installRequest : mCurrentInstallRequests) {
+ if (installRequest.getReturnCode() == PackageManager.INSTALL_UNKNOWN) {
return;
- } else if (status != PackageManager.INSTALL_SUCCEEDED) {
- completeStatus = status;
+ } else if (installRequest.getReturnCode() != PackageManager.INSTALL_SUCCEEDED) {
+ completeStatus = installRequest.getReturnCode();
break;
}
}
- final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
- for (Map.Entry<InstallRequest, Integer> entry : mCurrentState.entrySet()) {
- entry.getKey().setReturnCode(completeStatus);
- installRequests.add(entry.getKey());
+ final List<InstallRequest> installRequests = new ArrayList<>(
+ mCurrentInstallRequests.size());
+ for (InstallRequest installRequest : mCurrentInstallRequests) {
+ installRequest.setReturnCode(completeStatus);
+ installRequests.add(installRequest);
}
int finalCompleteStatus = completeStatus;
mPm.mHandler.post(() -> processInstallRequests(
diff --git a/services/core/java/com/android/server/pm/PrepareResult.java b/services/core/java/com/android/server/pm/PrepareResult.java
deleted file mode 100644
index e074f44afff5..000000000000
--- a/services/core/java/com/android/server/pm/PrepareResult.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm;
-
-import android.annotation.Nullable;
-
-import com.android.server.pm.parsing.pkg.ParsedPackage;
-import com.android.server.pm.pkg.AndroidPackage;
-
-/**
- * The set of data needed to successfully install the prepared package. This includes data that
- * will be used to scan and reconcile the package.
- */
-final class PrepareResult {
- public final boolean mReplace;
- public final int mScanFlags;
- public final int mParseFlags;
- @Nullable /* The original Package if it is being replaced, otherwise {@code null} */
- public final AndroidPackage mExistingPackage;
- public final ParsedPackage mPackageToScan;
- public final boolean mClearCodeCache;
- public final boolean mSystem;
- public final PackageSetting mOriginalPs;
- public final PackageSetting mDisabledPs;
-
- PrepareResult(boolean replace, int scanFlags,
- int parseFlags, AndroidPackage existingPackage,
- ParsedPackage packageToScan, boolean clearCodeCache, boolean system,
- PackageSetting originalPs, PackageSetting disabledPs) {
- mReplace = replace;
- mScanFlags = scanFlags;
- mParseFlags = parseFlags;
- mExistingPackage = existingPackage;
- mPackageToScan = packageToScan;
- mClearCodeCache = clearCodeCache;
- mSystem = system;
- mOriginalPs = originalPs;
- mDisabledPs = disabledPs;
- }
-}
diff --git a/services/core/java/com/android/server/pm/ReconcilePackageUtils.java b/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
index 165b450ce65b..ffce69e00d24 100644
--- a/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
+++ b/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
@@ -38,34 +38,44 @@ import com.android.server.utils.WatchedLongSparseArray;
import java.util.List;
import java.util.Map;
+/**
+ * Package scan results and related request details used to reconcile the potential addition of
+ * one or more packages to the system.
+ *
+ * Reconcile will take a set of package details that need to be committed to the system and make
+ * sure that they are valid in the context of the system and the other installing apps. Any
+ * invalid state or app will result in a failed reconciliation and thus whatever operation (such
+ * as install) led to the request.
+ */
final class ReconcilePackageUtils {
public static Map<String, ReconciledPackage> reconcilePackages(
- final ReconcileRequest request, SharedLibrariesImpl sharedLibraries,
+ List<InstallRequest> installRequests,
+ Map<String, AndroidPackage> allPackages,
+ Map<String, Settings.VersionInfo> versionInfos,
+ SharedLibrariesImpl sharedLibraries,
KeySetManagerService ksms, Settings settings)
throws ReconcileFailure {
- final Map<String, ScanResult> scannedPackages = request.mScannedPackages;
-
- final Map<String, ReconciledPackage> result = new ArrayMap<>(scannedPackages.size());
+ final Map<String, ReconciledPackage> result = new ArrayMap<>(installRequests.size());
// make a copy of the existing set of packages so we can combine them with incoming packages
final ArrayMap<String, AndroidPackage> combinedPackages =
- new ArrayMap<>(request.mAllPackages.size() + scannedPackages.size());
+ new ArrayMap<>(allPackages.size() + installRequests.size());
- combinedPackages.putAll(request.mAllPackages);
+ combinedPackages.putAll(allPackages);
final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> incomingSharedLibraries =
new ArrayMap<>();
- for (String installPackageName : scannedPackages.keySet()) {
- final ScanResult scanResult = scannedPackages.get(installPackageName);
+ for (InstallRequest installRequest : installRequests) {
+ final String installPackageName = installRequest.getParsedPackage().getPackageName();
// add / replace existing with incoming packages
- combinedPackages.put(scanResult.mPkgSetting.getPackageName(),
- scanResult.mRequest.mParsedPackage);
+ combinedPackages.put(installRequest.getScannedPackageSetting().getPackageName(),
+ installRequest.getParsedPackage());
// in the first pass, we'll build up the set of incoming shared libraries
final List<SharedLibraryInfo> allowedSharedLibInfos =
- sharedLibraries.getAllowedSharedLibInfos(scanResult);
+ sharedLibraries.getAllowedSharedLibInfos(installRequest);
if (allowedSharedLibInfos != null) {
for (SharedLibraryInfo info : allowedSharedLibInfos) {
if (!SharedLibraryUtils.addSharedLibraryToPackageVersionMap(
@@ -76,24 +86,18 @@ final class ReconcilePackageUtils {
}
}
- // the following may be null if we're just reconciling on boot (and not during install)
- final InstallRequest installRequest = request.mInstallRequests.get(installPackageName);
- final PrepareResult prepareResult = request.mPreparedPackages.get(installPackageName);
- final boolean isInstall = installRequest != null;
- if (isInstall && prepareResult == null) {
- throw new ReconcileFailure("Reconcile arguments are not balanced for "
- + installPackageName + "!");
- }
+
final DeletePackageAction deletePackageAction;
// we only want to try to delete for non system apps
- if (isInstall && prepareResult.mReplace && !prepareResult.mSystem) {
- final boolean killApp = (scanResult.mRequest.mScanFlags & SCAN_DONT_KILL_APP) == 0;
+ if (installRequest.isReplace() && !installRequest.isSystem()) {
+ final boolean killApp = (installRequest.getScanFlags() & SCAN_DONT_KILL_APP) == 0;
final int deleteFlags = PackageManager.DELETE_KEEP_DATA
| (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
deletePackageAction = DeletePackageHelper.mayDeletePackageLocked(
installRequest.getRemovedInfo(),
- prepareResult.mOriginalPs, prepareResult.mDisabledPs,
+ installRequest.getOriginalPackageSetting(),
+ installRequest.getDisabledPackageSetting(),
deleteFlags, null /* all users */);
if (deletePackageAction == null) {
throw new ReconcileFailure(
@@ -104,21 +108,24 @@ final class ReconcilePackageUtils {
deletePackageAction = null;
}
- final int scanFlags = scanResult.mRequest.mScanFlags;
- final int parseFlags = scanResult.mRequest.mParseFlags;
- final ParsedPackage parsedPackage = scanResult.mRequest.mParsedPackage;
-
- final PackageSetting disabledPkgSetting = scanResult.mRequest.mDisabledPkgSetting;
+ final int scanFlags = installRequest.getScanFlags();
+ final int parseFlags = installRequest.getParseFlags();
+ final ParsedPackage parsedPackage = installRequest.getParsedPackage();
+ final PackageSetting disabledPkgSetting = installRequest.getDisabledPackageSetting();
final PackageSetting lastStaticSharedLibSetting =
- scanResult.mStaticSharedLibraryInfo == null ? null
- : sharedLibraries.getStaticSharedLibLatestVersionSetting(scanResult);
+ installRequest.getStaticSharedLibraryInfo() == null ? null
+ : sharedLibraries.getStaticSharedLibLatestVersionSetting(
+ installRequest);
final PackageSetting signatureCheckPs =
- (prepareResult != null && lastStaticSharedLibSetting != null)
+ lastStaticSharedLibSetting != null
? lastStaticSharedLibSetting
- : scanResult.mPkgSetting;
+ : installRequest.getScannedPackageSetting();
boolean removeAppKeySetData = false;
boolean sharedUserSignaturesChanged = false;
SigningDetails signingDetails = null;
+ if (parsedPackage != null) {
+ signingDetails = parsedPackage.getSigningDetails();
+ }
SharedUserSetting sharedUserSetting = settings.getSharedUserSettingLPr(
signatureCheckPs);
if (ksms.shouldCheckUpgradeKeySetLocked(
@@ -138,28 +145,21 @@ final class ReconcilePackageUtils {
PackageManagerService.reportSettingsProblem(Log.WARN, msg);
}
}
- signingDetails = parsedPackage.getSigningDetails();
} else {
-
try {
- final Settings.VersionInfo versionInfo =
- request.mVersionInfos.get(installPackageName);
+ final Settings.VersionInfo versionInfo = versionInfos.get(installPackageName);
final boolean compareCompat = isCompatSignatureUpdateNeeded(versionInfo);
final boolean compareRecover = isRecoverSignatureUpdateNeeded(versionInfo);
- final boolean isRollback = installRequest != null
- && installRequest.isRollback();
+ final boolean isRollback = installRequest.isRollback();
final boolean compatMatch =
PackageManagerServiceUtils.verifySignatures(signatureCheckPs,
sharedUserSetting, disabledPkgSetting,
- parsedPackage.getSigningDetails(), compareCompat,
+ signingDetails, compareCompat,
compareRecover, isRollback);
// The new KeySets will be re-added later in the scanning process.
if (compatMatch) {
removeAppKeySetData = true;
}
- // We just determined the app is signed correctly, so bring
- // over the latest parsed certs.
- signingDetails = parsedPackage.getSigningDetails();
// if this is is a sharedUser, check to see if the new package is signed by a
// newer
@@ -257,13 +257,12 @@ final class ReconcilePackageUtils {
}
result.put(installPackageName,
- new ReconciledPackage(request, installRequest, scanResult.mPkgSetting,
- request.mPreparedPackages.get(installPackageName), scanResult,
+ new ReconciledPackage(installRequests, allPackages, installRequest,
deletePackageAction, allowedSharedLibInfos, signingDetails,
sharedUserSignaturesChanged, removeAppKeySetData));
}
- for (String installPackageName : scannedPackages.keySet()) {
+ for (InstallRequest installRequest : installRequests) {
// Check all shared libraries and map to their actual file path.
// We only do this here for apps not on a system dir, because those
// are the only ones that can fail an install due to this. We
@@ -271,16 +270,16 @@ final class ReconcilePackageUtils {
// library paths after the scan is done. Also during the initial
// scan don't update any libs as we do this wholesale after all
// apps are scanned to avoid dependency based scanning.
- final ScanResult scanResult = scannedPackages.get(installPackageName);
- if ((scanResult.mRequest.mScanFlags & SCAN_BOOTING) != 0
- || (scanResult.mRequest.mParseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR)
+ if ((installRequest.getScanFlags() & SCAN_BOOTING) != 0
+ || (installRequest.getParseFlags() & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR)
!= 0) {
continue;
}
+ final String installPackageName = installRequest.getParsedPackage().getPackageName();
try {
result.get(installPackageName).mCollectedSharedLibraryInfos =
sharedLibraries.collectSharedLibraryInfos(
- scanResult.mRequest.mParsedPackage, combinedPackages,
+ installRequest.getParsedPackage(), combinedPackages,
incomingSharedLibraries);
} catch (PackageManagerException e) {
throw new ReconcileFailure(e.error, e.getMessage());
diff --git a/services/core/java/com/android/server/pm/ReconcileRequest.java b/services/core/java/com/android/server/pm/ReconcileRequest.java
deleted file mode 100644
index 3568c153de91..000000000000
--- a/services/core/java/com/android/server/pm/ReconcileRequest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm;
-
-import com.android.server.pm.pkg.AndroidPackage;
-
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * Package scan results and related request details used to reconcile the potential addition of
- * one or more packages to the system.
- *
- * Reconcile will take a set of package details that need to be committed to the system and make
- * sure that they are valid in the context of the system and the other installing apps. Any
- * invalid state or app will result in a failed reconciliation and thus whatever operation (such
- * as install) led to the request.
- */
-final class ReconcileRequest {
- public final Map<String, ScanResult> mScannedPackages;
-
- public final Map<String, AndroidPackage> mAllPackages;
- public final Map<String, InstallRequest> mInstallRequests;
- public final Map<String, PrepareResult> mPreparedPackages;
- public final Map<String, Settings.VersionInfo> mVersionInfos;
-
- ReconcileRequest(Map<String, ScanResult> scannedPackages,
- Map<String, InstallRequest> installRequests,
- Map<String, PrepareResult> preparedPackages,
- Map<String, AndroidPackage> allPackages,
- Map<String, Settings.VersionInfo> versionInfos) {
- mScannedPackages = scannedPackages;
- mInstallRequests = installRequests;
- mPreparedPackages = preparedPackages;
- mAllPackages = allPackages;
- mVersionInfos = versionInfos;
- }
-
- ReconcileRequest(Map<String, ScanResult> scannedPackages,
- Map<String, AndroidPackage> allPackages,
- Map<String, Settings.VersionInfo> versionInfos) {
- this(scannedPackages, Collections.emptyMap(),
- Collections.emptyMap(), allPackages, versionInfos);
- }
-}
diff --git a/services/core/java/com/android/server/pm/ReconciledPackage.java b/services/core/java/com/android/server/pm/ReconciledPackage.java
index d4da6c798b15..701baee085ed 100644
--- a/services/core/java/com/android/server/pm/ReconciledPackage.java
+++ b/services/core/java/com/android/server/pm/ReconciledPackage.java
@@ -17,7 +17,6 @@
package com.android.server.pm;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.SigningDetails;
import android.util.ArrayMap;
@@ -33,12 +32,9 @@ import java.util.Map;
* TODO: move most of the data contained here into a PackageSetting for commit.
*/
final class ReconciledPackage {
- public final ReconcileRequest mRequest;
- public final PackageSetting mPkgSetting;
- public final ScanResult mScanResult;
- // TODO: Remove install-specific details from the reconcile result
- @Nullable public final PrepareResult mPrepareResult;
- @Nullable public final InstallRequest mInstallRequest;
+ private final List<InstallRequest> mInstallRequests;
+ private final Map<String, AndroidPackage> mAllPackages;
+ @NonNull public final InstallRequest mInstallRequest;
public final DeletePackageAction mDeletePackageAction;
public final List<SharedLibraryInfo> mAllowedSharedLibraryInfos;
public final SigningDetails mSigningDetails;
@@ -46,21 +42,17 @@ final class ReconciledPackage {
public ArrayList<SharedLibraryInfo> mCollectedSharedLibraryInfos;
public final boolean mRemoveAppKeySetData;
- ReconciledPackage(ReconcileRequest request,
+ ReconciledPackage(List<InstallRequest> installRequests,
+ Map<String, AndroidPackage> allPackages,
InstallRequest installRequest,
- PackageSetting pkgSetting,
- PrepareResult prepareResult,
- ScanResult scanResult,
DeletePackageAction deletePackageAction,
List<SharedLibraryInfo> allowedSharedLibraryInfos,
SigningDetails signingDetails,
boolean sharedUserSignaturesChanged,
boolean removeAppKeySetData) {
- mRequest = request;
+ mInstallRequests = installRequests;
+ mAllPackages = allPackages;
mInstallRequest = installRequest;
- mPkgSetting = pkgSetting;
- mPrepareResult = prepareResult;
- mScanResult = scanResult;
mDeletePackageAction = deletePackageAction;
mAllowedSharedLibraryInfos = allowedSharedLibraryInfos;
mSigningDetails = signingDetails;
@@ -75,13 +67,13 @@ final class ReconciledPackage {
*/
@NonNull Map<String, AndroidPackage> getCombinedAvailablePackages() {
final ArrayMap<String, AndroidPackage> combined =
- new ArrayMap<>(mRequest.mAllPackages.size() + mRequest.mScannedPackages.size());
+ new ArrayMap<>(mAllPackages.size() + mInstallRequests.size());
- combined.putAll(mRequest.mAllPackages);
+ combined.putAll(mAllPackages);
- for (ScanResult scanResult : mRequest.mScannedPackages.values()) {
- combined.put(scanResult.mPkgSetting.getPackageName(),
- scanResult.mRequest.mParsedPackage);
+ for (InstallRequest installRequest : mInstallRequests) {
+ combined.put(installRequest.getScannedPackageSetting().getPackageName(),
+ installRequest.getParsedPackage());
}
return combined;
diff --git a/services/core/java/com/android/server/pm/ScanPackageUtils.java b/services/core/java/com/android/server/pm/ScanPackageUtils.java
index bd3c7dd0a4b4..a905df98e577 100644
--- a/services/core/java/com/android/server/pm/ScanPackageUtils.java
+++ b/services/core/java/com/android/server/pm/ScanPackageUtils.java
@@ -462,7 +462,7 @@ final class ScanPackageUtils {
}
}
- return new ScanResult(request, true, pkgSetting, changedAbiCodePath,
+ return new ScanResult(request, pkgSetting, changedAbiCodePath,
!createNewPackage /* existingSettingCopied */,
Process.INVALID_UID /* previousAppId */ , sdkLibraryInfo,
staticSharedLibraryInfo, dynamicSharedLibraryInfos);
diff --git a/services/core/java/com/android/server/pm/ScanResult.java b/services/core/java/com/android/server/pm/ScanResult.java
index e2860ca327e7..750e893ebefb 100644
--- a/services/core/java/com/android/server/pm/ScanResult.java
+++ b/services/core/java/com/android/server/pm/ScanResult.java
@@ -16,6 +16,7 @@
package com.android.server.pm;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.SharedLibraryInfo;
import android.os.Process;
@@ -28,9 +29,7 @@ import java.util.List;
@VisibleForTesting
final class ScanResult {
/** The request that initiated the scan that produced this result. */
- public final ScanRequest mRequest;
- /** Whether or not the package scan was successful */
- public final boolean mSuccess;
+ @NonNull public final ScanRequest mRequest;
/**
* Whether or not the original PackageSetting needs to be updated with this result on
* commit.
@@ -58,7 +57,7 @@ final class ScanResult {
public final List<SharedLibraryInfo> mDynamicSharedLibraryInfos;
ScanResult(
- ScanRequest request, boolean success,
+ @NonNull ScanRequest request,
@Nullable PackageSetting pkgSetting,
@Nullable List<String> changedAbiCodePath, boolean existingSettingCopied,
int previousAppId,
@@ -66,7 +65,6 @@ final class ScanResult {
SharedLibraryInfo staticSharedLibraryInfo,
List<SharedLibraryInfo> dynamicSharedLibraryInfos) {
mRequest = request;
- mSuccess = success;
mPkgSetting = pkgSetting;
mChangedAbiCodePath = changedAbiCodePath;
mExistingSettingCopied = existingSettingCopied;
diff --git a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
index 094e748685e5..aa23d8d75c8c 100644
--- a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
+++ b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
@@ -422,15 +422,18 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
* Given a package scanned result of a static shared library, returns its package setting of
* the latest version
*
- * @param scanResult The scanned result of a static shared library package.
+ * @param installRequest The install result of a static shared library package.
* @return The package setting that represents the latest version of shared library info.
*/
@Nullable
- PackageSetting getStaticSharedLibLatestVersionSetting(@NonNull ScanResult scanResult) {
+ PackageSetting getStaticSharedLibLatestVersionSetting(@NonNull InstallRequest installRequest) {
+ if (installRequest.getParsedPackage() == null) {
+ return null;
+ }
PackageSetting sharedLibPackage = null;
synchronized (mPm.mLock) {
final SharedLibraryInfo latestSharedLibraVersionLPr =
- getLatestStaticSharedLibraVersionLPr(scanResult.mRequest.mParsedPackage);
+ getLatestStaticSharedLibraVersionLPr(installRequest.getParsedPackage());
if (latestSharedLibraVersionLPr != null) {
sharedLibPackage = mPm.mSettings.getPackageLPr(
latestSharedLibraVersionLPr.getPackageName());
@@ -823,34 +826,35 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
* Compare the newly scanned package with current system state to see which of its declared
* shared libraries should be allowed to be added to the system.
*/
- List<SharedLibraryInfo> getAllowedSharedLibInfos(ScanResult scanResult) {
+ List<SharedLibraryInfo> getAllowedSharedLibInfos(InstallRequest installRequest) {
// Let's used the parsed package as scanResult.pkgSetting may be null
- final ParsedPackage parsedPackage = scanResult.mRequest.mParsedPackage;
- if (scanResult.mSdkSharedLibraryInfo == null && scanResult.mStaticSharedLibraryInfo == null
- && scanResult.mDynamicSharedLibraryInfos == null) {
+ final ParsedPackage parsedPackage = installRequest.getParsedPackage();
+ if (installRequest.getSdkSharedLibraryInfo() == null
+ && installRequest.getStaticSharedLibraryInfo() == null
+ && installRequest.getDynamicSharedLibraryInfos() == null) {
return null;
}
// Any app can add new SDKs and static shared libraries.
- if (scanResult.mSdkSharedLibraryInfo != null) {
- return Collections.singletonList(scanResult.mSdkSharedLibraryInfo);
+ if (installRequest.getSdkSharedLibraryInfo() != null) {
+ return Collections.singletonList(installRequest.getSdkSharedLibraryInfo());
}
- if (scanResult.mStaticSharedLibraryInfo != null) {
- return Collections.singletonList(scanResult.mStaticSharedLibraryInfo);
+ if (installRequest.getStaticSharedLibraryInfo() != null) {
+ return Collections.singletonList(installRequest.getStaticSharedLibraryInfo());
}
- final boolean hasDynamicLibraries = parsedPackage.isSystem()
- && scanResult.mDynamicSharedLibraryInfos != null;
+ final boolean hasDynamicLibraries = parsedPackage != null && parsedPackage.isSystem()
+ && installRequest.getDynamicSharedLibraryInfos() != null;
if (!hasDynamicLibraries) {
return null;
}
- final boolean isUpdatedSystemApp = scanResult.mPkgSetting.getPkgState()
- .isUpdatedSystemApp();
+ final boolean isUpdatedSystemApp = installRequest.getScannedPackageSetting() != null
+ && installRequest.getScannedPackageSetting().getPkgState().isUpdatedSystemApp();
// We may not yet have disabled the updated package yet, so be sure to grab the
// current setting if that's the case.
final PackageSetting updatedSystemPs = isUpdatedSystemApp
- ? scanResult.mRequest.mDisabledPkgSetting == null
- ? scanResult.mRequest.mOldPkgSetting
- : scanResult.mRequest.mDisabledPkgSetting
+ ? installRequest.getDisabledPackageSetting() == null
+ ? installRequest.getScanRequestOldPackageSetting()
+ : installRequest.getDisabledPackageSetting()
: null;
if (isUpdatedSystemApp && (updatedSystemPs.getPkg() == null
|| updatedSystemPs.getPkg().getLibraryNames() == null)) {
@@ -859,8 +863,8 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
return null;
}
final ArrayList<SharedLibraryInfo> infos =
- new ArrayList<>(scanResult.mDynamicSharedLibraryInfos.size());
- for (SharedLibraryInfo info : scanResult.mDynamicSharedLibraryInfos) {
+ new ArrayList<>(installRequest.getDynamicSharedLibraryInfos().size());
+ for (SharedLibraryInfo info : installRequest.getDynamicSharedLibraryInfos()) {
final String name = info.getName();
if (isUpdatedSystemApp) {
// New library entries can only be added through the
diff --git a/services/core/java/com/android/server/pm/StorageEventHelper.java b/services/core/java/com/android/server/pm/StorageEventHelper.java
index 477e260a4818..aeb11b77f794 100644
--- a/services/core/java/com/android/server/pm/StorageEventHelper.java
+++ b/services/core/java/com/android/server/pm/StorageEventHelper.java
@@ -158,7 +158,7 @@ public final class StorageEventHelper extends StorageEventListener {
final AndroidPackage pkg;
try {
pkg = installPackageHelper.scanSystemPackageTracedLI(
- ps.getPath(), parseFlags, SCAN_INITIAL, null);
+ ps.getPath(), parseFlags, SCAN_INITIAL);
loaded.add(pkg);
} catch (PackageManagerException e) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
index e28d331b770b..28c78b20aae2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
@@ -22,6 +22,7 @@ import android.content.pm.SharedLibraryInfo
import android.content.pm.VersionedPackage
import android.os.Build
import android.os.storage.StorageManager
+import android.os.UserHandle
import android.util.ArrayMap
import android.util.PackageUtils
import com.android.server.SystemConfig.SharedLibraryEntry
@@ -222,10 +223,11 @@ class SharedLibrariesImplTest {
val parsedPackage = pair.second as ParsedPackage
val scanRequest = ScanRequest(parsedPackage, null, null, null, null,
null, null, null, 0, 0, false, null, null)
- val scanResult = ScanResult(scanRequest, true, null, null, false, 0, null, null, null)
+ val scanResult = ScanResult(scanRequest, null, null, false, 0, null, null, null)
+ var installRequest = InstallRequest(parsedPackage, 0, 0, UserHandle(0), scanResult)
val latestInfoSetting =
- mSharedLibrariesImpl.getStaticSharedLibLatestVersionSetting(scanResult)!!
+ mSharedLibrariesImpl.getStaticSharedLibLatestVersionSetting(installRequest)!!
assertThat(latestInfoSetting).isNotNull()
assertThat(latestInfoSetting.packageName).isEqualTo(STATIC_LIB_PACKAGE_NAME)
@@ -305,10 +307,11 @@ class SharedLibrariesImplTest {
@Test
fun getAllowedSharedLibInfos_withStaticSharedLibInfo() {
val testInfo = libOfStatic(TEST_LIB_PACKAGE_NAME, TEST_LIB_NAME, 1L)
- val scanResult = ScanResult(mock(), true, null, null,
+ val scanResult = ScanResult(mock(), null, null,
false, 0, null, testInfo, null)
+ var installRequest = InstallRequest(mock(), 0, 0, UserHandle(0), scanResult)
- val allowedInfos = mSharedLibrariesImpl.getAllowedSharedLibInfos(scanResult)
+ val allowedInfos = mSharedLibrariesImpl.getAllowedSharedLibInfos(installRequest)
assertThat(allowedInfos).hasSize(1)
assertThat(allowedInfos[0].name).isEqualTo(TEST_LIB_NAME)
@@ -327,10 +330,11 @@ class SharedLibrariesImplTest {
.setPkgFlags(ApplicationInfo.FLAG_SYSTEM).build()
val scanRequest = ScanRequest(parsedPackage, null, null, null, null,
null, null, null, 0, 0, false, null, null)
- val scanResult = ScanResult(scanRequest, true, packageSetting, null,
+ val scanResult = ScanResult(scanRequest, packageSetting, null,
false, 0, null, null, listOf(testInfo))
+ var installRequest = InstallRequest(parsedPackage, 0, 0, UserHandle(0), scanResult)
- val allowedInfos = mSharedLibrariesImpl.getAllowedSharedLibInfos(scanResult)
+ val allowedInfos = mSharedLibrariesImpl.getAllowedSharedLibInfos(installRequest)
assertThat(allowedInfos).hasSize(1)
assertThat(allowedInfos[0].name).isEqualTo(TEST_LIB_NAME)
diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
index 4d03749d2759..48d6d9037e95 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
@@ -568,7 +568,6 @@ public class ScanTests {
private static void assertBasicPackageScanResult(
ScanResult scanResult, String packageName, boolean isInstant) {
- assertThat(scanResult.mSuccess, is(true));
final PackageSetting pkgSetting = scanResult.mPkgSetting;
assertBasicPackageSetting(scanResult, packageName, isInstant, pkgSetting);