diff options
4 files changed, 84 insertions, 30 deletions
diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java index 5acebf54a159..d77b2f53fc5b 100644 --- a/core/java/android/content/pm/SharedLibraryInfo.java +++ b/core/java/android/content/pm/SharedLibraryInfo.java @@ -94,7 +94,7 @@ public final class SharedLibraryInfo implements Parcelable { private final String mPath; private final String mPackageName; private final String mName; - private final List<String> mCodePaths; + private List<String> mCodePaths; private final long mVersion; private final @Type int mType; @@ -282,6 +282,15 @@ public final class SharedLibraryInfo implements Parcelable { } /** + * Sets new all code paths for that library. + * + * @hide + */ + public void setAllCodePaths(List<String> paths) { + mCodePaths = paths; + } + + /** * Add a library dependency to that library. Note that this * should be called under the package manager lock. * diff --git a/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java b/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java index 12d326486e77..032ac4283712 100644 --- a/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java +++ b/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java @@ -3025,6 +3025,7 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, @Override public PackageImpl setSplitCodePaths(@Nullable String[] splitCodePaths) { this.splitCodePaths = splitCodePaths; + this.mSplits = null; // reset for paths changed if (splitCodePaths != null) { int size = splitCodePaths.length; for (int index = 0; index < size; index++) { diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index f449126af0f9..aca65bfd561c 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -1019,7 +1019,9 @@ final class InstallPackageHelper { && scanInstallPackages(requests, createdAppId, versionInfos)) { List<ReconciledPackage> reconciledPackages = reconcileInstallPackages(requests, versionInfos); - if (reconciledPackages != null && commitInstallPackages(reconciledPackages)) { + if (reconciledPackages != null + && renameAndUpdatePaths(requests) + && commitInstallPackages(reconciledPackages)) { success = true; } } @@ -1029,24 +1031,49 @@ final class InstallPackageHelper { } } - private boolean prepareInstallPackages(List<InstallRequest> requests) { - // TODO: will remove the locking after doRename is moved out of prepare + private boolean renameAndUpdatePaths(List<InstallRequest> requests) { try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) { for (InstallRequest request : requests) { + ParsedPackage parsedPackage = request.getParsedPackage(); + final boolean isApex = (request.getScanFlags() & SCAN_AS_APEX) != 0; + if (isApex) { + continue; + } try { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage"); - request.onPrepareStarted(); - preparePackageLI(request); - } catch (PrepareFailure prepareFailure) { - request.setError(prepareFailure.error, - prepareFailure.getMessage()); - request.setOriginPackage(prepareFailure.mConflictingPackage); - request.setOriginPermission(prepareFailure.mConflictingPermission); + doRenameLI(request, parsedPackage); + setUpFsVerity(parsedPackage); + } catch (Installer.InstallerException | IOException | DigestException + | NoSuchAlgorithmException | PrepareFailure e) { + request.setError(PackageManagerException.INTERNAL_ERROR_VERITY_SETUP, + "Failed to set up verity: " + e); return false; - } finally { - request.onPrepareFinished(); - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } + + // update paths that are set before renaming + PackageSetting scannedPackageSetting = request.getScannedPackageSetting(); + scannedPackageSetting.setPath(new File(parsedPackage.getPath())); + scannedPackageSetting.setLegacyNativeLibraryPath( + parsedPackage.getNativeLibraryRootDir()); + } + return true; + } + } + + private boolean prepareInstallPackages(List<InstallRequest> requests) { + for (InstallRequest request : requests) { + try { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage"); + request.onPrepareStarted(); + preparePackage(request); + } catch (PrepareFailure prepareFailure) { + request.setError(prepareFailure.error, + prepareFailure.getMessage()); + request.setOriginPackage(prepareFailure.mConflictingPackage); + request.setOriginPermission(prepareFailure.mConflictingPermission); + return false; + } finally { + request.onPrepareFinished(); + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } } return true; @@ -1231,8 +1258,7 @@ final class InstallPackageHelper { return newProp != null && newProp.getBoolean(); } - @GuardedBy("mPm.mInstallLock") - private void preparePackageLI(InstallRequest request) throws PrepareFailure { + private void preparePackage(InstallRequest request) throws PrepareFailure { final int[] allUsers = mPm.mUserManager.getUserIds(); final int installFlags = request.getInstallFlags(); final boolean onExternal = request.getVolumeUuid() != null; @@ -1739,18 +1765,7 @@ final class InstallPackageHelper { } } - if (!isApex) { - doRenameLI(request, parsedPackage); - - try { - setUpFsVerity(parsedPackage); - } catch (Installer.InstallerException | IOException | DigestException - | NoSuchAlgorithmException e) { - throw PrepareFailure.ofInternalError( - "Failed to set up verity: " + e, - PackageManagerException.INTERNAL_ERROR_VERITY_SETUP); - } - } else { + if (isApex) { // Use the path returned by apexd parsedPackage.setPath(request.getApexInfo().modulePath); parsedPackage.setBaseApkPath(request.getApexInfo().modulePath); @@ -2092,7 +2107,21 @@ final class InstallPackageHelper { // Reflect the rename in scanned details try { - parsedPackage.setPath(afterCodeFile.getCanonicalPath()); + String afterCanonicalPath = afterCodeFile.getCanonicalPath(); + String beforeCanonicalPath = beforeCodeFile.getCanonicalPath(); + parsedPackage.setPath(afterCanonicalPath); + + parsedPackage.setNativeLibraryDir( + parsedPackage.getNativeLibraryDir() + .replace(beforeCanonicalPath, afterCanonicalPath)); + parsedPackage.setNativeLibraryRootDir( + parsedPackage.getNativeLibraryRootDir() + .replace(beforeCanonicalPath, afterCanonicalPath)); + String secondaryNativeLibraryDir = parsedPackage.getSecondaryNativeLibraryDir(); + if (secondaryNativeLibraryDir != null) { + parsedPackage.setSecondaryNativeLibraryDir( + secondaryNativeLibraryDir.replace(beforeCanonicalPath, afterCanonicalPath)); + } } catch (IOException e) { Slog.e(TAG, "Failed to get path: " + afterCodeFile, e); throw new PrepareFailure(PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE, @@ -2102,6 +2131,7 @@ final class InstallPackageHelper { afterCodeFile, parsedPackage.getBaseApkPath())); parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, parsedPackage.getSplitCodePaths())); + request.updateAllCodePaths(AndroidPackageUtils.getAllCodePaths(parsedPackage)); } // TODO(b/168126411): Once staged install flow starts using the same folder as non-staged diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java index ae7749b7dfe1..1f79ac0afdac 100644 --- a/services/core/java/com/android/server/pm/InstallRequest.java +++ b/services/core/java/com/android/server/pm/InstallRequest.java @@ -615,6 +615,20 @@ final class InstallRequest { return mScanResult.mDynamicSharedLibraryInfos; } + public void updateAllCodePaths(List<String> paths) { + if (mScanResult.mSdkSharedLibraryInfo != null) { + mScanResult.mSdkSharedLibraryInfo.setAllCodePaths(paths); + } + if (mScanResult.mStaticSharedLibraryInfo != null) { + mScanResult.mStaticSharedLibraryInfo.setAllCodePaths(paths); + } + if (mScanResult.mDynamicSharedLibraryInfos != null) { + for (SharedLibraryInfo info : mScanResult.mDynamicSharedLibraryInfos) { + info.setAllCodePaths(paths); + } + } + } + @Nullable public PackageSetting getScannedPackageSetting() { assertScanResultExists(); |