[pm] merge CommitRequest, PrepareResult, ReconcileRequest into InstallRequest
BUG: 238678399 Test: atest com.android.server.pm.ScanTests Change-Id: I9f7d17d458318da89a6e47cdf9a0989825b1dbe5
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user