Loading dexpreopt/class_loader_context.go +6 −26 Original line number Diff line number Diff line Loading @@ -196,10 +196,6 @@ type ClassLoaderContext struct { // If the library is optional or required. Optional bool // If the library is implicitly infered by Soong (as opposed to explicitly added via `uses_libs` // or `optional_uses_libs`. Implicit bool // On-host build path to the library dex file (used in dex2oat argument --class-loader-context). Host android.Path Loading Loading @@ -290,9 +286,8 @@ const UnknownInstallLibraryPath = "error" const AnySdkVersion int = android.FutureApiLevelInt // 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, optional, implicit bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) error { func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathContext, sdkVer int, lib string, 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) Loading Loading @@ -341,7 +336,6 @@ func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathCont clcMap[sdkVer] = append(clcMap[sdkVer], &ClassLoaderContext{ Name: lib, Optional: optional, Implicit: implicit, Host: hostPath, Device: devicePath, Subcontexts: subcontexts, Loading @@ -354,10 +348,9 @@ func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathCont // 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, optional, implicit bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) { lib string, optional bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) { err := clcMap.addContext(ctx, sdkVer, lib, optional, implicit, hostPath, installPath, nestedClcMap) err := clcMap.addContext(ctx, sdkVer, lib, optional, hostPath, installPath, nestedClcMap) if err != nil { ctx.ModuleErrorf(err.Error()) } Loading Loading @@ -401,15 +394,13 @@ func (clcMap ClassLoaderContextMap) AddContextMap(otherClcMap ClassLoaderContext // 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. // Required and optional libraries are in separate lists. func (clcMap ClassLoaderContextMap) usesLibs(implicit bool) (required []string, optional []string) { func (clcMap ClassLoaderContextMap) UsesLibs() (required []string, optional []string) { if clcMap != nil { clcs := clcMap[AnySdkVersion] required = make([]string, 0, len(clcs)) optional = make([]string, 0, len(clcs)) for _, clc := range clcs { if implicit && !clc.Implicit { // Skip, this is an explicit library and we need only the implicit ones. } else if clc.Optional { if clc.Optional { optional = append(optional, clc.Name) } else { required = append(required, clc.Name) Loading @@ -419,14 +410,6 @@ func (clcMap ClassLoaderContextMap) usesLibs(implicit bool) (required []string, return required, optional } func (clcMap ClassLoaderContextMap) UsesLibs() ([]string, []string) { return clcMap.usesLibs(false) } func (clcMap ClassLoaderContextMap) ImplicitUsesLibs() ([]string, []string) { return clcMap.usesLibs(true) } func (clcMap ClassLoaderContextMap) Dump() string { jsonCLC := toJsonClassLoaderContext(clcMap) bytes, err := json.MarshalIndent(jsonCLC, "", " ") Loading Loading @@ -631,7 +614,6 @@ func computeClassLoaderContextRec(clcs []*ClassLoaderContext) (string, string, a type jsonClassLoaderContext struct { Name string Optional bool Implicit bool Host string Device string Subcontexts []*jsonClassLoaderContext Loading Loading @@ -664,7 +646,6 @@ func fromJsonClassLoaderContextRec(ctx android.PathContext, jClcs []*jsonClassLo clcs = append(clcs, &ClassLoaderContext{ Name: clc.Name, Optional: clc.Optional, Implicit: clc.Implicit, Host: constructPath(ctx, clc.Host), Device: clc.Device, Subcontexts: fromJsonClassLoaderContextRec(ctx, clc.Subcontexts), Loading Loading @@ -700,7 +681,6 @@ func toJsonClassLoaderContextRec(clcs []*ClassLoaderContext) []*jsonClassLoaderC jClcs[i] = &jsonClassLoaderContext{ Name: clc.Name, Optional: clc.Optional, Implicit: clc.Implicit, Host: host, Device: clc.Device, Subcontexts: toJsonClassLoaderContextRec(clc.Subcontexts), Loading dexpreopt/class_loader_context_test.go +38 −51 Original line number Diff line number Diff line Loading @@ -50,34 +50,33 @@ func TestCLC(t *testing.T) { ctx := testContext() optional := false implicit := true m := make(ClassLoaderContextMap) m.AddContext(ctx, AnySdkVersion, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, AnySdkVersion, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, AnySdkVersion, "c", optional, implicit, buildPath(ctx, "c"), installPath(ctx, "c"), nil) m.AddContext(ctx, AnySdkVersion, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, AnySdkVersion, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil) // Add some libraries with nested subcontexts. m1 := make(ClassLoaderContextMap) m1.AddContext(ctx, AnySdkVersion, "a1", optional, implicit, buildPath(ctx, "a1"), installPath(ctx, "a1"), nil) m1.AddContext(ctx, AnySdkVersion, "b1", optional, implicit, buildPath(ctx, "b1"), installPath(ctx, "b1"), nil) m1.AddContext(ctx, AnySdkVersion, "a1", optional, buildPath(ctx, "a1"), installPath(ctx, "a1"), nil) m1.AddContext(ctx, AnySdkVersion, "b1", optional, buildPath(ctx, "b1"), installPath(ctx, "b1"), nil) m2 := make(ClassLoaderContextMap) m2.AddContext(ctx, AnySdkVersion, "a2", optional, implicit, buildPath(ctx, "a2"), installPath(ctx, "a2"), nil) m2.AddContext(ctx, AnySdkVersion, "b2", optional, implicit, buildPath(ctx, "b2"), installPath(ctx, "b2"), nil) m2.AddContext(ctx, AnySdkVersion, "c2", optional, implicit, buildPath(ctx, "c2"), installPath(ctx, "c2"), m1) m2.AddContext(ctx, AnySdkVersion, "a2", optional, buildPath(ctx, "a2"), installPath(ctx, "a2"), nil) m2.AddContext(ctx, AnySdkVersion, "b2", optional, buildPath(ctx, "b2"), installPath(ctx, "b2"), nil) m2.AddContext(ctx, AnySdkVersion, "c2", optional, buildPath(ctx, "c2"), installPath(ctx, "c2"), m1) m3 := make(ClassLoaderContextMap) m3.AddContext(ctx, AnySdkVersion, "a3", optional, implicit, buildPath(ctx, "a3"), installPath(ctx, "a3"), nil) m3.AddContext(ctx, AnySdkVersion, "b3", optional, implicit, buildPath(ctx, "b3"), installPath(ctx, "b3"), nil) m3.AddContext(ctx, AnySdkVersion, "a3", optional, buildPath(ctx, "a3"), installPath(ctx, "a3"), nil) m3.AddContext(ctx, AnySdkVersion, "b3", optional, buildPath(ctx, "b3"), installPath(ctx, "b3"), nil) m.AddContext(ctx, AnySdkVersion, "d", optional, implicit, buildPath(ctx, "d"), installPath(ctx, "d"), m2) m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), m2) // When the same library is both in conditional and unconditional context, it should be removed // from conditional context. m.AddContext(ctx, 42, "f", optional, implicit, buildPath(ctx, "f"), installPath(ctx, "f"), nil) m.AddContext(ctx, AnySdkVersion, "f", optional, implicit, buildPath(ctx, "f"), installPath(ctx, "f"), nil) m.AddContext(ctx, 42, "f", optional, buildPath(ctx, "f"), installPath(ctx, "f"), nil) m.AddContext(ctx, AnySdkVersion, "f", optional, buildPath(ctx, "f"), installPath(ctx, "f"), nil) // Merge map with implicit root library that is among toplevel contexts => does nothing. m.AddContextMap(m1, "c") Loading @@ -86,12 +85,12 @@ func TestCLC(t *testing.T) { m.AddContextMap(m3, "m_g") // Compatibility libraries with unknown install paths get default paths. m.AddContext(ctx, 29, AndroidHidlManager, optional, implicit, buildPath(ctx, AndroidHidlManager), nil, nil) m.AddContext(ctx, 29, AndroidHidlBase, optional, implicit, buildPath(ctx, AndroidHidlBase), nil, nil) m.AddContext(ctx, 29, AndroidHidlManager, optional, buildPath(ctx, AndroidHidlManager), nil, nil) m.AddContext(ctx, 29, AndroidHidlBase, optional, buildPath(ctx, AndroidHidlBase), nil, nil) // Add "android.test.mock" to conditional CLC, observe that is gets removed because it is only // needed as a compatibility library if "android.test.runner" is in CLC as well. m.AddContext(ctx, 30, AndroidTestMock, optional, implicit, buildPath(ctx, AndroidTestMock), nil, nil) m.AddContext(ctx, 30, AndroidTestMock, optional, buildPath(ctx, AndroidTestMock), nil, nil) valid, validationError := validateClassLoaderContext(m) Loading Loading @@ -165,12 +164,11 @@ func TestCLC(t *testing.T) { func TestCLCJson(t *testing.T) { ctx := testContext() optional := false implicit := true m := make(ClassLoaderContextMap) m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 29, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, 30, "c", optional, implicit, buildPath(ctx, "c"), installPath(ctx, "c"), nil) m.AddContext(ctx, AnySdkVersion, "d", optional, implicit, buildPath(ctx, "d"), installPath(ctx, "d"), nil) m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 29, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, 30, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil) m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), nil) jsonCLC := toJsonClassLoaderContext(m) restored := fromJsonClassLoaderContext(ctx, jsonCLC) android.AssertIntEquals(t, "The size of the maps should be the same.", len(m), len(restored)) Loading @@ -191,13 +189,12 @@ func TestCLCJson(t *testing.T) { func testCLCUnknownPath(t *testing.T, whichPath string) { ctx := testContext() optional := false implicit := true m := make(ClassLoaderContextMap) if whichPath == "build" { m.AddContext(ctx, AnySdkVersion, "a", optional, implicit, nil, nil, nil) m.AddContext(ctx, AnySdkVersion, "a", optional, nil, nil, nil) } else { m.AddContext(ctx, AnySdkVersion, "a", optional, implicit, buildPath(ctx, "a"), nil, nil) m.AddContext(ctx, AnySdkVersion, "a", optional, buildPath(ctx, "a"), nil, nil) } // The library should be added to <uses-library> tags by the manifest_fixer. Loading Loading @@ -232,11 +229,10 @@ func TestCLCUnknownInstallPath(t *testing.T) { func TestCLCNestedConditional(t *testing.T) { ctx := testContext() optional := false implicit := true m1 := make(ClassLoaderContextMap) m1.AddContext(ctx, 42, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m1.AddContext(ctx, 42, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m := make(ClassLoaderContextMap) err := m.addContext(ctx, AnySdkVersion, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), m1) err := m.addContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), m1) checkError(t, err, "nested class loader context shouldn't have conditional part") } Loading @@ -245,12 +241,11 @@ func TestCLCNestedConditional(t *testing.T) { func TestCLCSdkVersionOrder(t *testing.T) { ctx := testContext() optional := false implicit := true m := make(ClassLoaderContextMap) m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 29, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, 30, "c", optional, implicit, buildPath(ctx, "c"), installPath(ctx, "c"), nil) m.AddContext(ctx, AnySdkVersion, "d", optional, implicit, buildPath(ctx, "d"), installPath(ctx, "d"), nil) m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 29, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, 30, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil) m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), nil) valid, validationError := validateClassLoaderContext(m) Loading Loading @@ -287,7 +282,6 @@ func TestCLCSdkVersionOrder(t *testing.T) { func TestCLCMExcludeLibs(t *testing.T) { ctx := testContext() const optional = false const implicit = true excludeLibs := func(t *testing.T, m ClassLoaderContextMap, excluded_libs ...string) ClassLoaderContextMap { // Dump the CLCM before creating a new copy that excludes a specific set of libraries. Loading @@ -305,7 +299,7 @@ func TestCLCMExcludeLibs(t *testing.T) { t.Run("exclude nothing", func(t *testing.T) { m := make(ClassLoaderContextMap) m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) a := excludeLibs(t, m) Loading @@ -314,7 +308,6 @@ func TestCLCMExcludeLibs(t *testing.T) { { "Name": "a", "Optional": false, "Implicit": true, "Host": "out/soong/a.jar", "Device": "/system/a.jar", "Subcontexts": [] Loading @@ -325,8 +318,8 @@ func TestCLCMExcludeLibs(t *testing.T) { t.Run("one item from list", func(t *testing.T) { m := make(ClassLoaderContextMap) m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 28, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 28, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil) a := excludeLibs(t, m, "a") Loading @@ -335,7 +328,6 @@ func TestCLCMExcludeLibs(t *testing.T) { { "Name": "b", "Optional": false, "Implicit": true, "Host": "out/soong/b.jar", "Device": "/system/b.jar", "Subcontexts": [] Loading @@ -347,8 +339,8 @@ func TestCLCMExcludeLibs(t *testing.T) { t.Run("all items from a list", func(t *testing.T) { m := make(ClassLoaderContextMap) m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 28, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 28, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil) a := excludeLibs(t, m, "a", "b") Loading @@ -357,11 +349,11 @@ func TestCLCMExcludeLibs(t *testing.T) { t.Run("items from a subcontext", func(t *testing.T) { s := make(ClassLoaderContextMap) s.AddContext(ctx, AnySdkVersion, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) s.AddContext(ctx, AnySdkVersion, "c", optional, implicit, buildPath(ctx, "c"), installPath(ctx, "c"), nil) s.AddContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil) s.AddContext(ctx, AnySdkVersion, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil) m := make(ClassLoaderContextMap) m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), s) m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), s) a := excludeLibs(t, m, "b") Loading @@ -370,14 +362,12 @@ func TestCLCMExcludeLibs(t *testing.T) { { "Name": "a", "Optional": false, "Implicit": true, "Host": "out/soong/a.jar", "Device": "/system/a.jar", "Subcontexts": [ { "Name": "c", "Optional": false, "Implicit": true, "Host": "out/soong/c.jar", "Device": "/system/c.jar", "Subcontexts": [] Loading @@ -393,16 +383,14 @@ func TestCLCMExcludeLibs(t *testing.T) { func TestCLCtoJSON(t *testing.T) { ctx := testContext() optional := false implicit := true m := make(ClassLoaderContextMap) m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, AnySdkVersion, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil) android.AssertStringEquals(t, "output CLCM ", `{ "28": [ { "Name": "a", "Optional": false, "Implicit": true, "Host": "out/soong/a.jar", "Device": "/system/a.jar", "Subcontexts": [] Loading @@ -412,7 +400,6 @@ func TestCLCtoJSON(t *testing.T) { { "Name": "b", "Optional": false, "Implicit": true, "Host": "out/soong/b.jar", "Device": "/system/b.jar", "Subcontexts": [] Loading java/android_manifest.go +3 −3 Original line number Diff line number Diff line Loading @@ -96,9 +96,9 @@ func ManifestFixer(ctx android.ModuleContext, manifest android.Path, } if params.ClassLoaderContexts != nil { // manifest_fixer should add only the implicit SDK libraries inferred by Soong, not those added // explicitly via `uses_libs`/`optional_uses_libs`. requiredUsesLibs, optionalUsesLibs := params.ClassLoaderContexts.ImplicitUsesLibs() // Libraries propagated via `uses_libs`/`optional_uses_libs` are also added (they may be // propagated from dependencies). requiredUsesLibs, optionalUsesLibs := params.ClassLoaderContexts.UsesLibs() for _, usesLib := range requiredUsesLibs { args = append(args, "--uses-library", usesLib) Loading java/app.go +8 −19 Original line number Diff line number Diff line Loading @@ -1227,28 +1227,17 @@ func (u *usesLibrary) addLib(lib string, optional bool) { func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) { if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() { reqTag := makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false, false) ctx.AddVariationDependencies(nil, reqTag, u.usesLibraryProperties.Uses_libs...) optTag := makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true, false) ctx.AddVariationDependencies(nil, optTag, u.presentOptionalUsesLibs(ctx)...) ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs...) ctx.AddVariationDependencies(nil, usesLibOptTag, u.presentOptionalUsesLibs(ctx)...) // Only add these extra dependencies if the module depends on framework libs. This avoids // creating a cyclic dependency: // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res. if hasFrameworkLibs { // Add implicit <uses-library> dependencies on compatibility libraries. Some of them are // optional, and some required --- this depends on the most common usage of the library // and may be wrong for some apps (they need explicit `uses_libs`/`optional_uses_libs`). compat28OptTag := makeUsesLibraryDependencyTag(28, true, true) ctx.AddVariationDependencies(nil, compat28OptTag, dexpreopt.OptionalCompatUsesLibs28...) compat29ReqTag := makeUsesLibraryDependencyTag(29, false, true) ctx.AddVariationDependencies(nil, compat29ReqTag, dexpreopt.CompatUsesLibs29...) compat30OptTag := makeUsesLibraryDependencyTag(30, true, true) ctx.AddVariationDependencies(nil, compat30OptTag, dexpreopt.OptionalCompatUsesLibs30...) // Dexpreopt needs paths to the dex jars of these libraries in order to construct // class loader context for dex2oat. Add them as a dependency with a special tag. ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...) ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...) ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...) } } } Loading Loading @@ -1307,7 +1296,7 @@ func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName) replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName) } clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, tag.implicit, clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, lib.DexJarBuildPath().PathOrNil(), lib.DexJarInstallPath(), lib.ClassLoaderContexts()) } else if ctx.Config().AllowMissingDependencies() { Loading java/app_test.go +10 −2 Original line number Diff line number Diff line Loading @@ -2505,12 +2505,20 @@ func TestUsesLibraries(t *testing.T) { prebuilt := result.ModuleForTests("prebuilt", "android_common") // Test that implicit dependencies on java_sdk_library instances are passed to the manifest. // This should not include explicit `uses_libs`/`optional_uses_libs` entries. // These also include explicit `uses_libs`/`optional_uses_libs` entries, as they may be // propagated from dependencies. actualManifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"] expectManifestFixerArgs := `--extract-native-libs=true ` + `--uses-library qux ` + `--uses-library quuz ` + `--uses-library runtime-library` `--uses-library foo ` + `--uses-library com.non.sdk.lib ` + `--uses-library runtime-library ` + `--uses-library runtime-required-x ` + `--uses-library runtime-required-y ` + `--optional-uses-library bar ` + `--optional-uses-library runtime-optional-x ` + `--optional-uses-library runtime-optional-y` android.AssertStringDoesContain(t, "manifest_fixer args", actualManifestFixerArgs, expectManifestFixerArgs) // Test that all libraries are verified (library order matters). Loading Loading
dexpreopt/class_loader_context.go +6 −26 Original line number Diff line number Diff line Loading @@ -196,10 +196,6 @@ type ClassLoaderContext struct { // If the library is optional or required. Optional bool // If the library is implicitly infered by Soong (as opposed to explicitly added via `uses_libs` // or `optional_uses_libs`. Implicit bool // On-host build path to the library dex file (used in dex2oat argument --class-loader-context). Host android.Path Loading Loading @@ -290,9 +286,8 @@ const UnknownInstallLibraryPath = "error" const AnySdkVersion int = android.FutureApiLevelInt // 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, optional, implicit bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) error { func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathContext, sdkVer int, lib string, 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) Loading Loading @@ -341,7 +336,6 @@ func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathCont clcMap[sdkVer] = append(clcMap[sdkVer], &ClassLoaderContext{ Name: lib, Optional: optional, Implicit: implicit, Host: hostPath, Device: devicePath, Subcontexts: subcontexts, Loading @@ -354,10 +348,9 @@ func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathCont // 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, optional, implicit bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) { lib string, optional bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) { err := clcMap.addContext(ctx, sdkVer, lib, optional, implicit, hostPath, installPath, nestedClcMap) err := clcMap.addContext(ctx, sdkVer, lib, optional, hostPath, installPath, nestedClcMap) if err != nil { ctx.ModuleErrorf(err.Error()) } Loading Loading @@ -401,15 +394,13 @@ func (clcMap ClassLoaderContextMap) AddContextMap(otherClcMap ClassLoaderContext // 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. // Required and optional libraries are in separate lists. func (clcMap ClassLoaderContextMap) usesLibs(implicit bool) (required []string, optional []string) { func (clcMap ClassLoaderContextMap) UsesLibs() (required []string, optional []string) { if clcMap != nil { clcs := clcMap[AnySdkVersion] required = make([]string, 0, len(clcs)) optional = make([]string, 0, len(clcs)) for _, clc := range clcs { if implicit && !clc.Implicit { // Skip, this is an explicit library and we need only the implicit ones. } else if clc.Optional { if clc.Optional { optional = append(optional, clc.Name) } else { required = append(required, clc.Name) Loading @@ -419,14 +410,6 @@ func (clcMap ClassLoaderContextMap) usesLibs(implicit bool) (required []string, return required, optional } func (clcMap ClassLoaderContextMap) UsesLibs() ([]string, []string) { return clcMap.usesLibs(false) } func (clcMap ClassLoaderContextMap) ImplicitUsesLibs() ([]string, []string) { return clcMap.usesLibs(true) } func (clcMap ClassLoaderContextMap) Dump() string { jsonCLC := toJsonClassLoaderContext(clcMap) bytes, err := json.MarshalIndent(jsonCLC, "", " ") Loading Loading @@ -631,7 +614,6 @@ func computeClassLoaderContextRec(clcs []*ClassLoaderContext) (string, string, a type jsonClassLoaderContext struct { Name string Optional bool Implicit bool Host string Device string Subcontexts []*jsonClassLoaderContext Loading Loading @@ -664,7 +646,6 @@ func fromJsonClassLoaderContextRec(ctx android.PathContext, jClcs []*jsonClassLo clcs = append(clcs, &ClassLoaderContext{ Name: clc.Name, Optional: clc.Optional, Implicit: clc.Implicit, Host: constructPath(ctx, clc.Host), Device: clc.Device, Subcontexts: fromJsonClassLoaderContextRec(ctx, clc.Subcontexts), Loading Loading @@ -700,7 +681,6 @@ func toJsonClassLoaderContextRec(clcs []*ClassLoaderContext) []*jsonClassLoaderC jClcs[i] = &jsonClassLoaderContext{ Name: clc.Name, Optional: clc.Optional, Implicit: clc.Implicit, Host: host, Device: clc.Device, Subcontexts: toJsonClassLoaderContextRec(clc.Subcontexts), Loading
dexpreopt/class_loader_context_test.go +38 −51 Original line number Diff line number Diff line Loading @@ -50,34 +50,33 @@ func TestCLC(t *testing.T) { ctx := testContext() optional := false implicit := true m := make(ClassLoaderContextMap) m.AddContext(ctx, AnySdkVersion, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, AnySdkVersion, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, AnySdkVersion, "c", optional, implicit, buildPath(ctx, "c"), installPath(ctx, "c"), nil) m.AddContext(ctx, AnySdkVersion, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, AnySdkVersion, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil) // Add some libraries with nested subcontexts. m1 := make(ClassLoaderContextMap) m1.AddContext(ctx, AnySdkVersion, "a1", optional, implicit, buildPath(ctx, "a1"), installPath(ctx, "a1"), nil) m1.AddContext(ctx, AnySdkVersion, "b1", optional, implicit, buildPath(ctx, "b1"), installPath(ctx, "b1"), nil) m1.AddContext(ctx, AnySdkVersion, "a1", optional, buildPath(ctx, "a1"), installPath(ctx, "a1"), nil) m1.AddContext(ctx, AnySdkVersion, "b1", optional, buildPath(ctx, "b1"), installPath(ctx, "b1"), nil) m2 := make(ClassLoaderContextMap) m2.AddContext(ctx, AnySdkVersion, "a2", optional, implicit, buildPath(ctx, "a2"), installPath(ctx, "a2"), nil) m2.AddContext(ctx, AnySdkVersion, "b2", optional, implicit, buildPath(ctx, "b2"), installPath(ctx, "b2"), nil) m2.AddContext(ctx, AnySdkVersion, "c2", optional, implicit, buildPath(ctx, "c2"), installPath(ctx, "c2"), m1) m2.AddContext(ctx, AnySdkVersion, "a2", optional, buildPath(ctx, "a2"), installPath(ctx, "a2"), nil) m2.AddContext(ctx, AnySdkVersion, "b2", optional, buildPath(ctx, "b2"), installPath(ctx, "b2"), nil) m2.AddContext(ctx, AnySdkVersion, "c2", optional, buildPath(ctx, "c2"), installPath(ctx, "c2"), m1) m3 := make(ClassLoaderContextMap) m3.AddContext(ctx, AnySdkVersion, "a3", optional, implicit, buildPath(ctx, "a3"), installPath(ctx, "a3"), nil) m3.AddContext(ctx, AnySdkVersion, "b3", optional, implicit, buildPath(ctx, "b3"), installPath(ctx, "b3"), nil) m3.AddContext(ctx, AnySdkVersion, "a3", optional, buildPath(ctx, "a3"), installPath(ctx, "a3"), nil) m3.AddContext(ctx, AnySdkVersion, "b3", optional, buildPath(ctx, "b3"), installPath(ctx, "b3"), nil) m.AddContext(ctx, AnySdkVersion, "d", optional, implicit, buildPath(ctx, "d"), installPath(ctx, "d"), m2) m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), m2) // When the same library is both in conditional and unconditional context, it should be removed // from conditional context. m.AddContext(ctx, 42, "f", optional, implicit, buildPath(ctx, "f"), installPath(ctx, "f"), nil) m.AddContext(ctx, AnySdkVersion, "f", optional, implicit, buildPath(ctx, "f"), installPath(ctx, "f"), nil) m.AddContext(ctx, 42, "f", optional, buildPath(ctx, "f"), installPath(ctx, "f"), nil) m.AddContext(ctx, AnySdkVersion, "f", optional, buildPath(ctx, "f"), installPath(ctx, "f"), nil) // Merge map with implicit root library that is among toplevel contexts => does nothing. m.AddContextMap(m1, "c") Loading @@ -86,12 +85,12 @@ func TestCLC(t *testing.T) { m.AddContextMap(m3, "m_g") // Compatibility libraries with unknown install paths get default paths. m.AddContext(ctx, 29, AndroidHidlManager, optional, implicit, buildPath(ctx, AndroidHidlManager), nil, nil) m.AddContext(ctx, 29, AndroidHidlBase, optional, implicit, buildPath(ctx, AndroidHidlBase), nil, nil) m.AddContext(ctx, 29, AndroidHidlManager, optional, buildPath(ctx, AndroidHidlManager), nil, nil) m.AddContext(ctx, 29, AndroidHidlBase, optional, buildPath(ctx, AndroidHidlBase), nil, nil) // Add "android.test.mock" to conditional CLC, observe that is gets removed because it is only // needed as a compatibility library if "android.test.runner" is in CLC as well. m.AddContext(ctx, 30, AndroidTestMock, optional, implicit, buildPath(ctx, AndroidTestMock), nil, nil) m.AddContext(ctx, 30, AndroidTestMock, optional, buildPath(ctx, AndroidTestMock), nil, nil) valid, validationError := validateClassLoaderContext(m) Loading Loading @@ -165,12 +164,11 @@ func TestCLC(t *testing.T) { func TestCLCJson(t *testing.T) { ctx := testContext() optional := false implicit := true m := make(ClassLoaderContextMap) m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 29, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, 30, "c", optional, implicit, buildPath(ctx, "c"), installPath(ctx, "c"), nil) m.AddContext(ctx, AnySdkVersion, "d", optional, implicit, buildPath(ctx, "d"), installPath(ctx, "d"), nil) m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 29, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, 30, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil) m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), nil) jsonCLC := toJsonClassLoaderContext(m) restored := fromJsonClassLoaderContext(ctx, jsonCLC) android.AssertIntEquals(t, "The size of the maps should be the same.", len(m), len(restored)) Loading @@ -191,13 +189,12 @@ func TestCLCJson(t *testing.T) { func testCLCUnknownPath(t *testing.T, whichPath string) { ctx := testContext() optional := false implicit := true m := make(ClassLoaderContextMap) if whichPath == "build" { m.AddContext(ctx, AnySdkVersion, "a", optional, implicit, nil, nil, nil) m.AddContext(ctx, AnySdkVersion, "a", optional, nil, nil, nil) } else { m.AddContext(ctx, AnySdkVersion, "a", optional, implicit, buildPath(ctx, "a"), nil, nil) m.AddContext(ctx, AnySdkVersion, "a", optional, buildPath(ctx, "a"), nil, nil) } // The library should be added to <uses-library> tags by the manifest_fixer. Loading Loading @@ -232,11 +229,10 @@ func TestCLCUnknownInstallPath(t *testing.T) { func TestCLCNestedConditional(t *testing.T) { ctx := testContext() optional := false implicit := true m1 := make(ClassLoaderContextMap) m1.AddContext(ctx, 42, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m1.AddContext(ctx, 42, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m := make(ClassLoaderContextMap) err := m.addContext(ctx, AnySdkVersion, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), m1) err := m.addContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), m1) checkError(t, err, "nested class loader context shouldn't have conditional part") } Loading @@ -245,12 +241,11 @@ func TestCLCNestedConditional(t *testing.T) { func TestCLCSdkVersionOrder(t *testing.T) { ctx := testContext() optional := false implicit := true m := make(ClassLoaderContextMap) m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 29, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, 30, "c", optional, implicit, buildPath(ctx, "c"), installPath(ctx, "c"), nil) m.AddContext(ctx, AnySdkVersion, "d", optional, implicit, buildPath(ctx, "d"), installPath(ctx, "d"), nil) m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 29, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, 30, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil) m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), nil) valid, validationError := validateClassLoaderContext(m) Loading Loading @@ -287,7 +282,6 @@ func TestCLCSdkVersionOrder(t *testing.T) { func TestCLCMExcludeLibs(t *testing.T) { ctx := testContext() const optional = false const implicit = true excludeLibs := func(t *testing.T, m ClassLoaderContextMap, excluded_libs ...string) ClassLoaderContextMap { // Dump the CLCM before creating a new copy that excludes a specific set of libraries. Loading @@ -305,7 +299,7 @@ func TestCLCMExcludeLibs(t *testing.T) { t.Run("exclude nothing", func(t *testing.T) { m := make(ClassLoaderContextMap) m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) a := excludeLibs(t, m) Loading @@ -314,7 +308,6 @@ func TestCLCMExcludeLibs(t *testing.T) { { "Name": "a", "Optional": false, "Implicit": true, "Host": "out/soong/a.jar", "Device": "/system/a.jar", "Subcontexts": [] Loading @@ -325,8 +318,8 @@ func TestCLCMExcludeLibs(t *testing.T) { t.Run("one item from list", func(t *testing.T) { m := make(ClassLoaderContextMap) m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 28, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 28, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil) a := excludeLibs(t, m, "a") Loading @@ -335,7 +328,6 @@ func TestCLCMExcludeLibs(t *testing.T) { { "Name": "b", "Optional": false, "Implicit": true, "Host": "out/soong/b.jar", "Device": "/system/b.jar", "Subcontexts": [] Loading @@ -347,8 +339,8 @@ func TestCLCMExcludeLibs(t *testing.T) { t.Run("all items from a list", func(t *testing.T) { m := make(ClassLoaderContextMap) m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 28, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, 28, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil) a := excludeLibs(t, m, "a", "b") Loading @@ -357,11 +349,11 @@ func TestCLCMExcludeLibs(t *testing.T) { t.Run("items from a subcontext", func(t *testing.T) { s := make(ClassLoaderContextMap) s.AddContext(ctx, AnySdkVersion, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) s.AddContext(ctx, AnySdkVersion, "c", optional, implicit, buildPath(ctx, "c"), installPath(ctx, "c"), nil) s.AddContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil) s.AddContext(ctx, AnySdkVersion, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil) m := make(ClassLoaderContextMap) m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), s) m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), s) a := excludeLibs(t, m, "b") Loading @@ -370,14 +362,12 @@ func TestCLCMExcludeLibs(t *testing.T) { { "Name": "a", "Optional": false, "Implicit": true, "Host": "out/soong/a.jar", "Device": "/system/a.jar", "Subcontexts": [ { "Name": "c", "Optional": false, "Implicit": true, "Host": "out/soong/c.jar", "Device": "/system/c.jar", "Subcontexts": [] Loading @@ -393,16 +383,14 @@ func TestCLCMExcludeLibs(t *testing.T) { func TestCLCtoJSON(t *testing.T) { ctx := testContext() optional := false implicit := true m := make(ClassLoaderContextMap) m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, AnySdkVersion, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m.AddContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil) android.AssertStringEquals(t, "output CLCM ", `{ "28": [ { "Name": "a", "Optional": false, "Implicit": true, "Host": "out/soong/a.jar", "Device": "/system/a.jar", "Subcontexts": [] Loading @@ -412,7 +400,6 @@ func TestCLCtoJSON(t *testing.T) { { "Name": "b", "Optional": false, "Implicit": true, "Host": "out/soong/b.jar", "Device": "/system/b.jar", "Subcontexts": [] Loading
java/android_manifest.go +3 −3 Original line number Diff line number Diff line Loading @@ -96,9 +96,9 @@ func ManifestFixer(ctx android.ModuleContext, manifest android.Path, } if params.ClassLoaderContexts != nil { // manifest_fixer should add only the implicit SDK libraries inferred by Soong, not those added // explicitly via `uses_libs`/`optional_uses_libs`. requiredUsesLibs, optionalUsesLibs := params.ClassLoaderContexts.ImplicitUsesLibs() // Libraries propagated via `uses_libs`/`optional_uses_libs` are also added (they may be // propagated from dependencies). requiredUsesLibs, optionalUsesLibs := params.ClassLoaderContexts.UsesLibs() for _, usesLib := range requiredUsesLibs { args = append(args, "--uses-library", usesLib) Loading
java/app.go +8 −19 Original line number Diff line number Diff line Loading @@ -1227,28 +1227,17 @@ func (u *usesLibrary) addLib(lib string, optional bool) { func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) { if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() { reqTag := makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false, false) ctx.AddVariationDependencies(nil, reqTag, u.usesLibraryProperties.Uses_libs...) optTag := makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true, false) ctx.AddVariationDependencies(nil, optTag, u.presentOptionalUsesLibs(ctx)...) ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs...) ctx.AddVariationDependencies(nil, usesLibOptTag, u.presentOptionalUsesLibs(ctx)...) // Only add these extra dependencies if the module depends on framework libs. This avoids // creating a cyclic dependency: // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res. if hasFrameworkLibs { // Add implicit <uses-library> dependencies on compatibility libraries. Some of them are // optional, and some required --- this depends on the most common usage of the library // and may be wrong for some apps (they need explicit `uses_libs`/`optional_uses_libs`). compat28OptTag := makeUsesLibraryDependencyTag(28, true, true) ctx.AddVariationDependencies(nil, compat28OptTag, dexpreopt.OptionalCompatUsesLibs28...) compat29ReqTag := makeUsesLibraryDependencyTag(29, false, true) ctx.AddVariationDependencies(nil, compat29ReqTag, dexpreopt.CompatUsesLibs29...) compat30OptTag := makeUsesLibraryDependencyTag(30, true, true) ctx.AddVariationDependencies(nil, compat30OptTag, dexpreopt.OptionalCompatUsesLibs30...) // Dexpreopt needs paths to the dex jars of these libraries in order to construct // class loader context for dex2oat. Add them as a dependency with a special tag. ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...) ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...) ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...) } } } Loading Loading @@ -1307,7 +1296,7 @@ func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName) replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName) } clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, tag.implicit, clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, lib.DexJarBuildPath().PathOrNil(), lib.DexJarInstallPath(), lib.ClassLoaderContexts()) } else if ctx.Config().AllowMissingDependencies() { Loading
java/app_test.go +10 −2 Original line number Diff line number Diff line Loading @@ -2505,12 +2505,20 @@ func TestUsesLibraries(t *testing.T) { prebuilt := result.ModuleForTests("prebuilt", "android_common") // Test that implicit dependencies on java_sdk_library instances are passed to the manifest. // This should not include explicit `uses_libs`/`optional_uses_libs` entries. // These also include explicit `uses_libs`/`optional_uses_libs` entries, as they may be // propagated from dependencies. actualManifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"] expectManifestFixerArgs := `--extract-native-libs=true ` + `--uses-library qux ` + `--uses-library quuz ` + `--uses-library runtime-library` `--uses-library foo ` + `--uses-library com.non.sdk.lib ` + `--uses-library runtime-library ` + `--uses-library runtime-required-x ` + `--uses-library runtime-required-y ` + `--optional-uses-library bar ` + `--optional-uses-library runtime-optional-x ` + `--optional-uses-library runtime-optional-y` android.AssertStringDoesContain(t, "manifest_fixer args", actualManifestFixerArgs, expectManifestFixerArgs) // Test that all libraries are verified (library order matters). Loading