diff options
| author | Jiyong Park <jiyong@google.com> | 2020-07-23 08:56:41 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-07-23 08:56:41 +0000 |
| commit | 5a63c659983b78766ed8cefd31c19013287d5eec (patch) | |
| tree | fbe1ad63b75c51d15d3c3134d59308b8ddd3d886 /core/java/android | |
| parent | 3e9bfcf84fa5a42a50d1ba1d707eb7c4c3d4fcae (diff) | |
| parent | 6a5b8b1f6db172b5aaadcec0c3868e54e214b675 (diff) | |
Merge "Introduce uses-native-library tag"
Diffstat (limited to 'core/java/android')
7 files changed, 164 insertions, 10 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<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 */); } /** 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<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); 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<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(); } /** @@ -137,6 +150,15 @@ public final class SharedLibraryInfo implements Parcelable { } /** + * 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 @@ -186,6 +186,13 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { @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(); @Nullable private long[] usesStaticLibrariesVersions; @@ -669,6 +676,27 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { } @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, TextUtils.safeIntern(libraryName)); @@ -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(); @@ -1417,6 +1449,18 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { @NonNull @Override + public List<String> getUsesNativeLibraries() { + return usesNativeLibraries; + } + + @NonNull + @Override + public List<String> getUsesOptionalNativeLibraries() { + return usesOptionalNativeLibraries; + } + + @NonNull + @Override public List<String> getUsesStaticLibraries() { return usesStaticLibraries; } 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<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 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": @@ -2178,6 +2182,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) throws IOException, XmlPullParserException { |
