Merge "Make shared library dependencies explicit in SharedLibraryInfo"
This commit is contained in:
@@ -25,6 +25,7 @@ import android.os.Parcelable;
|
|||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -78,6 +79,7 @@ public final class SharedLibraryInfo implements Parcelable {
|
|||||||
private final @Type int mType;
|
private final @Type int mType;
|
||||||
private final VersionedPackage mDeclaringPackage;
|
private final VersionedPackage mDeclaringPackage;
|
||||||
private final List<VersionedPackage> mDependentPackages;
|
private final List<VersionedPackage> mDependentPackages;
|
||||||
|
private List<SharedLibraryInfo> mDependencies;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
@@ -91,7 +93,8 @@ public final class SharedLibraryInfo implements Parcelable {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public SharedLibraryInfo(String path, String packageName, String name, long version, int type,
|
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;
|
mPath = path;
|
||||||
mPackageName = packageName;
|
mPackageName = packageName;
|
||||||
mName = name;
|
mName = name;
|
||||||
@@ -99,11 +102,13 @@ public final class SharedLibraryInfo implements Parcelable {
|
|||||||
mType = type;
|
mType = type;
|
||||||
mDeclaringPackage = declaringPackage;
|
mDeclaringPackage = declaringPackage;
|
||||||
mDependentPackages = dependentPackages;
|
mDependentPackages = dependentPackages;
|
||||||
|
mDependencies = dependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SharedLibraryInfo(Parcel parcel) {
|
private SharedLibraryInfo(Parcel parcel) {
|
||||||
this(parcel.readString(), parcel.readString(), parcel.readString(), parcel.readLong(),
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -149,6 +154,47 @@ public final class SharedLibraryInfo implements Parcelable {
|
|||||||
return mPackageName;
|
return mPackageName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 Use {@link #getLongVersion()} instead.
|
||||||
*/
|
*/
|
||||||
@@ -232,6 +278,7 @@ public final class SharedLibraryInfo implements Parcelable {
|
|||||||
parcel.writeInt(mType);
|
parcel.writeInt(mType);
|
||||||
parcel.writeParcelable(mDeclaringPackage, flags);
|
parcel.writeParcelable(mDeclaringPackage, flags);
|
||||||
parcel.writeList(mDependentPackages);
|
parcel.writeList(mDependentPackages);
|
||||||
|
parcel.writeTypedList(mDependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String typeToString(int type) {
|
private static String typeToString(int type) {
|
||||||
|
|||||||
@@ -22,15 +22,15 @@ package android.content.pm;
|
|||||||
*/
|
*/
|
||||||
public class SharedLibraryNames {
|
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";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_DENIED;
|
||||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
import static android.content.pm.PackageParser.isApkFile;
|
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.Trace.TRACE_TAG_PACKAGE_MANAGER;
|
||||||
import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
|
import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
|
||||||
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
|
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.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Predicate;
|
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,
|
public PackageManagerService(Context context, Installer installer,
|
||||||
boolean factoryTest, boolean onlyCore) {
|
boolean factoryTest, boolean onlyCore) {
|
||||||
LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
|
LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
|
||||||
@@ -2496,6 +2524,9 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
|
addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
|
||||||
SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
|
SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
|
||||||
}
|
}
|
||||||
|
// Builtin libraries cannot encode their dependency where they are
|
||||||
|
// defined, so fix that now.
|
||||||
|
setupBuiltinSharedLibraryDependenciesLocked();
|
||||||
|
|
||||||
SELinuxMMAC.readInstallPolicy();
|
SELinuxMMAC.readInstallPolicy();
|
||||||
|
|
||||||
@@ -5057,7 +5088,10 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getPath(),
|
SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getPath(),
|
||||||
libInfo.getPackageName(), libInfo.getName(), libInfo.getLongVersion(),
|
libInfo.getPackageName(), libInfo.getName(), libInfo.getLongVersion(),
|
||||||
libInfo.getType(), libInfo.getDeclaringPackage(),
|
libInfo.getType(), libInfo.getDeclaringPackage(),
|
||||||
getPackagesUsingSharedLibraryLPr(libInfo, flags, userId));
|
getPackagesUsingSharedLibraryLPr(libInfo, flags, userId),
|
||||||
|
(libInfo.getDependencies() == null
|
||||||
|
? null
|
||||||
|
: new ArrayList(libInfo.getDependencies())));
|
||||||
|
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
result = new ArrayList<>();
|
result = new ArrayList<>();
|
||||||
@@ -9690,16 +9724,35 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSharedLibraryLPr(Set<String> usesLibraryFiles,
|
@GuardedBy("mPackages")
|
||||||
SharedLibraryInfo file,
|
private void applyDefiningSharedLibraryUpdateLocked(
|
||||||
PackageParser.Package changingLib) {
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (file.getPath() != null) {
|
@GuardedBy("mPackages")
|
||||||
usesLibraryFiles.add(file.getPath());
|
private void addSharedLibraryLPr(PackageParser.Package pkg, Set<String> usesLibraryFiles,
|
||||||
|
SharedLibraryInfo libInfo, PackageParser.Package changingLib) {
|
||||||
|
|
||||||
|
if (libInfo.getPath() != null) {
|
||||||
|
usesLibraryFiles.add(libInfo.getPath());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PackageParser.Package p = mPackages.get(file.getPackageName());
|
PackageParser.Package p = mPackages.get(libInfo.getPackageName());
|
||||||
if (changingLib != null && changingLib.packageName.equals(file.getPackageName())) {
|
if (changingLib != null && changingLib.packageName.equals(libInfo.getPackageName())) {
|
||||||
// If we are doing this while in the middle of updating a library apk,
|
// 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
|
// 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
|
// dependencies here. (We haven't yet finished committing the new apk
|
||||||
@@ -9710,6 +9763,10 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
}
|
}
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
usesLibraryFiles.addAll(p.getAllCodePaths());
|
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) {
|
if (p.usesLibraryFiles != null) {
|
||||||
Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
|
Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
|
||||||
}
|
}
|
||||||
@@ -9721,6 +9778,12 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
if (pkg == null) {
|
if (pkg == null) {
|
||||||
return;
|
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
|
// The collection used here must maintain the order of addition (so
|
||||||
// that libraries are searched in the correct order) and must have no
|
// that libraries are searched in the correct order) and must have no
|
||||||
// duplicates.
|
// duplicates.
|
||||||
@@ -9747,7 +9810,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
// usesLibraryFiles while eliminating duplicates.
|
// usesLibraryFiles while eliminating duplicates.
|
||||||
Set<String> usesLibraryFiles = new LinkedHashSet<>();
|
Set<String> usesLibraryFiles = new LinkedHashSet<>();
|
||||||
for (SharedLibraryInfo libInfo : usesLibraryInfos) {
|
for (SharedLibraryInfo libInfo : usesLibraryInfos) {
|
||||||
addSharedLibraryLPr(usesLibraryFiles, libInfo, changingLib);
|
addSharedLibraryLPr(pkg, usesLibraryFiles, libInfo, changingLib);
|
||||||
}
|
}
|
||||||
pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
|
pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
|
||||||
} else {
|
} else {
|
||||||
@@ -11265,7 +11328,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
}
|
}
|
||||||
SharedLibraryInfo libraryInfo = new SharedLibraryInfo(path, apk, name,
|
SharedLibraryInfo libraryInfo = new SharedLibraryInfo(path, apk, name,
|
||||||
version, type, new VersionedPackage(declaringPackageName, declaringVersionCode),
|
version, type, new VersionedPackage(declaringPackageName, declaringVersionCode),
|
||||||
null);
|
null, null);
|
||||||
versionedLib.put(version, libraryInfo);
|
versionedLib.put(version, libraryInfo);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -489,7 +489,7 @@ public class PackageParserTest {
|
|||||||
pkg.usesLibraryFiles = new String[] { "foo13"};
|
pkg.usesLibraryFiles = new String[] { "foo13"};
|
||||||
|
|
||||||
pkg.usesLibraryInfos = new ArrayList<>();
|
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 = new ArrayList<>();
|
||||||
pkg.mOriginalPackages.add("foo14");
|
pkg.mOriginalPackages.add("foo14");
|
||||||
|
|||||||
Reference in New Issue
Block a user