Fix the way manifest fixer detects optional <uses-library> entries.
Previously manifest_fixer used a naive way to distiniguish optional libs
from required ones: it checked if a library is on the list of optional
compatibility libraries. This works for compatibility libs, but not for
other libs.
Now we properly track optionality through all stages of the build,
starting with the addition of the library as a dependency (here's where
the `uses_libs`/`optional_uses_libs` distinction kicks in), store it in
dependency tag and propagate to class loader context, and from there to
the manifest_fixer.
The tests have been updated accordingly.
Bug: 196377222
Test: lunch bertha_x86_64-userdebug && m droid dist cts mts
Change-Id: I3631ce59ebe47116ce7a9b3d33a86f636846ef0f
diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go
index 245af2c..ebb8959 100644
--- a/dexpreopt/class_loader_context.go
+++ b/dexpreopt/class_loader_context.go
@@ -193,6 +193,9 @@
// The name of the library.
Name string
+ // If the library is optional or required.
+ Optional bool
+
// On-host build path to the library dex file (used in dex2oat argument --class-loader-context).
Host android.Path
@@ -256,7 +259,7 @@
// Add class loader context for the given library to the map entry for the given SDK version.
func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathContext, sdkVer int, lib string,
- hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) error {
+ optional bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) error {
// For prebuilts, library should have the same name as the source module.
lib = android.RemoveOptionalPrebuiltPrefix(lib)
@@ -304,6 +307,7 @@
clcMap[sdkVer] = append(clcMap[sdkVer], &ClassLoaderContext{
Name: lib,
+ Optional: optional,
Host: hostPath,
Device: devicePath,
Subcontexts: subcontexts,
@@ -316,9 +320,9 @@
// about paths). For the subset of libraries that are used in dexpreopt, their build/install paths
// are validated later before CLC is used (in validateClassLoaderContext).
func (clcMap ClassLoaderContextMap) AddContext(ctx android.ModuleInstallPathContext, sdkVer int,
- lib string, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) {
+ lib string, optional bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) {
- err := clcMap.addContext(ctx, sdkVer, lib, hostPath, installPath, nestedClcMap)
+ err := clcMap.addContext(ctx, sdkVer, lib, optional, hostPath, installPath, nestedClcMap)
if err != nil {
ctx.ModuleErrorf(err.Error())
}
@@ -361,15 +365,21 @@
// Returns top-level libraries in the CLC (conditional CLC, i.e. compatibility libraries are not
// included). This is the list of libraries that should be in the <uses-library> tags in the
// manifest. Some of them may be present in the source manifest, others are added by manifest_fixer.
-func (clcMap ClassLoaderContextMap) UsesLibs() (ulibs []string) {
+// Required and optional libraries are in separate lists.
+func (clcMap ClassLoaderContextMap) UsesLibs() (required []string, optional []string) {
if clcMap != nil {
clcs := clcMap[AnySdkVersion]
- ulibs = make([]string, 0, len(clcs))
+ required = make([]string, 0, len(clcs))
+ optional = make([]string, 0, len(clcs))
for _, clc := range clcs {
- ulibs = append(ulibs, clc.Name)
+ if clc.Optional {
+ optional = append(optional, clc.Name)
+ } else {
+ required = append(required, clc.Name)
+ }
}
}
- return ulibs
+ return required, optional
}
func (clcMap ClassLoaderContextMap) Dump() string {
@@ -388,7 +398,8 @@
// TODO(b/132357300): remove "android.hidl.manager" and "android.hidl.base" for non-system apps.
//
func fixClassLoaderContext(clcMap ClassLoaderContextMap) {
- usesLibs := clcMap.UsesLibs()
+ required, optional := clcMap.UsesLibs()
+ usesLibs := append(required, optional...)
for sdkVer, clcs := range clcMap {
if sdkVer == AnySdkVersion {