diff --git a/apex/deapexer.go b/apex/deapexer.go index 1db13f916..9bc57209e 100644 --- a/apex/deapexer.go +++ b/apex/deapexer.go @@ -44,9 +44,13 @@ import ( // module.` type DeapexerProperties struct { // List of java libraries that are embedded inside this prebuilt APEX bundle and for which this - // APEX bundle will provide dex implementation jars for use by dexpreopt and boot jars package - // check. + // APEX bundle will create an APEX variant and provide dex implementation jars for use by + // dexpreopt and boot jars package check. Exported_java_libs []string + + // List of bootclasspath fragments inside this prebuiltd APEX bundle and for which this APEX + // bundle will create an APEX variant. + Exported_bootclasspath_fragments []string } type SelectedApexProperties struct { diff --git a/apex/prebuilt.go b/apex/prebuilt.go index a9d24a7c5..7830f95af 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -97,10 +97,17 @@ func (p *prebuiltCommon) checkForceDisable(ctx android.ModuleContext) bool { func (p *prebuiltCommon) deapexerDeps(ctx android.BottomUpMutatorContext) { // Add dependencies onto the java modules that represent the java libraries that are provided by // and exported from this prebuilt apex. - for _, lib := range p.deapexerProperties.Exported_java_libs { - dep := prebuiltApexExportedModuleName(ctx, lib) + for _, exported := range p.deapexerProperties.Exported_java_libs { + dep := prebuiltApexExportedModuleName(ctx, exported) ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), exportedJavaLibTag, dep) } + + // Add dependencies onto the bootclasspath fragment modules that are exported from this prebuilt + // apex. + for _, exported := range p.deapexerProperties.Exported_bootclasspath_fragments { + dep := prebuiltApexExportedModuleName(ctx, exported) + ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), exportedBootclasspathFragmentTag, dep) + } } // apexInfoMutator marks any modules for which this apex exports a file as requiring an apex @@ -137,18 +144,19 @@ func (p *prebuiltCommon) apexInfoMutator(mctx android.TopDownMutatorContext) { var dependencies []android.ApexModule mctx.VisitDirectDeps(func(m android.Module) { tag := mctx.OtherModuleDependencyTag(m) - if tag == exportedJavaLibTag { + if exportedTag, ok := tag.(exportedDependencyTag); ok { + propertyName := exportedTag.name depName := mctx.OtherModuleName(m) // It is an error if the other module is not a prebuilt. if _, ok := m.(android.PrebuiltInterface); !ok { - mctx.PropertyErrorf("exported_java_libs", "%q is not a prebuilt module", depName) + mctx.PropertyErrorf(propertyName, "%q is not a prebuilt module", depName) return } // It is an error if the other module is not an ApexModule. if _, ok := m.(android.ApexModule); !ok { - mctx.PropertyErrorf("exported_java_libs", "%q is not usable within an apex", depName) + mctx.PropertyErrorf(propertyName, "%q is not usable within an apex", depName) return } @@ -451,7 +459,8 @@ type exportedDependencyTag struct { func (t exportedDependencyTag) ExcludeFromVisibilityEnforcement() {} var ( - exportedJavaLibTag = exportedDependencyTag{name: "exported_java_lib"} + exportedJavaLibTag = exportedDependencyTag{name: "exported_java_libs"} + exportedBootclasspathFragmentTag = exportedDependencyTag{name: "exported_bootclasspath_fragments"} ) func (p *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) { diff --git a/java/boot_image.go b/java/boot_image.go index d0862a961..6f50c27e6 100644 --- a/java/boot_image.go +++ b/java/boot_image.go @@ -124,8 +124,22 @@ func bootImageConsistencyCheck(ctx android.EarlyModuleContext, m *BootImageModul if m.properties.Image_name != nil && len(contents) != 0 { ctx.ModuleErrorf(`both of the "image_name" and "contents" properties have been supplied, please supply exactly one`) } + imageName := proptools.String(m.properties.Image_name) if imageName == "art" { + // TODO(b/177892522): Prebuilts (versioned or not) should not use the image_name property. + if m.MemberName() != "" { + // The module is a versioned prebuilt so ignore it. This is done for a couple of reasons: + // 1. There is no way to use this at the moment so ignoring it is safe. + // 2. Attempting to initialize the contents property from the configuration will end up having + // the versioned prebuilt depending on the unversioned prebuilt. That will cause problems + // as the unversioned prebuilt could end up with an APEX variant created for the source + // APEX which will prevent it from having an APEX variant for the prebuilt APEX which in + // turn will prevent it from accessing the dex implementation jar from that which will + // break hidden API processing, amongst others. + return + } + // Get the configuration for the art apex jars. Do not use getImageConfig(ctx) here as this is // too early in the Soong processing for that to work. global := dexpreopt.GetGlobalConfig(ctx) diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go index 0ce4351eb..ef4d7cd45 100644 --- a/sdk/bootclasspath_fragment_sdk_test.go +++ b/sdk/bootclasspath_fragment_sdk_test.go @@ -24,6 +24,7 @@ import ( func TestSnapshotWithBootclasspathFragment_ImageName(t *testing.T) { result := android.GroupFixturePreparers( prepareForSdkTestWithJava, + java.PrepareForTestWithJavaDefaultModules, prepareForSdkTestWithApex, // Some additional files needed for the art apex. @@ -32,6 +33,20 @@ func TestSnapshotWithBootclasspathFragment_ImageName(t *testing.T) { "com.android.art.pem": nil, "system/sepolicy/apex/com.android.art-file_contexts": nil, }), + + // platform_bootclasspath that depends on the fragment. + android.FixtureAddTextFile("frameworks/base/boot/Android.bp", ` + platform_bootclasspath { + name: "platform-bootclasspath", + fragments: [ + { + apex: "com.android.art", + module: "mybootclasspathfragment", + }, + ], + } + `), + java.FixtureConfigureBootJars("com.android.art:mybootlib"), android.FixtureWithRootAndroidBp(` sdk { @@ -72,6 +87,23 @@ func TestSnapshotWithBootclasspathFragment_ImageName(t *testing.T) { `), ).RunTest(t) + // A preparer to add a prebuilt apex to the test fixture. + prepareWithPrebuiltApex := android.GroupFixturePreparers( + android.FixtureAddTextFile("prebuilts/apex/Android.bp", ` + prebuilt_apex { + name: "com.android.art", + src: "art.apex", + exported_java_libs: [ + "mybootlib", + ], + exported_bootclasspath_fragments: [ + "mybootclasspathfragment", + ], + } + `), + android.FixtureAddFile("prebuilts/apex/art.apex", nil), + ) + CheckSnapshot(t, result, "mysdk", "", checkUnversionedAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -121,19 +153,9 @@ sdk_snapshot { checkAllCopyRules(` .intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar `), - snapshotTestPreparer(checkSnapshotPreferredWithSource, android.GroupFixturePreparers( - android.FixtureAddTextFile("prebuilts/apex/Android.bp", ` - prebuilt_apex { - name: "com.android.art", - src: "art.apex", - exported_java_libs: [ - "mybootlib", - ], - } - `), - android.FixtureAddFile("prebuilts/apex/art.apex", nil), - ), - ), + snapshotTestPreparer(checkSnapshotWithoutSource, prepareWithPrebuiltApex), + snapshotTestPreparer(checkSnapshotWithSourcePreferred, prepareWithPrebuiltApex), + snapshotTestPreparer(checkSnapshotPreferredWithSource, prepareWithPrebuiltApex), ) } diff --git a/sdk/testing.go b/sdk/testing.go index bf59aeda0..f4e85c0cf 100644 --- a/sdk/testing.go +++ b/sdk/testing.go @@ -254,6 +254,7 @@ func CheckSnapshot(t *testing.T, result *android.TestResult, name string, dir st snapshotPreparer := android.GroupFixturePreparers(sourcePreparers, fs.AddToFixture()) var runSnapshotTestWithCheckers = func(t *testing.T, testConfig snapshotTest, extraPreparer android.FixturePreparer) { + t.Helper() customization := snapshotBuildInfo.snapshotTestCustomization(testConfig) customizedPreparers := android.GroupFixturePreparers(customization.preparers...)