From 6a5b8b1f6db172b5aaadcec0c3868e54e214b675 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Tue, 30 Jun 2020 13:23:36 +0900 Subject: Introduce uses-native-library tag Since Android 7.0, partners were able to export some of their native shared libraries to apps. So far, the native libraries were provided to all apps regardless of whether they are actually needed or not. Even worse, it was impossible to prevent the installation of an app to the device where the some (or all) of the required native libs don't exist; the apps had to manually handle the case, which sometimes impossible when the dependency is so fundamental. This change introduces a new tag to the app manifest. Similary to the existing tag which is for (java) shared libraries, the new tag is used to describe the depedencies to the native shared libraries. Apps targeting Android S or higher are required to use the tag to import the native shared libraries. Libraries that are not depended on won't be available to the app even if the libraries are listed in the public.libraries*.txt files. Furthermore, when the dependency can't be satisfied for an app, the package manager refejects installing the app. The dependency can be optional using the `android:required` attribute. When it is set to true, the absence of the lib on the device doesn't prevent the app from being installed. However, the app has to gracefully deal with the absence. The changed behavior only affects apps targeting S or higher. Existing apps are unaffected; they still get all the public native libraries regardless of whether they have tags or not; the tags are simply ignored. This is the first version of the implementation and therefore needs further refinements. The followings are two major TODOs. 1) The native shared lib dependencies of the java shared libraries are not enforced. For example, if an app depends on a java shared library foo and foo depends on some native shared libraries, the classloader where code from foo is loaded still gets all native shared libraries. This should be fixed. 2) New APIs should be added. SharedLibraryInfo should be extended to represent native shared libraries. The meaning of ApplicationInfo.sharedLibraryFiles should be revised. Finally, the new tag should be made public. Bug: 142191088 Test: atest CtsUsesNativeLibraryTest Change-Id: Iceb038aa86872d23e9faf582ae91b1fdcaf5c64c --- core/java/android/app/ApplicationLoaders.java | 28 ++++++++---- core/java/android/app/LoadedApk.java | 23 +++++++++- .../java/android/content/pm/SharedLibraryInfo.java | 25 ++++++++++- .../android/content/pm/parsing/ParsingPackage.java | 6 +++ .../content/pm/parsing/ParsingPackageImpl.java | 44 ++++++++++++++++++ .../content/pm/parsing/ParsingPackageRead.java | 13 ++++++ .../content/pm/parsing/ParsingPackageUtils.java | 35 +++++++++++++++ .../android/internal/os/ClassLoaderFactory.java | 15 +++++-- core/java/com/android/server/SystemConfig.java | 40 +++++++++++++++++ .../com_android_internal_os_ClassLoaderFactory.cpp | 9 ++-- core/res/res/values/attrs_manifest.xml | 23 ++++++++++ .../android/server/pm/PackageManagerService.java | 52 ++++++++++++++++++---- .../core/java/com/android/server/pm/Settings.java | 17 +++++++ .../server/pm/parsing/pkg/AndroidPackage.java | 13 ++++++ tools/aapt2/dump/DumpManifest.cpp | 25 +++++++++++ tools/aapt2/link/ManifestFixer.cpp | 1 + 16 files changed, 343 insertions(+), 26 deletions(-) diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java index bac432e42318..15237beee805 100644 --- a/core/java/android/app/ApplicationLoaders.java +++ b/core/java/android/app/ApplicationLoaders.java @@ -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 sharedLibraries) { + List sharedLibraries, List 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 + // 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 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 sharedLibraries) { + String classLoaderName, List sharedLibraries, + List 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 */); } /** diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index f9b48e710148..1dc54ddbac4b 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -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 paths = lib.getAllCodePaths(); outSeenPaths.addAll(paths); for (String path : paths) { @@ -696,6 +702,12 @@ public final class LoadedApk { } List 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 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); diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java index da2a3d885fc6..862563706da7 100644 --- a/core/java/android/content/pm/SharedLibraryInfo.java +++ b/core/java/android/content/pm/SharedLibraryInfo.java @@ -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 mDependentPackages; private List 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 codePaths, String name, long version, int type, VersionedPackage declaringPackage, List dependentPackages, - List dependencies) { + List 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 codePaths, + String name, long version, int type, + VersionedPackage declaringPackage, List dependentPackages, + List 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) { diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java index 2ee0ad67b108..872098c8689e 100644 --- a/core/java/android/content/pm/parsing/ParsingPackage.java +++ b/core/java/android/content/pm/parsing/ParsingPackage.java @@ -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); diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java index f932bc250e28..0c0dc313087e 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java +++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java @@ -184,6 +184,13 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { @DataClass.ParcelWith(ForInternedStringList.class) protected List usesOptionalLibraries = emptyList(); + @NonNull + @DataClass.ParcelWith(ForInternedStringList.class) + protected List usesNativeLibraries = emptyList(); + @NonNull + @DataClass.ParcelWith(ForInternedStringList.class) + protected List usesOptionalNativeLibraries = emptyList(); + @NonNull @DataClass.ParcelWith(ForInternedStringList.class) private List 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 getUsesNativeLibraries() { + return usesNativeLibraries; + } + + @NonNull + @Override + public List getUsesOptionalNativeLibraries() { + return usesOptionalNativeLibraries; + } + @NonNull @Override public List getUsesStaticLibraries() { diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java index 5b53c18b820c..7e0fe7dc41bf 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageRead.java +++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java @@ -230,6 +230,19 @@ public interface ParsingPackageRead extends Parcelable { @NonNull List getUsesOptionalLibraries(); + /** @see R.styleabele#AndroidManifestUsesNativeLibrary */ + @NonNull + List 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 getUsesOptionalNativeLibraries(); + /** * TODO(b/135203078): Move static library stuff to an inner data class * @see R.styleable#AndroidManifestUsesStaticLibrary diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 3688f1bda979..e1f08f3e55a1 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -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 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 parseProcesses(ParseInput input, ParsingPackage pkg, Resources res, XmlResourceParser parser, String[] separateProcesses, int flags) diff --git a/core/java/com/android/internal/os/ClassLoaderFactory.java b/core/java/com/android/internal/os/ClassLoaderFactory.java index a18943c264f5..f83c5bdc4e28 100644 --- a/core/java/com/android/internal/os/ClassLoaderFactory.java +++ b/core/java/com/android/internal/os/ClassLoaderFactory.java @@ -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 sharedLibraries) { + List sharedLibraries, List 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); } diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java index 0eb3981ed598..957cc76b3e54 100644 --- a/core/java/com/android/server/SystemConfig.java +++ b/core/java/com/android/server/SystemConfig.java @@ -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 [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; } diff --git a/core/jni/com_android_internal_os_ClassLoaderFactory.cpp b/core/jni/com_android_internal_os_ClassLoaderFactory.cpp index f8d41e4bef54..59c413ff58a6 100644 --- a/core/jni/com_android_internal_os_ClassLoaderFactory.cpp +++ b/core/jni/com_android_internal_os_ClassLoaderFactory.cpp @@ -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(createClassloaderNamespace_native) }, }; diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index eb30c9be4eba..ac08d96ab303 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -2173,6 +2173,29 @@ + + + + + + + +