diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go index 245af2cea..ebb8959d1 100644 --- a/dexpreopt/class_loader_context.go +++ b/dexpreopt/class_loader_context.go @@ -193,6 +193,9 @@ type ClassLoaderContext struct { // 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 @@ 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, - 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 @@ func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathCont clcMap[sdkVer] = append(clcMap[sdkVer], &ClassLoaderContext{ Name: lib, + Optional: optional, Host: hostPath, Device: devicePath, Subcontexts: subcontexts, @@ -316,9 +320,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, 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 @@ func (clcMap ClassLoaderContextMap) AddContextMap(otherClcMap ClassLoaderContext // 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 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 @@ func (clcMap ClassLoaderContextMap) Dump() string { // 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 { diff --git a/dexpreopt/class_loader_context_test.go b/dexpreopt/class_loader_context_test.go index 610a4c9ec..0b7b54620 100644 --- a/dexpreopt/class_loader_context_test.go +++ b/dexpreopt/class_loader_context_test.go @@ -49,32 +49,34 @@ func TestCLC(t *testing.T) { // ctx := testContext() + optional := false + m := make(ClassLoaderContextMap) - m.AddContext(ctx, AnySdkVersion, "a", buildPath(ctx, "a"), installPath(ctx, "a"), nil) - m.AddContext(ctx, AnySdkVersion, "b", buildPath(ctx, "b"), installPath(ctx, "b"), nil) - m.AddContext(ctx, AnySdkVersion, "c", 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", buildPath(ctx, "a1"), installPath(ctx, "a1"), nil) - m1.AddContext(ctx, AnySdkVersion, "b1", 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", buildPath(ctx, "a2"), installPath(ctx, "a2"), nil) - m2.AddContext(ctx, AnySdkVersion, "b2", buildPath(ctx, "b2"), installPath(ctx, "b2"), nil) - m2.AddContext(ctx, AnySdkVersion, "c2", 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", buildPath(ctx, "a3"), installPath(ctx, "a3"), nil) - m3.AddContext(ctx, AnySdkVersion, "b3", 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", 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", buildPath(ctx, "f"), installPath(ctx, "f"), nil) - m.AddContext(ctx, AnySdkVersion, "f", 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") @@ -83,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, buildPath(ctx, AndroidHidlManager), nil, nil) - m.AddContext(ctx, 29, AndroidHidlBase, 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, buildPath(ctx, AndroidTestMock), nil, nil) + m.AddContext(ctx, 30, AndroidTestMock, optional, buildPath(ctx, AndroidTestMock), nil, nil) valid, validationError := validateClassLoaderContext(m) @@ -96,10 +98,10 @@ func TestCLC(t *testing.T) { var haveStr string var havePaths android.Paths - var haveUsesLibs []string + var haveUsesLibsReq, haveUsesLibsOpt []string if valid && validationError == nil { haveStr, havePaths = ComputeClassLoaderContext(m) - haveUsesLibs = m.UsesLibs() + haveUsesLibsReq, haveUsesLibsOpt = m.UsesLibs() } // Test that validation is successful (all paths are known). @@ -148,20 +150,25 @@ func TestCLC(t *testing.T) { // Test for libraries that are added by the manifest_fixer. t.Run("uses libs", func(t *testing.T) { - wantUsesLibs := []string{"a", "b", "c", "d", "f", "a3", "b3"} - if !reflect.DeepEqual(wantUsesLibs, haveUsesLibs) { - t.Errorf("\nwant uses libs: %s\nhave uses libs: %s", wantUsesLibs, haveUsesLibs) + wantUsesLibsReq := []string{"a", "b", "c", "d", "f", "a3", "b3"} + wantUsesLibsOpt := []string{} + if !reflect.DeepEqual(wantUsesLibsReq, haveUsesLibsReq) { + t.Errorf("\nwant required uses libs: %s\nhave required uses libs: %s", wantUsesLibsReq, haveUsesLibsReq) + } + if !reflect.DeepEqual(wantUsesLibsOpt, haveUsesLibsOpt) { + t.Errorf("\nwant optional uses libs: %s\nhave optional uses libs: %s", wantUsesLibsOpt, haveUsesLibsOpt) } }) } func TestCLCJson(t *testing.T) { ctx := testContext() + optional := false m := make(ClassLoaderContextMap) - m.AddContext(ctx, 28, "a", buildPath(ctx, "a"), installPath(ctx, "a"), nil) - m.AddContext(ctx, 29, "b", buildPath(ctx, "b"), installPath(ctx, "b"), nil) - m.AddContext(ctx, 30, "c", buildPath(ctx, "c"), installPath(ctx, "c"), nil) - m.AddContext(ctx, AnySdkVersion, "d", 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)) @@ -181,20 +188,25 @@ func TestCLCJson(t *testing.T) { // Test that unknown library paths cause a validation error. func testCLCUnknownPath(t *testing.T, whichPath string) { ctx := testContext() + optional := false m := make(ClassLoaderContextMap) if whichPath == "build" { - m.AddContext(ctx, AnySdkVersion, "a", nil, nil, nil) + m.AddContext(ctx, AnySdkVersion, "a", optional, nil, nil, nil) } else { - m.AddContext(ctx, AnySdkVersion, "a", buildPath(ctx, "a"), nil, nil) + m.AddContext(ctx, AnySdkVersion, "a", optional, buildPath(ctx, "a"), nil, nil) } // The library should be added to tags by the manifest_fixer. t.Run("uses libs", func(t *testing.T) { - haveUsesLibs := m.UsesLibs() - wantUsesLibs := []string{"a"} - if !reflect.DeepEqual(wantUsesLibs, haveUsesLibs) { - t.Errorf("\nwant uses libs: %s\nhave uses libs: %s", wantUsesLibs, haveUsesLibs) + haveUsesLibsReq, haveUsesLibsOpt := m.UsesLibs() + wantUsesLibsReq := []string{"a"} + wantUsesLibsOpt := []string{} + if !reflect.DeepEqual(wantUsesLibsReq, haveUsesLibsReq) { + t.Errorf("\nwant required uses libs: %s\nhave required uses libs: %s", wantUsesLibsReq, haveUsesLibsReq) + } + if !reflect.DeepEqual(wantUsesLibsOpt, haveUsesLibsOpt) { + t.Errorf("\nwant optional uses libs: %s\nhave optional uses libs: %s", wantUsesLibsOpt, haveUsesLibsOpt) } }) @@ -216,10 +228,11 @@ func TestCLCUnknownInstallPath(t *testing.T) { // An attempt to add conditional nested subcontext should fail. func TestCLCNestedConditional(t *testing.T) { ctx := testContext() + optional := false m1 := make(ClassLoaderContextMap) - m1.AddContext(ctx, 42, "a", 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", 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") } @@ -227,11 +240,12 @@ func TestCLCNestedConditional(t *testing.T) { // they end up in the order that agrees with PackageManager. func TestCLCSdkVersionOrder(t *testing.T) { ctx := testContext() + optional := false m := make(ClassLoaderContextMap) - m.AddContext(ctx, 28, "a", buildPath(ctx, "a"), installPath(ctx, "a"), nil) - m.AddContext(ctx, 29, "b", buildPath(ctx, "b"), installPath(ctx, "b"), nil) - m.AddContext(ctx, 30, "c", buildPath(ctx, "c"), installPath(ctx, "c"), nil) - m.AddContext(ctx, AnySdkVersion, "d", 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) diff --git a/java/android_manifest.go b/java/android_manifest.go index 331f941ec..1f7234d13 100644 --- a/java/android_manifest.go +++ b/java/android_manifest.go @@ -71,12 +71,12 @@ func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext args = append(args, "--use-embedded-dex") } - for _, usesLib := range classLoaderContexts.UsesLibs() { - if inList(usesLib, dexpreopt.OptionalCompatUsesLibs) { - args = append(args, "--optional-uses-library", usesLib) - } else { - args = append(args, "--uses-library", usesLib) - } + requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs() + for _, usesLib := range requiredUsesLibs { + args = append(args, "--uses-library", usesLib) + } + for _, usesLib := range optionalUsesLibs { + args = append(args, "--optional-uses-library", usesLib) } if hasNoCode { diff --git a/java/androidmk.go b/java/androidmk.go index 04357e066..68ccd82e9 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -114,7 +114,8 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries { entries.SetPath("LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR", library.jacocoReportClassesFile) } - entries.AddStrings("LOCAL_EXPORT_SDK_LIBRARIES", library.classLoaderContexts.UsesLibs()...) + requiredUsesLibs, optionalUsesLibs := library.classLoaderContexts.UsesLibs() + entries.AddStrings("LOCAL_EXPORT_SDK_LIBRARIES", append(requiredUsesLibs, optionalUsesLibs...)...) if len(library.additionalCheckedModules) != 0 { entries.AddStrings("LOCAL_ADDITIONAL_CHECKED_MODULE", library.additionalCheckedModules.Strings()...) diff --git a/java/app.go b/java/app.go index 35ed27f52..99e2ab68c 100755 --- a/java/app.go +++ b/java/app.go @@ -649,8 +649,12 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { a.usesLibrary.freezeEnforceUsesLibraries() // Add implicit SDK libraries to list. - for _, usesLib := range a.classLoaderContexts.UsesLibs() { - a.usesLibrary.addLib(usesLib, inList(usesLib, dexpreopt.OptionalCompatUsesLibs)) + requiredUsesLibs, optionalUsesLibs := a.classLoaderContexts.UsesLibs() + for _, usesLib := range requiredUsesLibs { + a.usesLibrary.addLib(usesLib, false) + } + for _, usesLib := range optionalUsesLibs { + a.usesLibrary.addLib(usesLib, true) } // Check that the list is coherent with the manifest. @@ -1220,17 +1224,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() { - ctx.AddVariationDependencies(nil, usesLibTag, u.usesLibraryProperties.Uses_libs...) - ctx.AddVariationDependencies(nil, usesLibTag, 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 { // 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, usesLibCompat29Tag, dexpreopt.CompatUsesLibs29...) - ctx.AddVariationDependencies(nil, usesLibCompat28Tag, dexpreopt.OptionalCompatUsesLibs28...) - ctx.AddVariationDependencies(nil, usesLibCompat30Tag, dexpreopt.OptionalCompatUsesLibs30...) + ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...) + ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...) + ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...) } } } @@ -1289,7 +1293,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, + clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, lib.DexJarBuildPath(), lib.DexJarInstallPath(), lib.ClassLoaderContexts()) } else if ctx.Config().AllowMissingDependencies() { ctx.AddMissingDependencies([]string{dep}) diff --git a/java/app_test.go b/java/app_test.go index 7997f7ad8..8de669146 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -2355,8 +2355,8 @@ func TestUsesLibraries(t *testing.T) { `--uses-library quuz ` + `--uses-library foo ` + // TODO(b/132357300): "foo" should not be passed to manifest_fixer `--uses-library com.non.sdk.lib ` + // TODO(b/132357300): "com.non.sdk.lib" should not be passed to manifest_fixer - `--uses-library bar ` + // TODO(b/132357300): "bar" should not be passed to manifest_fixer - `--uses-library runtime-library` + `--uses-library runtime-library ` + + `--optional-uses-library bar` // TODO(b/132357300): "bar" should not be passed to manifest_fixer android.AssertStringEquals(t, "manifest_fixer args", expectManifestFixerArgs, actualManifestFixerArgs) // Test that all libraries are verified (library order matters). diff --git a/java/base.go b/java/base.go index d8cd6b3c1..ea5b13721 100644 --- a/java/base.go +++ b/java/base.go @@ -605,7 +605,12 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { if dep != nil { if component, ok := dep.(SdkLibraryComponentDependency); ok { if lib := component.OptionalSdkLibraryImplementation(); lib != nil { - ctx.AddVariationDependencies(nil, usesLibTag, *lib) + // Add library as optional if it's one of the optional compatibility libs. + tag := usesLibReqTag + if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) { + tag = usesLibOptTag + } + ctx.AddVariationDependencies(nil, tag, *lib) } } } diff --git a/java/java.go b/java/java.go index b6e2a5425..5bf3d79fb 100644 --- a/java/java.go +++ b/java/java.go @@ -248,13 +248,15 @@ type installDependencyTag struct { type usesLibraryDependencyTag struct { dependencyTag - sdkVersion int // SDK version in which the library appared as a standalone library. + sdkVersion int // SDK version in which the library appared as a standalone library. + optional bool // If the dependency is optional or required. } -func makeUsesLibraryDependencyTag(sdkVersion int) usesLibraryDependencyTag { +func makeUsesLibraryDependencyTag(sdkVersion int, optional bool) usesLibraryDependencyTag { return usesLibraryDependencyTag{ dependencyTag: dependencyTag{name: fmt.Sprintf("uses-library-%d", sdkVersion)}, sdkVersion: sdkVersion, + optional: optional, } } @@ -283,10 +285,11 @@ var ( syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"} jniInstallTag = installDependencyTag{name: "jni install"} binaryInstallTag = installDependencyTag{name: "binary install"} - usesLibTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion) - usesLibCompat28Tag = makeUsesLibraryDependencyTag(28) - usesLibCompat29Tag = makeUsesLibraryDependencyTag(29) - usesLibCompat30Tag = makeUsesLibraryDependencyTag(30) + usesLibReqTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false) + usesLibOptTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true) + usesLibCompat28OptTag = makeUsesLibraryDependencyTag(28, true) + usesLibCompat29ReqTag = makeUsesLibraryDependencyTag(29, false) + usesLibCompat30OptTag = makeUsesLibraryDependencyTag(30, true) ) func IsLibDepTag(depTag blueprint.DependencyTag) bool { @@ -1807,8 +1810,10 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, } depTag := ctx.OtherModuleDependencyTag(depModule) - if depTag == libTag || depTag == usesLibTag { + if depTag == libTag { // Ok, propagate through non-static library dependencies. + } else if tag, ok := depTag.(usesLibraryDependencyTag); ok && tag.sdkVersion == dexpreopt.AnySdkVersion { + // Ok, propagate through non-compatibility dependencies. } else if depTag == staticLibTag { // Propagate through static library dependencies, unless it is a component // library (such as stubs). Component libraries have a dependency on their SDK library, @@ -1826,7 +1831,7 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, // and should not be added to CLC, but the transitive dependencies // from its CLC should be added to the current CLC. if sdkLib != nil { - clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, + clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false, dep.DexJarBuildPath(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) } else { clcMap.AddContextMap(dep.ClassLoaderContexts(), depName) diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index 8e0618e31..eeec50482 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -156,8 +156,9 @@ func TestJavaSdkLibrary(t *testing.T) { // test if baz has exported SDK lib names foo and bar to qux qux := result.ModuleForTests("qux", "android_common") if quxLib, ok := qux.Module().(*Library); ok { - sdkLibs := quxLib.ClassLoaderContexts().UsesLibs() - android.AssertDeepEquals(t, "qux exports", []string{"foo", "bar", "fred", "quuz"}, sdkLibs) + requiredSdkLibs, optionalSdkLibs := quxLib.ClassLoaderContexts().UsesLibs() + android.AssertDeepEquals(t, "qux exports (required)", []string{"foo", "bar", "fred", "quuz"}, requiredSdkLibs) + android.AssertDeepEquals(t, "qux exports (optional)", []string{}, optionalSdkLibs) } }