Merge "Introduce uses-native-library tag"

This commit is contained in:
Jiyong Park
2020-07-23 08:56:41 +00:00
committed by Android (Google) Code Review
16 changed files with 343 additions and 26 deletions

View File

@@ -48,17 +48,18 @@ public class ApplicationLoaders {
ClassLoader parent, String classLoaderName) {
return getClassLoaderWithSharedLibraries(zip, targetSdkVersion, isBundled,
librarySearchPath, libraryPermittedPath, parent, classLoaderName,
null);
null, null);
}
ClassLoader getClassLoaderWithSharedLibraries(
String zip, int targetSdkVersion, boolean isBundled,
String librarySearchPath, String libraryPermittedPath,
ClassLoader parent, String classLoaderName,
List<ClassLoader> sharedLibraries) {
List<ClassLoader> sharedLibraries, List<String> nativeSharedLibraries) {
// For normal usage the cache key used is the same as the zip path.
return getClassLoader(zip, targetSdkVersion, isBundled, librarySearchPath,
libraryPermittedPath, parent, zip, classLoaderName, sharedLibraries);
libraryPermittedPath, parent, zip, classLoaderName, sharedLibraries,
nativeSharedLibraries);
}
/**
@@ -77,14 +78,22 @@ public class ApplicationLoaders {
return loader;
}
// TODO(b/142191088): allow (Java) shared libraries to have <uses-native-library>
// Until that is supported, assume that all native shared libraries are used.
// "ALL" is a magic string that libnativeloader uses to unconditionally add all available
// native shared libraries to the classloader.
List<String> nativeSharedLibraries = new ArrayList<>();
nativeSharedLibraries.add("ALL");
return getClassLoaderWithSharedLibraries(zip, targetSdkVersion, isBundled,
librarySearchPath, libraryPermittedPath, parent, classLoaderName, sharedLibraries);
librarySearchPath, libraryPermittedPath, parent, classLoaderName, sharedLibraries,
nativeSharedLibraries);
}
private ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled,
String librarySearchPath, String libraryPermittedPath,
ClassLoader parent, String cacheKey,
String classLoaderName, List<ClassLoader> sharedLibraries) {
String classLoaderName, List<ClassLoader> sharedLibraries,
List<String> nativeSharedLibraries) {
/*
* This is the parent we use if they pass "null" in. In theory
* this should be the "system" class loader; in practice we
@@ -113,7 +122,8 @@ public class ApplicationLoaders {
ClassLoader classloader = ClassLoaderFactory.createClassLoader(
zip, librarySearchPath, libraryPermittedPath, parent,
targetSdkVersion, isBundled, classLoaderName, sharedLibraries);
targetSdkVersion, isBundled, classLoaderName, sharedLibraries,
nativeSharedLibraries);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
@@ -185,7 +195,8 @@ public class ApplicationLoaders {
// assume cached libraries work with current sdk since they are built-in
ClassLoader classLoader = getClassLoader(path, Build.VERSION.SDK_INT, true /*isBundled*/,
null /*librarySearchPath*/, null /*libraryPermittedPath*/, null /*parent*/,
null /*cacheKey*/, null /*classLoaderName*/, sharedLibraries /*sharedLibraries*/);
null /*cacheKey*/, null /*classLoaderName*/, sharedLibraries /*sharedLibraries*/,
null /* nativeSharedLibraries */);
if (classLoader == null) {
// bad configuration or break in classloading code
@@ -255,7 +266,8 @@ public class ApplicationLoaders {
// The cache key is passed separately to enable the stub WebView to be cached under the
// stub's APK path, when the actual package path is the donor APK.
return getClassLoader(packagePath, Build.VERSION.SDK_INT, false, libsPath, null, null,
cacheKey, null /* classLoaderName */, null /* sharedLibraries */);
cacheKey, null /* classLoaderName */, null /* sharedLibraries */,
null /* nativeSharedLibraries */);
}
/**

View File

@@ -412,6 +412,12 @@ public final class LoadedApk {
return;
}
for (SharedLibraryInfo lib : sharedLibraries) {
if (lib.isNative()) {
// Native shared lib doesn't contribute to the native lib search path. Its name is
// sent to libnativeloader and then the native shared lib is exported from the
// default linker namespace.
continue;
}
List<String> paths = lib.getAllCodePaths();
outSeenPaths.addAll(paths);
for (String path : paths) {
@@ -696,6 +702,12 @@ public final class LoadedApk {
}
List<ClassLoader> loaders = new ArrayList<>();
for (SharedLibraryInfo info : sharedLibraries) {
if (info.isNative()) {
// Native shared lib doesn't contribute to the native lib search path. Its name is
// sent to libnativeloader and then the native shared lib is exported from the
// default linker namespace.
continue;
}
loaders.add(createSharedLibraryLoader(
info, isBundledApp, librarySearchPath, libraryPermittedPath));
}
@@ -898,10 +910,19 @@ public final class LoadedApk {
mApplicationInfo.sharedLibraryInfos, isBundledApp, librarySearchPath,
libraryPermittedPath);
List<String> nativeSharedLibraries = new ArrayList<>();
if (mApplicationInfo.sharedLibraryInfos != null) {
for (SharedLibraryInfo info : mApplicationInfo.sharedLibraryInfos) {
if (info.isNative()) {
nativeSharedLibraries.add(info.getName());
}
}
}
mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries(
zip, mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
libraryPermittedPath, mBaseClassLoader,
mApplicationInfo.classLoaderName, sharedLibraries);
mApplicationInfo.classLoaderName, sharedLibraries, nativeSharedLibraries);
mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
setThreadPolicy(oldPolicy);

View File

@@ -79,6 +79,7 @@ public final class SharedLibraryInfo implements Parcelable {
private final long mVersion;
private final @Type int mType;
private final boolean mIsNative;
private final VersionedPackage mDeclaringPackage;
private final List<VersionedPackage> mDependentPackages;
private List<SharedLibraryInfo> mDependencies;
@@ -93,13 +94,14 @@ public final class SharedLibraryInfo implements Parcelable {
* @param type The lib type.
* @param declaringPackage The package that declares the library.
* @param dependentPackages The packages that depend on the library.
* @param isNative indicate if this shared lib is a native lib or not (i.e. java)
*
* @hide
*/
public SharedLibraryInfo(String path, String packageName, List<String> codePaths,
String name, long version, int type,
VersionedPackage declaringPackage, List<VersionedPackage> dependentPackages,
List<SharedLibraryInfo> dependencies) {
List<SharedLibraryInfo> dependencies, boolean isNative) {
mPath = path;
mPackageName = packageName;
mCodePaths = codePaths;
@@ -109,6 +111,16 @@ public final class SharedLibraryInfo implements Parcelable {
mDeclaringPackage = declaringPackage;
mDependentPackages = dependentPackages;
mDependencies = dependencies;
mIsNative = isNative;
}
/** @hide */
public SharedLibraryInfo(String path, String packageName, List<String> codePaths,
String name, long version, int type,
VersionedPackage declaringPackage, List<VersionedPackage> dependentPackages,
List<SharedLibraryInfo> dependencies) {
this(path, packageName, codePaths, name, version, type, declaringPackage, dependentPackages,
dependencies, false /* isNative */);
}
private SharedLibraryInfo(Parcel parcel) {
@@ -125,6 +137,7 @@ public final class SharedLibraryInfo implements Parcelable {
mDeclaringPackage = parcel.readParcelable(null);
mDependentPackages = parcel.readArrayList(null);
mDependencies = parcel.createTypedArrayList(SharedLibraryInfo.CREATOR);
mIsNative = parcel.readBoolean();
}
/**
@@ -136,6 +149,15 @@ public final class SharedLibraryInfo implements Parcelable {
return mType;
}
/**
* Tells whether this library is a native shared library or not.
*
* @hide
*/
public boolean isNative() {
return mIsNative;
}
/**
* Gets the library name an app defines in its manifest
* to depend on the library.
@@ -320,6 +342,7 @@ public final class SharedLibraryInfo implements Parcelable {
parcel.writeParcelable(mDeclaringPackage, flags);
parcel.writeList(mDependentPackages);
parcel.writeTypedList(mDependencies);
parcel.writeBoolean(mIsNative);
}
private static String typeToString(int type) {

View File

@@ -92,6 +92,10 @@ public interface ParsingPackage extends ParsingPackageRead {
ParsingPackage addUsesOptionalLibrary(String libraryName);
ParsingPackage addUsesNativeLibrary(String libraryName);
ParsingPackage addUsesOptionalNativeLibrary(String libraryName);
ParsingPackage addUsesStaticLibrary(String libraryName);
ParsingPackage addUsesStaticLibraryCertDigests(String[] certSha256Digests);
@@ -219,6 +223,8 @@ public interface ParsingPackage extends ParsingPackageRead {
ParsingPackage removeUsesOptionalLibrary(String libraryName);
ParsingPackage removeUsesOptionalNativeLibrary(String libraryName);
ParsingPackage setAnyDensity(int anyDensity);
ParsingPackage setAppComponentFactory(String appComponentFactory);

View File

@@ -184,6 +184,13 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
@DataClass.ParcelWith(ForInternedStringList.class)
protected List<String> usesOptionalLibraries = emptyList();
@NonNull
@DataClass.ParcelWith(ForInternedStringList.class)
protected List<String> usesNativeLibraries = emptyList();
@NonNull
@DataClass.ParcelWith(ForInternedStringList.class)
protected List<String> usesOptionalNativeLibraries = emptyList();
@NonNull
@DataClass.ParcelWith(ForInternedStringList.class)
private List<String> usesStaticLibraries = emptyList();
@@ -668,6 +675,27 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
return this;
}
@Override
public final ParsingPackageImpl addUsesOptionalNativeLibrary(String libraryName) {
this.usesOptionalNativeLibraries = CollectionUtils.add(this.usesOptionalNativeLibraries,
TextUtils.safeIntern(libraryName));
return this;
}
@Override
public final ParsingPackageImpl addUsesNativeLibrary(String libraryName) {
this.usesNativeLibraries = CollectionUtils.add(this.usesNativeLibraries,
TextUtils.safeIntern(libraryName));
return this;
}
@Override public ParsingPackageImpl removeUsesOptionalNativeLibrary(String libraryName) {
this.usesOptionalNativeLibraries = CollectionUtils.remove(this.usesOptionalNativeLibraries,
libraryName);
return this;
}
@Override
public ParsingPackageImpl addUsesStaticLibrary(String libraryName) {
this.usesStaticLibraries = CollectionUtils.add(this.usesStaticLibraries,
@@ -982,6 +1010,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
sForInternedStringList.parcel(this.libraryNames, dest, flags);
sForInternedStringList.parcel(this.usesLibraries, dest, flags);
sForInternedStringList.parcel(this.usesOptionalLibraries, dest, flags);
sForInternedStringList.parcel(this.usesNativeLibraries, dest, flags);
sForInternedStringList.parcel(this.usesOptionalNativeLibraries, dest, flags);
sForInternedStringList.parcel(this.usesStaticLibraries, dest, flags);
dest.writeLongArray(this.usesStaticLibrariesVersions);
@@ -1144,6 +1174,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
this.libraryNames = sForInternedStringList.unparcel(in);
this.usesLibraries = sForInternedStringList.unparcel(in);
this.usesOptionalLibraries = sForInternedStringList.unparcel(in);
this.usesNativeLibraries = sForInternedStringList.unparcel(in);
this.usesOptionalNativeLibraries = sForInternedStringList.unparcel(in);
this.usesStaticLibraries = sForInternedStringList.unparcel(in);
this.usesStaticLibrariesVersions = in.createLongArray();
@@ -1415,6 +1447,18 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
return usesOptionalLibraries;
}
@NonNull
@Override
public List<String> getUsesNativeLibraries() {
return usesNativeLibraries;
}
@NonNull
@Override
public List<String> getUsesOptionalNativeLibraries() {
return usesOptionalNativeLibraries;
}
@NonNull
@Override
public List<String> getUsesStaticLibraries() {

View File

@@ -230,6 +230,19 @@ public interface ParsingPackageRead extends Parcelable {
@NonNull
List<String> getUsesOptionalLibraries();
/** @see R.styleabele#AndroidManifestUsesNativeLibrary */
@NonNull
List<String> getUsesNativeLibraries();
/**
* Like {@link #getUsesNativeLibraries()}, but marked optional by setting
* {@link R.styleable#AndroidManifestUsesNativeLibrary_required} to false . Application is
* expected to handle absence manually.
* @see R.styleable#AndroidManifestUsesNativeLibrary
*/
@NonNull
List<String> getUsesOptionalNativeLibraries();
/**
* TODO(b/135203078): Move static library stuff to an inner data class
* @see R.styleable#AndroidManifestUsesStaticLibrary

View File

@@ -701,6 +701,8 @@ public class ParsingPackageUtils {
return parseUsesStaticLibrary(input, pkg, res, parser);
case "uses-library":
return parseUsesLibrary(input, pkg, res, parser);
case "uses-native-library":
return parseUsesNativeLibrary(input, pkg, res, parser);
case "uses-package":
// Dependencies for app installers; we don't currently try to
// enforce this.
@@ -2017,6 +2019,8 @@ public class ParsingPackageUtils {
return parseUsesStaticLibrary(input, pkg, res, parser);
case "uses-library":
return parseUsesLibrary(input, pkg, res, parser);
case "uses-native-library":
return parseUsesNativeLibrary(input, pkg, res, parser);
case "processes":
return parseProcesses(input, pkg, res, parser, mSeparateProcesses, flags);
case "uses-package":
@@ -2177,6 +2181,37 @@ public class ParsingPackageUtils {
}
}
@NonNull
private static ParseResult<ParsingPackage> parseUsesNativeLibrary(ParseInput input,
ParsingPackage pkg, Resources res, XmlResourceParser parser) {
TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesNativeLibrary);
try {
// Note: don't allow this value to be a reference to a resource
// that may change.
String lname = sa.getNonResourceString(
R.styleable.AndroidManifestUsesNativeLibrary_name);
boolean req = sa.getBoolean(R.styleable.AndroidManifestUsesNativeLibrary_required,
true);
if (lname != null) {
if (req) {
// Upgrade to treat as stronger constraint
pkg.addUsesNativeLibrary(lname)
.removeUsesOptionalNativeLibrary(lname);
} else {
// Ignore if someone already defined as required
if (!ArrayUtils.contains(pkg.getUsesNativeLibraries(), lname)) {
pkg.addUsesOptionalNativeLibrary(lname);
}
}
}
return input.success(pkg);
} finally {
sa.recycle();
}
}
@NonNull
private static ParseResult<ParsingPackage> parseProcesses(ParseInput input, ParsingPackage pkg,
Resources res, XmlResourceParser parser, String[] separateProcesses, int flags)

View File

@@ -101,7 +101,7 @@ public class ClassLoaderFactory {
String librarySearchPath, String libraryPermittedPath, ClassLoader parent,
int targetSdkVersion, boolean isNamespaceShared, String classLoaderName) {
return createClassLoader(dexPath, librarySearchPath, libraryPermittedPath,
parent, targetSdkVersion, isNamespaceShared, classLoaderName, null);
parent, targetSdkVersion, isNamespaceShared, classLoaderName, null, null);
}
@@ -111,18 +111,24 @@ public class ClassLoaderFactory {
public static ClassLoader createClassLoader(String dexPath,
String librarySearchPath, String libraryPermittedPath, ClassLoader parent,
int targetSdkVersion, boolean isNamespaceShared, String classLoaderName,
List<ClassLoader> sharedLibraries) {
List<ClassLoader> sharedLibraries, List<String> nativeSharedLibraries) {
final ClassLoader classLoader = createClassLoader(dexPath, librarySearchPath, parent,
classLoaderName, sharedLibraries);
String sonameList = "";
if (nativeSharedLibraries != null) {
sonameList = String.join(":", nativeSharedLibraries);
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "createClassloaderNamespace");
String errorMessage = createClassloaderNamespace(classLoader,
targetSdkVersion,
librarySearchPath,
libraryPermittedPath,
isNamespaceShared,
dexPath);
dexPath,
sonameList);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
if (errorMessage != null) {
@@ -139,5 +145,6 @@ public class ClassLoaderFactory {
String librarySearchPath,
String libraryPermittedPath,
boolean isNamespaceShared,
String dexPath);
String dexPath,
String sonameList);
}

View File

@@ -49,10 +49,12 @@ import libcore.io.IoUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -104,11 +106,17 @@ public class SystemConfig {
public final String name;
public final String filename;
public final String[] dependencies;
public final boolean isNative;
SharedLibraryEntry(String name, String filename, String[] dependencies) {
this(name, filename, dependencies, false /* isNative */);
}
SharedLibraryEntry(String name, String filename, String[] dependencies, boolean isNative) {
this.name = name;
this.filename = filename;
this.dependencies = dependencies;
this.isNative = isNative;
}
}
@@ -457,6 +465,7 @@ public class SystemConfig {
log.traceBegin("readAllPermissions");
try {
readAllPermissions();
readPublicNativeLibrariesList();
} finally {
log.traceEnd();
}
@@ -1513,6 +1522,37 @@ public class SystemConfig {
}
}
private void readPublicNativeLibrariesList() {
readPublicLibrariesListFile(new File("/vendor/etc/public.libraries.txt"));
String[] dirs = {"/system/etc", "/system_ext/etc", "/product/etc"};
for (String dir : dirs) {
for (File f : (new File(dir)).listFiles()) {
String name = f.getName();
if (name.startsWith("public.libraries-") && name.endsWith(".txt")) {
readPublicLibrariesListFile(f);
}
}
}
}
private void readPublicLibrariesListFile(File listFile) {
try (BufferedReader br = new BufferedReader(new FileReader(listFile))) {
String line;
while ((line = br.readLine()) != null) {
if (line.isEmpty() || line.startsWith("#")) {
continue;
}
// Line format is <soname> [abi]. We take the soname part.
String soname = line.trim().split(" ")[0];
SharedLibraryEntry entry = new SharedLibraryEntry(
soname, soname, new String[0], true);
mSharedLibraries.put(entry.name, entry);
}
} catch (IOException e) {
Slog.w(TAG, "Failed to read public libraries file " + listFile, e);
}
}
private static boolean isSystemProcess() {
return Process.myUid() == Process.SYSTEM_UID;
}

View File

@@ -28,16 +28,19 @@ static jstring createClassloaderNamespace_native(JNIEnv* env,
jstring librarySearchPath,
jstring libraryPermittedPath,
jboolean isShared,
jstring dexPath) {
jstring dexPath,
jstring sonameList) {
return android::CreateClassLoaderNamespace(env, targetSdkVersion,
classLoader, isShared == JNI_TRUE,
dexPath,
librarySearchPath, libraryPermittedPath);
librarySearchPath,
libraryPermittedPath,
sonameList);
}
static const JNINativeMethod g_methods[] = {
{ "createClassloaderNamespace",
"(Ljava/lang/ClassLoader;ILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;)Ljava/lang/String;",
"(Ljava/lang/ClassLoader;ILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
reinterpret_cast<void*>(createClassloaderNamespace_native) },
};

View File

@@ -2173,6 +2173,29 @@
<attr name="required" />
</declare-styleable>
<!-- The <code>uses-native-library</code> specifies a native shared library that this
package requires to be linked against. Specifying this flag tells the
system to make the native library to be available to your app.
<p>On devices running R or lower, this is ignored and the app has access to all
the public native shared libraries that are exported from the platform. This is
also ignored if the app is targeting R or lower.
<p>This appears as a child tag of the
{@link #AndroidManifestApplication application} tag. -->
<declare-styleable name="AndroidManifestUsesNativeLibrary" parent="AndroidManifestApplication">
<!-- Required name of the library you use. -->
<attr name="name" />
<!-- Specify whether this native library is required for the application.
The default is true, meaning the application requires the
library, and does not want to be installed on devices that
don't support it. If you set this to false, then this will
allow the application to be installed even if the library
doesn't exist, and you will need to check for its presence
dynamically at runtime. -->
<attr name="required" />
</declare-styleable>
<!-- The <code>uses-static-library</code> specifies a shared <strong>static</strong>
library that this package requires to be statically linked against. Specifying
this tag tells the system to include this library's code in your class loader.

View File

@@ -651,6 +651,23 @@ public class PackageManagerService extends IPackageManager.Stub
private static final long THROW_EXCEPTION_ON_REQUIRE_INSTALL_PACKAGES_TO_ADD_INSTALLER_PACKAGE =
150857253;
/**
* Apps targeting Android S and above need to declare dependencies to the public native
* shared libraries that are defined by the device maker using {@code uses-native-library} tag
* in its {@code AndroidManifest.xml}.
*
* If any of the dependencies cannot be satisfied, i.e. one of the dependency doesn't exist,
* the package manager rejects to install the app. The dependency can be specified as optional
* using {@code android:required} attribute in the tag, in which case failing to satisfy the
* dependency doesn't stop the installation.
* <p>Once installed, an app is provided with only the native shared libraries that are
* specified in the app manifest. {@code dlopen}ing a native shared library that doesn't appear
* in the app manifest will fail even if it actually exists on the device.
*/
@ChangeId
@EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
private static final long ENFORCE_NATIVE_SHARED_LIBRARY_DEPENDENCIES = 142191088;
public static final String PLATFORM_PACKAGE_NAME = "android";
private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
@@ -2952,9 +2969,8 @@ public class PackageManagerService extends IPackageManager.Stub
= systemConfig.getSharedLibraries();
final int builtInLibCount = libConfig.size();
for (int i = 0; i < builtInLibCount; i++) {
String name = libConfig.keyAt(i);
SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
addBuiltInSharedLibraryLocked(entry.filename, name);
addBuiltInSharedLibraryLocked(libConfig.valueAt(i));
}
// Now that we have added all the libraries, iterate again to add dependency
@@ -10486,6 +10502,19 @@ public class PackageManagerService extends IPackageManager.Stub
null, null, pkg.getPackageName(), false, pkg.getTargetSdkVersion(),
usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
}
// TODO(b/160928779) gate this behavior using ENFORCE_NATIVE_SHARED_LIBRARY_DEPENDENCIES
if (pkg.getTargetSdkVersion() > 30) {
if (!pkg.getUsesNativeLibraries().isEmpty() && pkg.getTargetSdkVersion() > 30) {
usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesNativeLibraries(), null,
null, pkg.getPackageName(), true, pkg.getTargetSdkVersion(),
usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
}
if (!pkg.getUsesOptionalNativeLibraries().isEmpty()) {
usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalNativeLibraries(),
null, null, pkg.getPackageName(), false, pkg.getTargetSdkVersion(),
usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
}
}
return usesLibraryInfos;
}
@@ -12177,15 +12206,16 @@ public class PackageManagerService extends IPackageManager.Stub
}
@GuardedBy("mLock")
private boolean addBuiltInSharedLibraryLocked(String path, String name) {
if (nonStaticSharedLibExistsLocked(name)) {
private boolean addBuiltInSharedLibraryLocked(SystemConfig.SharedLibraryEntry entry) {
if (nonStaticSharedLibExistsLocked(entry.name)) {
return false;
}
SharedLibraryInfo libraryInfo = new SharedLibraryInfo(path, null, null, name,
(long) SharedLibraryInfo.VERSION_UNDEFINED, SharedLibraryInfo.TYPE_BUILTIN,
new VersionedPackage(PLATFORM_PACKAGE_NAME, (long) 0),
null, null);
SharedLibraryInfo libraryInfo = new SharedLibraryInfo(entry.filename, null, null,
entry.name, (long) SharedLibraryInfo.VERSION_UNDEFINED,
SharedLibraryInfo.TYPE_BUILTIN,
new VersionedPackage(PLATFORM_PACKAGE_NAME, (long)0), null, null,
entry.isNative);
commitSharedLibraryInfoLocked(libraryInfo);
return true;
@@ -21900,7 +21930,11 @@ public class PackageManagerService extends IPackageManager.Stub
pw.print(" -> ");
}
if (libraryInfo.getPath() != null) {
pw.print(" (jar) ");
if (libraryInfo.isNative()) {
pw.print(" (so) ");
} else {
pw.print(" (jar) ");
}
pw.print(libraryInfo.getPath());
} else {
pw.print(" (apk) ");

View File

@@ -4784,6 +4784,23 @@ public final class Settings {
}
}
List<String> usesNativeLibraries = pkg.getUsesNativeLibraries();
if (usesNativeLibraries.size() > 0) {
pw.print(prefix); pw.println(" usesNativeLibraries:");
for (int i=0; i< usesNativeLibraries.size(); i++) {
pw.print(prefix); pw.print(" "); pw.println(usesNativeLibraries.get(i));
}
}
List<String> usesOptionalNativeLibraries = pkg.getUsesOptionalNativeLibraries();
if (usesOptionalNativeLibraries.size() > 0) {
pw.print(prefix); pw.println(" usesOptionalNativeLibraries:");
for (int i=0; i< usesOptionalNativeLibraries.size(); i++) {
pw.print(prefix); pw.print(" ");
pw.println(usesOptionalNativeLibraries.get(i));
}
}
List<String> usesLibraryFiles = ps.getPkgState().getUsesLibraryFiles();
if (usesLibraryFiles.size() > 0) {
pw.print(prefix); pw.println(" usesLibraryFiles:");

View File

@@ -252,6 +252,19 @@ public interface AndroidPackage extends PkgAppInfo, PkgPackageInfo, ParsingPacka
@NonNull
List<String> getUsesOptionalLibraries();
/** @see R.styleabele#AndroidManifestUsesNativeLibrary */
@NonNull
List<String> getUsesNativeLibraries();
/**
* Like {@link #getUsesNativeLibraries()}, but marked optional by setting
* {@link R.styleable#AndroidManifestUsesNativeLibrary_required} to false . Application is
* expected to handle absence manually.
* @see R.styleable#AndroidManifestUsesNativeLibrary
*/
@NonNull
List<String> getUsesOptionalNativeLibraries();
/**
* TODO(b/135203078): Move static library stuff to an inner data class
* @see R.styleable#AndroidManifestUsesStaticLibrary

View File

@@ -1405,6 +1405,29 @@ class UsesStaticLibrary : public ManifestExtractor::Element {
}
};
/** Represents <uses-native-library> elements. **/
class UsesNativeLibrary : public ManifestExtractor::Element {
public:
UsesNativeLibrary() = default;
std::string name;
int required;
void Extract(xml::Element* element) override {
auto parent_stack = extractor()->parent_stack();
if (parent_stack.size() > 0 && ElementCast<Application>(parent_stack[0])) {
name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), "");
required = GetAttributeIntegerDefault(FindAttribute(element, REQUIRED_ATTR), 1);
}
}
void Print(text::Printer* printer) override {
if (!name.empty()) {
printer->Print(StringPrintf("uses-native-library%s:'%s'\n",
(required == 0) ? "-not-required" : "", name.data()));
}
}
};
/**
* Represents <meta-data> elements. These tags are only printed when a flag is passed in to
* explicitly enable meta data printing.
@@ -2245,6 +2268,7 @@ T* ElementCast(ManifestExtractor::Element* element) {
{"uses-static-library", std::is_base_of<UsesStaticLibrary, T>::value},
{"additional-certificate", std::is_base_of<AdditionalCertificate, T>::value},
{"uses-sdk", std::is_base_of<UsesSdkBadging, T>::value},
{"uses-native-library", std::is_base_of<UsesNativeLibrary, T>::value},
};
auto check = kTagCheck.find(element->tag());
@@ -2295,6 +2319,7 @@ std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Element::Inflate(
{"uses-package", &CreateType<UsesPackage>},
{"additional-certificate", &CreateType<AdditionalCertificate>},
{"uses-sdk", &CreateType<UsesSdkBadging>},
{"uses-native-library", &CreateType<UsesNativeLibrary>},
};
// Attempt to map the xml tag to a element inflater

View File

@@ -422,6 +422,7 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
application_action.Action(OptionalNameIsJavaClassName);
application_action["uses-library"].Action(RequiredNameIsNotEmpty);
application_action["uses-native-library"].Action(RequiredNameIsNotEmpty);
application_action["library"].Action(RequiredNameIsNotEmpty);
application_action["profileable"];