From 0b1c70efbcbb0c8408f44964923f5b156d025936 Mon Sep 17 00:00:00 2001 From: Ulya Trafimovich Date: Fri, 20 Aug 2021 15:39:12 +0100 Subject: [PATCH] Don't add `uses_libs`/`optional_uses_libs` to the manifest_fixer. These properties specify libraries that cannot be implicitly inferred by Soong. If these properties are added to Android.bp, this can only be for the reason that there is a tag in the manifest which is unknown to the build system. Adding them to the manifest_fixer doesn't make sense: if they are not in the manifest, they should be removed from Android.bp as well. Bug: 132357300 Test: $ lunch aosp_cf_x86_64_phone-userdebug && m && launch_cvd $ adb wait-for-device && adb root && adb logcat \ | grep -E 'ClassLoaderContext [a-z ]+ mismatch' # empty grep output, no errors Change-Id: Ic6eb5268a954ef3be7f06a181ec72af99000c547 --- dexpreopt/class_loader_context.go | 35 ++++++++++++--- dexpreopt/class_loader_context_test.go | 61 ++++++++++++++------------ java/android_manifest.go | 4 +- java/app.go | 27 ++++++++---- java/app_test.go | 9 +--- java/base.go | 6 +-- java/java.go | 28 +++++++----- 7 files changed, 104 insertions(+), 66 deletions(-) diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go index ebb8959d1..1bdd04002 100644 --- a/dexpreopt/class_loader_context.go +++ b/dexpreopt/class_loader_context.go @@ -196,6 +196,10 @@ 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 @@ -258,8 +262,9 @@ 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 bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) error { +func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathContext, sdkVer int, + lib string, optional, implicit bool, hostPath, installPath android.Path, + nestedClcMap ClassLoaderContextMap) error { // For prebuilts, library should have the same name as the source module. lib = android.RemoveOptionalPrebuiltPrefix(lib) @@ -308,6 +313,7 @@ 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, @@ -320,9 +326,10 @@ 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 bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) { + lib string, optional, implicit bool, hostPath, installPath android.Path, + nestedClcMap ClassLoaderContextMap) { - err := clcMap.addContext(ctx, sdkVer, lib, optional, hostPath, installPath, nestedClcMap) + err := clcMap.addContext(ctx, sdkVer, lib, optional, implicit, hostPath, installPath, nestedClcMap) if err != nil { ctx.ModuleErrorf(err.Error()) } @@ -366,13 +373,15 @@ func (clcMap ClassLoaderContextMap) AddContextMap(otherClcMap ClassLoaderContext // 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. // Required and optional libraries are in separate lists. -func (clcMap ClassLoaderContextMap) UsesLibs() (required []string, optional []string) { +func (clcMap ClassLoaderContextMap) usesLibs(implicit bool) (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 clc.Optional { + if implicit && !clc.Implicit { + // Skip, this is an explicit library and we need only the implicit ones. + } else if clc.Optional { optional = append(optional, clc.Name) } else { required = append(required, clc.Name) @@ -382,6 +391,14 @@ func (clcMap ClassLoaderContextMap) UsesLibs() (required []string, optional []st 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, "", " ") @@ -524,6 +541,8 @@ func computeClassLoaderContextRec(clcs []*ClassLoaderContext) (string, string, a // the same as Soong representation except that SDK versions and paths are represented with strings. type jsonClassLoaderContext struct { Name string + Optional bool + Implicit bool Host string Device string Subcontexts []*jsonClassLoaderContext @@ -555,6 +574,8 @@ func fromJsonClassLoaderContextRec(ctx android.PathContext, jClcs []*jsonClassLo for _, clc := range jClcs { 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), @@ -579,6 +600,8 @@ func toJsonClassLoaderContextRec(clcs []*ClassLoaderContext) []*jsonClassLoaderC for i, clc := range clcs { jClcs[i] = &jsonClassLoaderContext{ Name: clc.Name, + Optional: clc.Optional, + Implicit: clc.Implicit, Host: clc.Host.String(), Device: clc.Device, Subcontexts: toJsonClassLoaderContextRec(clc.Subcontexts), diff --git a/dexpreopt/class_loader_context_test.go b/dexpreopt/class_loader_context_test.go index 0b7b54620..d81ac2cbf 100644 --- a/dexpreopt/class_loader_context_test.go +++ b/dexpreopt/class_loader_context_test.go @@ -50,33 +50,34 @@ func TestCLC(t *testing.T) { ctx := testContext() optional := false + implicit := true m := make(ClassLoaderContextMap) - 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) + 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) // Add some libraries with nested subcontexts. m1 := make(ClassLoaderContextMap) - 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) + 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) m2 := make(ClassLoaderContextMap) - 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) + 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) m3 := make(ClassLoaderContextMap) - 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) + 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) - m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), m2) + m.AddContext(ctx, AnySdkVersion, "d", optional, implicit, 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, buildPath(ctx, "f"), installPath(ctx, "f"), nil) - m.AddContext(ctx, AnySdkVersion, "f", optional, buildPath(ctx, "f"), installPath(ctx, "f"), nil) + 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) // Merge map with implicit root library that is among toplevel contexts => does nothing. m.AddContextMap(m1, "c") @@ -85,12 +86,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, buildPath(ctx, AndroidHidlManager), nil, nil) - m.AddContext(ctx, 29, AndroidHidlBase, optional, buildPath(ctx, AndroidHidlBase), nil, nil) + m.AddContext(ctx, 29, AndroidHidlManager, optional, implicit, buildPath(ctx, AndroidHidlManager), nil, nil) + m.AddContext(ctx, 29, AndroidHidlBase, optional, implicit, 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, buildPath(ctx, AndroidTestMock), nil, nil) + m.AddContext(ctx, 30, AndroidTestMock, optional, implicit, buildPath(ctx, AndroidTestMock), nil, nil) valid, validationError := validateClassLoaderContext(m) @@ -164,11 +165,12 @@ 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, 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) + 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) jsonCLC := toJsonClassLoaderContext(m) restored := fromJsonClassLoaderContext(ctx, jsonCLC) android.AssertIntEquals(t, "The size of the maps should be the same.", len(m), len(restored)) @@ -189,12 +191,13 @@ 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, nil, nil, nil) + m.AddContext(ctx, AnySdkVersion, "a", optional, implicit, nil, nil, nil) } else { - m.AddContext(ctx, AnySdkVersion, "a", optional, buildPath(ctx, "a"), nil, nil) + m.AddContext(ctx, AnySdkVersion, "a", optional, implicit, buildPath(ctx, "a"), nil, nil) } // The library should be added to tags by the manifest_fixer. @@ -229,10 +232,11 @@ 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, buildPath(ctx, "a"), installPath(ctx, "a"), nil) + m1.AddContext(ctx, 42, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) m := make(ClassLoaderContextMap) - err := m.addContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), m1) + err := m.addContext(ctx, AnySdkVersion, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), m1) checkError(t, err, "nested class loader context shouldn't have conditional part") } @@ -241,11 +245,12 @@ 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, 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) + 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) valid, validationError := validateClassLoaderContext(m) diff --git a/java/android_manifest.go b/java/android_manifest.go index 1f7234d13..38065f153 100644 --- a/java/android_manifest.go +++ b/java/android_manifest.go @@ -71,7 +71,9 @@ func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext args = append(args, "--use-embedded-dex") } - requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs() + // manifest_fixer should add only the implicit SDK libraries inferred by Soong, not those added + // explicitly via `uses_libs`/`optional_uses_libs`. + requiredUsesLibs, optionalUsesLibs := classLoaderContexts.ImplicitUsesLibs() for _, usesLib := range requiredUsesLibs { args = append(args, "--uses-library", usesLib) } diff --git a/java/app.go b/java/app.go index e7661df6c..5104f07d6 100755 --- a/java/app.go +++ b/java/app.go @@ -1224,17 +1224,28 @@ 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, usesLibReqTag, u.usesLibraryProperties.Uses_libs...) - ctx.AddVariationDependencies(nil, usesLibOptTag, u.presentOptionalUsesLibs(ctx)...) + 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)...) + // 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, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...) - ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...) - ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...) + // Add implicit 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...) } } } @@ -1293,7 +1304,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, + clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, tag.implicit, 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 c14c65d18..56ad28d3e 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -2398,14 +2398,7 @@ func TestUsesLibraries(t *testing.T) { expectManifestFixerArgs := `--extract-native-libs=true ` + `--uses-library qux ` + `--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 runtime-library ` + - `--uses-library runtime-required-x ` + // TODO(b/132357300): "runtime-required-x" should not be passed to manifest_fixer - `--uses-library runtime-required-y ` + // TODO(b/132357300): "runtime-required-y" should not be passed to manifest_fixer - `--optional-uses-library bar ` + // TODO(b/132357300): "bar" should not be passed to manifest_fixer - `--optional-uses-library runtime-optional-x ` + // TODO(b/132357300): "runtime-optional-x" should not be passed to manifest_fixer - `--optional-uses-library runtime-optional-y` // TODO(b/132357300): "runtime-optional-y" should not be passed to manifest_fixer + `--uses-library runtime-library` 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 ea5b13721..8e6d1cd50 100644 --- a/java/base.go +++ b/java/base.go @@ -606,10 +606,8 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { if component, ok := dep.(SdkLibraryComponentDependency); ok { if lib := component.OptionalSdkLibraryImplementation(); lib != nil { // Add library as optional if it's one of the optional compatibility libs. - tag := usesLibReqTag - if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) { - tag = usesLibOptTag - } + optional := android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) + tag := makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, optional, true) ctx.AddVariationDependencies(nil, tag, *lib) } } diff --git a/java/java.go b/java/java.go index b46324f9f..4c2ca9ba2 100644 --- a/java/java.go +++ b/java/java.go @@ -248,15 +248,24 @@ type installDependencyTag struct { type usesLibraryDependencyTag struct { dependencyTag - sdkVersion int // SDK version in which the library appared as a standalone library. - optional bool // If the dependency is optional or required. + + // SDK version in which the library appared as a standalone library. + sdkVersion int + + // If the dependency is optional or required. + optional bool + + // Whether this is an implicit dependency inferred by Soong, or an explicit one added via + // `uses_libs`/`optional_uses_libs` properties. + implicit bool } -func makeUsesLibraryDependencyTag(sdkVersion int, optional bool) usesLibraryDependencyTag { +func makeUsesLibraryDependencyTag(sdkVersion int, optional bool, implicit bool) usesLibraryDependencyTag { return usesLibraryDependencyTag{ dependencyTag: dependencyTag{name: fmt.Sprintf("uses-library-%d", sdkVersion)}, sdkVersion: sdkVersion, optional: optional, + implicit: implicit, } } @@ -285,11 +294,6 @@ var ( syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"} jniInstallTag = installDependencyTag{name: "jni install"} binaryInstallTag = installDependencyTag{name: "binary install"} - 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 { @@ -1813,8 +1817,10 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, depTag := ctx.OtherModuleDependencyTag(depModule) 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 tag, ok := depTag.(usesLibraryDependencyTag); ok && + tag.sdkVersion == dexpreopt.AnySdkVersion && tag.implicit { + // Ok, propagate through non-compatibility implicit + // 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, @@ -1832,7 +1838,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, false, + clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false, true, dep.DexJarBuildPath(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) } else { clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)