diff options
4 files changed, 129 insertions, 19 deletions
diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java index a8bbeab03f0a..096301c92faa 100644 --- a/core/java/android/content/pm/SharedLibraryInfo.java +++ b/core/java/android/content/pm/SharedLibraryInfo.java @@ -25,6 +25,7 @@ import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -78,6 +79,7 @@ public final class SharedLibraryInfo implements Parcelable { private final @Type int mType; private final VersionedPackage mDeclaringPackage; private final List<VersionedPackage> mDependentPackages; + private List<SharedLibraryInfo> mDependencies; /** * Creates a new instance. @@ -91,7 +93,8 @@ public final class SharedLibraryInfo implements Parcelable { * @hide */ public SharedLibraryInfo(String path, String packageName, String name, long version, int type, - VersionedPackage declaringPackage, List<VersionedPackage> dependentPackages) { + VersionedPackage declaringPackage, List<VersionedPackage> dependentPackages, + List<SharedLibraryInfo> dependencies) { mPath = path; mPackageName = packageName; mName = name; @@ -99,11 +102,13 @@ public final class SharedLibraryInfo implements Parcelable { mType = type; mDeclaringPackage = declaringPackage; mDependentPackages = dependentPackages; + mDependencies = dependencies; } private SharedLibraryInfo(Parcel parcel) { this(parcel.readString(), parcel.readString(), parcel.readString(), parcel.readLong(), - parcel.readInt(), parcel.readParcelable(null), parcel.readArrayList(null)); + parcel.readInt(), parcel.readParcelable(null), parcel.readArrayList(null), + parcel.createTypedArrayList(SharedLibraryInfo.CREATOR)); } /** @@ -150,6 +155,47 @@ public final class SharedLibraryInfo implements Parcelable { } /** + * Add a library dependency to that library. Note that this + * should be called under the package manager lock. + * + * @hide + */ + public void addDependency(@Nullable SharedLibraryInfo info) { + if (info == null) { + // For convenience of the caller, allow null to be passed. + // This can happen when we create the dependencies of builtin + // libraries. + return; + } + if (mDependencies == null) { + mDependencies = new ArrayList<>(); + } + mDependencies.add(info); + } + + /** + * Clear all dependencies. + * + * @hide + */ + public void clearDependencies() { + mDependencies = null; + } + + /** + * Gets the libraries this library directly depends on. Note that + * the package manager prevents recursive dependencies when installing + * a package. + * + * @return The dependencies. + * + * @hide + */ + public @Nullable List<SharedLibraryInfo> getDependencies() { + return mDependencies; + } + + /** * @deprecated Use {@link #getLongVersion()} instead. */ @Deprecated @@ -232,6 +278,7 @@ public final class SharedLibraryInfo implements Parcelable { parcel.writeInt(mType); parcel.writeParcelable(mDeclaringPackage, flags); parcel.writeList(mDependentPackages); + parcel.writeTypedList(mDependencies); } private static String typeToString(int type) { diff --git a/core/java/android/content/pm/SharedLibraryNames.java b/core/java/android/content/pm/SharedLibraryNames.java index 387d29e81dfc..5afc8a9721b4 100644 --- a/core/java/android/content/pm/SharedLibraryNames.java +++ b/core/java/android/content/pm/SharedLibraryNames.java @@ -22,15 +22,15 @@ package android.content.pm; */ public class SharedLibraryNames { - static final String ANDROID_HIDL_BASE = "android.hidl.base-V1.0-java"; + public static final String ANDROID_HIDL_BASE = "android.hidl.base-V1.0-java"; - static final String ANDROID_HIDL_MANAGER = "android.hidl.manager-V1.0-java"; + public static final String ANDROID_HIDL_MANAGER = "android.hidl.manager-V1.0-java"; - static final String ANDROID_TEST_BASE = "android.test.base"; + public static final String ANDROID_TEST_BASE = "android.test.base"; - static final String ANDROID_TEST_MOCK = "android.test.mock"; + public static final String ANDROID_TEST_MOCK = "android.test.mock"; - static final String ANDROID_TEST_RUNNER = "android.test.runner"; + public static final String ANDROID_TEST_RUNNER = "android.test.runner"; - static final String ORG_APACHE_HTTP_LEGACY = "org.apache.http.legacy"; + public static final String ORG_APACHE_HTTP_LEGACY = "org.apache.http.legacy"; } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 96c3c41e2e13..a3ca97be73c0 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -83,6 +83,11 @@ import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageParser.isApkFile; +import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_BASE; +import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_MANAGER; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_MOCK; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; import static android.os.storage.StorageManager.FLAG_STORAGE_CE; import static android.os.storage.StorageManager.FLAG_STORAGE_DE; @@ -367,6 +372,7 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiConsumer; import java.util.function.Predicate; /** @@ -2385,6 +2391,28 @@ public class PackageManagerService extends IPackageManager.Stub } } + @GuardedBy("mPackages") + private void setupBuiltinSharedLibraryDependenciesLocked() { + // Builtin libraries don't have versions. + long version = SharedLibraryInfo.VERSION_UNDEFINED; + + SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(ANDROID_HIDL_MANAGER, version); + if (libraryInfo != null) { + libraryInfo.addDependency(getSharedLibraryInfoLPr(ANDROID_HIDL_BASE, version)); + } + + libraryInfo = getSharedLibraryInfoLPr(ANDROID_TEST_RUNNER, version); + if (libraryInfo != null) { + libraryInfo.addDependency(getSharedLibraryInfoLPr(ANDROID_TEST_MOCK, version)); + libraryInfo.addDependency(getSharedLibraryInfoLPr(ANDROID_TEST_BASE, version)); + } + + libraryInfo = getSharedLibraryInfoLPr(ANDROID_TEST_MOCK, version); + if (libraryInfo != null) { + libraryInfo.addDependency(getSharedLibraryInfoLPr(ANDROID_TEST_BASE, version)); + } + } + public PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore) { LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES); @@ -2496,6 +2524,9 @@ public class PackageManagerService extends IPackageManager.Stub addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED, SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0); } + // Builtin libraries cannot encode their dependency where they are + // defined, so fix that now. + setupBuiltinSharedLibraryDependenciesLocked(); SELinuxMMAC.readInstallPolicy(); @@ -5057,7 +5088,10 @@ public class PackageManagerService extends IPackageManager.Stub SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getPath(), libInfo.getPackageName(), libInfo.getName(), libInfo.getLongVersion(), libInfo.getType(), libInfo.getDeclaringPackage(), - getPackagesUsingSharedLibraryLPr(libInfo, flags, userId)); + getPackagesUsingSharedLibraryLPr(libInfo, flags, userId), + (libInfo.getDependencies() == null + ? null + : new ArrayList(libInfo.getDependencies()))); if (result == null) { result = new ArrayList<>(); @@ -9690,16 +9724,35 @@ public class PackageManagerService extends IPackageManager.Stub } } - private void addSharedLibraryLPr(Set<String> usesLibraryFiles, - SharedLibraryInfo file, - PackageParser.Package changingLib) { + @GuardedBy("mPackages") + private void applyDefiningSharedLibraryUpdateLocked( + PackageParser.Package pkg, SharedLibraryInfo libInfo, + BiConsumer<SharedLibraryInfo, SharedLibraryInfo> action) { + if (pkg.isLibrary()) { + if (pkg.staticSharedLibName != null) { + SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr( + pkg.staticSharedLibName, pkg.staticSharedLibVersion); + action.accept(definedLibrary, libInfo); + } else { + for (String libraryName : pkg.libraryNames) { + SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr( + libraryName, SharedLibraryInfo.VERSION_UNDEFINED); + action.accept(definedLibrary, libInfo); + } + } + } + } + + @GuardedBy("mPackages") + private void addSharedLibraryLPr(PackageParser.Package pkg, Set<String> usesLibraryFiles, + SharedLibraryInfo libInfo, PackageParser.Package changingLib) { - if (file.getPath() != null) { - usesLibraryFiles.add(file.getPath()); + if (libInfo.getPath() != null) { + usesLibraryFiles.add(libInfo.getPath()); return; } - PackageParser.Package p = mPackages.get(file.getPackageName()); - if (changingLib != null && changingLib.packageName.equals(file.getPackageName())) { + PackageParser.Package p = mPackages.get(libInfo.getPackageName()); + if (changingLib != null && changingLib.packageName.equals(libInfo.getPackageName())) { // If we are doing this while in the middle of updating a library apk, // then we need to make sure to use that new apk for determining the // dependencies here. (We haven't yet finished committing the new apk @@ -9710,6 +9763,10 @@ public class PackageManagerService extends IPackageManager.Stub } if (p != null) { usesLibraryFiles.addAll(p.getAllCodePaths()); + // If the package provides libraries, add the dependency to them. + applyDefiningSharedLibraryUpdateLocked(pkg, libInfo, (definingLibrary, dependency) -> { + definingLibrary.addDependency(dependency); + }); if (p.usesLibraryFiles != null) { Collections.addAll(usesLibraryFiles, p.usesLibraryFiles); } @@ -9721,6 +9778,12 @@ public class PackageManagerService extends IPackageManager.Stub if (pkg == null) { return; } + + // If the package provides libraries, clear their old dependencies. + // This method will set them up again. + applyDefiningSharedLibraryUpdateLocked(pkg, null, (definingLibrary, dependency) -> { + definingLibrary.clearDependencies(); + }); // The collection used here must maintain the order of addition (so // that libraries are searched in the correct order) and must have no // duplicates. @@ -9747,7 +9810,7 @@ public class PackageManagerService extends IPackageManager.Stub // usesLibraryFiles while eliminating duplicates. Set<String> usesLibraryFiles = new LinkedHashSet<>(); for (SharedLibraryInfo libInfo : usesLibraryInfos) { - addSharedLibraryLPr(usesLibraryFiles, libInfo, changingLib); + addSharedLibraryLPr(pkg, usesLibraryFiles, libInfo, changingLib); } pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]); } else { @@ -11265,7 +11328,7 @@ public class PackageManagerService extends IPackageManager.Stub } SharedLibraryInfo libraryInfo = new SharedLibraryInfo(path, apk, name, version, type, new VersionedPackage(declaringPackageName, declaringVersionCode), - null); + null, null); versionedLib.put(version, libraryInfo); return true; } diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java index 952abfa2e99d..cdbc665dc0c2 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java @@ -489,7 +489,7 @@ public class PackageParserTest { pkg.usesLibraryFiles = new String[] { "foo13"}; pkg.usesLibraryInfos = new ArrayList<>(); - pkg.usesLibraryInfos.add(new SharedLibraryInfo(null, null, null, 0L, 0, null, null)); + pkg.usesLibraryInfos.add(new SharedLibraryInfo(null, null, null, 0L, 0, null, null, null)); pkg.mOriginalPackages = new ArrayList<>(); pkg.mOriginalPackages.add("foo14"); |