summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/androidmk.go6
-rwxr-xr-xjava/app.go3
-rw-r--r--java/app_import_test.go16
-rw-r--r--java/app_test.go2
-rw-r--r--java/base.go3
-rw-r--r--java/bootclasspath_fragment.go29
-rw-r--r--java/code_metadata_test.go19
-rw-r--r--java/config/config.go2
-rw-r--r--java/dex.go7
-rw-r--r--java/dexpreopt.go40
-rw-r--r--java/dexpreopt_bootjars.go166
-rw-r--r--java/dexpreopt_config.go2
-rw-r--r--java/dexpreopt_test.go6
-rw-r--r--java/droidstubs_test.go2
-rw-r--r--java/hiddenapi_modular.go20
-rw-r--r--java/java.go23
-rw-r--r--java/java_test.go4
-rw-r--r--java/platform_bootclasspath.go11
-rw-r--r--java/sdk_library.go25
-rw-r--r--java/sdk_library_test.go8
-rw-r--r--java/system_modules.go3
-rw-r--r--java/test_spec_test.go19
-rw-r--r--java/testing.go6
23 files changed, 281 insertions, 141 deletions
diff --git a/java/androidmk.go b/java/androidmk.go
index 809f9b563..cbf9abb96 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -207,11 +207,7 @@ func (j *TestHelperLibrary) AndroidMkEntries() []android.AndroidMkEntries {
func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries {
if prebuilt.hideApexVariantFromMake {
- // For a library imported from a prebuilt APEX, we don't need a Make module for itself, as we
- // don't need to install it. However, we need to add its dexpreopt outputs as sub-modules, if it
- // is preopted.
- dexpreoptEntries := prebuilt.dexpreopter.AndroidMkEntriesForApex()
- return append(dexpreoptEntries, android.AndroidMkEntries{Disabled: true})
+ return []android.AndroidMkEntries{}
}
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
diff --git a/java/app.go b/java/app.go
index 7f0303a6b..8b28dac78 100755
--- a/java/app.go
+++ b/java/app.go
@@ -22,7 +22,6 @@ import (
"path/filepath"
"strings"
- "android/soong/aconfig"
"android/soong/testing"
"github.com/google/blueprint"
@@ -509,7 +508,7 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
var aconfigTextFilePaths android.Paths
ctx.VisitDirectDepsWithTag(aconfigDeclarationTag, func(dep android.Module) {
- if provider, ok := android.OtherModuleProvider(ctx, dep, aconfig.DeclarationsProviderKey); ok {
+ if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
} else {
ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
diff --git a/java/app_import_test.go b/java/app_import_test.go
index 8f29bb373..ef4626e26 100644
--- a/java/app_import_test.go
+++ b/java/app_import_test.go
@@ -40,8 +40,8 @@ func TestAndroidAppImport(t *testing.T) {
variant := ctx.ModuleForTests("foo", "android_common")
// Check dexpreopt outputs.
- if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
- variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
+ if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
+ variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil {
t.Errorf("can't find dexpreopt outputs")
}
@@ -74,8 +74,8 @@ func TestAndroidAppImport_NoDexPreopt(t *testing.T) {
variant := ctx.ModuleForTests("foo", "android_common")
// Check dexpreopt outputs. They shouldn't exist.
- if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule != nil ||
- variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule != nil {
+ if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule != nil ||
+ variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule != nil {
t.Errorf("dexpreopt shouldn't have run.")
}
@@ -101,8 +101,8 @@ func TestAndroidAppImport_Presigned(t *testing.T) {
variant := ctx.ModuleForTests("foo", "android_common")
// Check dexpreopt outputs.
- if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
- variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
+ if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
+ variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil {
t.Errorf("can't find dexpreopt outputs")
}
// Make sure signing was skipped and aligning was done.
@@ -210,8 +210,8 @@ func TestAndroidAppImport_DefaultDevCert(t *testing.T) {
variant := ctx.ModuleForTests("foo", "android_common")
// Check dexpreopt outputs.
- if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
- variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
+ if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
+ variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil {
t.Errorf("can't find dexpreopt outputs")
}
diff --git a/java/app_test.go b/java/app_test.go
index 0936b281a..861c04761 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -3357,7 +3357,7 @@ func TestUsesLibraries(t *testing.T) {
cmd := app.Rule("dexpreopt").RuleParams.Command
android.AssertStringDoesContain(t, "dexpreopt app cmd context", cmd, "--context-json=")
android.AssertStringDoesContain(t, "dexpreopt app cmd product_packages", cmd,
- "--product-packages=out/soong/.intermediates/app/android_common/dexpreopt/product_packages.txt")
+ "--product-packages=out/soong/.intermediates/app/android_common/dexpreopt/app/product_packages.txt")
}
func TestDexpreoptBcp(t *testing.T) {
diff --git a/java/base.go b/java/base.go
index 41f2fcc96..0d3e4dbe3 100644
--- a/java/base.go
+++ b/java/base.go
@@ -24,7 +24,6 @@ import (
"github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
- "android/soong/aconfig"
"android/soong/android"
"android/soong/dexpreopt"
"android/soong/java/config"
@@ -1694,7 +1693,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
ctx.CheckbuildFile(outputFile)
- aconfig.CollectDependencyAconfigFiles(ctx, &j.mergedAconfigFiles)
+ android.CollectDependencyAconfigFiles(ctx, &j.mergedAconfigFiles)
android.SetProvider(ctx, JavaInfoProvider, JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index d2bb52315..ae2440466 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -240,7 +240,8 @@ type BootclasspathFragmentModule struct {
sourceOnlyProperties SourceOnlyBootclasspathProperties
// Path to the boot image profile.
- profilePath android.WritablePath
+ profilePath android.WritablePath
+ profilePathErr error
}
// commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt
@@ -384,6 +385,10 @@ func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(mod
}
}
+func (i BootclasspathFragmentApexContentInfo) DexBootJarPathMap() bootDexJarByModule {
+ return i.contentModuleDexJarPaths
+}
+
func (i BootclasspathFragmentApexContentInfo) ProfilePathOnHost() android.Path {
return i.profilePathOnHost
}
@@ -533,7 +538,7 @@ func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleC
if profile != nil {
info.profilePathOnHost = profile
- info.profileInstallPathInApex = profileInstallPathInApex
+ info.profileInstallPathInApex = ProfileInstallPathInApex
}
// Make the apex content info available for other modules.
@@ -1033,10 +1038,6 @@ func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx an
return android.PathForModuleSrc(ctx, *src)
}
- // Retrieve the dex files directly from the content modules. They in turn should retrieve the
- // encoded dex jars from the prebuilt .apex files.
- encodedBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, contents)
-
output := HiddenAPIOutput{
HiddenAPIFlagOutput: HiddenAPIFlagOutput{
AnnotationFlagsPath: pathForSrc("hidden_api.annotation_flags", module.prebuiltProperties.Hidden_api.Annotation_flags),
@@ -1047,8 +1048,6 @@ func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx an
StubFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Stub_flags, nil),
AllFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.All_flags, nil),
},
-
- EncodedBootDexFilesByModule: encodedBootDexJarsByModule,
}
// TODO: Temporarily fallback to stub_flags/all_flags properties until prebuilts have been updated.
@@ -1065,15 +1064,21 @@ func (module *PrebuiltBootclasspathFragmentModule) produceBootImageProfile(ctx a
return nil
}
- di := android.FindDeapexerProviderForModule(ctx)
- if di == nil {
+ di, err := android.FindDeapexerProviderForModule(ctx)
+ if err != nil {
+ // An error was found, possibly due to multiple apexes in the tree that export this library
+ // Defer the error till a client tries to call getProfilePath
+ module.profilePathErr = err
return nil // An error has been reported by FindDeapexerProviderForModule.
}
- return di.PrebuiltExportPath(profileInstallPathInApex)
+ return di.PrebuiltExportPath(ProfileInstallPathInApex)
}
func (b *PrebuiltBootclasspathFragmentModule) getProfilePath() android.Path {
+ if b.profilePathErr != nil {
+ panic(b.profilePathErr.Error())
+ }
return b.profilePath
}
@@ -1087,7 +1092,7 @@ var _ commonBootclasspathFragment = (*PrebuiltBootclasspathFragmentModule)(nil)
func (module *PrebuiltBootclasspathFragmentModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string {
for _, apex := range module.ApexProperties.Apex_available {
if isProfileProviderApex(ctx, apex) {
- return []string{profileInstallPathInApex}
+ return []string{ProfileInstallPathInApex}
}
}
return nil
diff --git a/java/code_metadata_test.go b/java/code_metadata_test.go
index 509e70112..0ef348afe 100644
--- a/java/code_metadata_test.go
+++ b/java/code_metadata_test.go
@@ -25,12 +25,10 @@ func TestCodeMetadata(t *testing.T) {
}`
result := runCodeMetadataTest(t, android.FixtureExpectsNoErrors, bp)
- module := result.ModuleForTests(
- "module-name", "",
- ).Module().(*soongTesting.CodeMetadataModule)
+ module := result.ModuleForTests("module-name", "")
// Check that the provider has the right contents
- data, _ := android.SingletonModuleProvider(result, module, soongTesting.CodeMetadataProviderKey)
+ data, _ := android.SingletonModuleProvider(result, module.Module(), soongTesting.CodeMetadataProviderKey)
if !strings.HasSuffix(
data.IntermediatePath.String(), "/intermediateCodeMetadata.pb",
) {
@@ -40,13 +38,8 @@ func TestCodeMetadata(t *testing.T) {
)
}
- buildParamsSlice := module.BuildParamsForTests()
- var metadata = ""
- for _, params := range buildParamsSlice {
- if params.Rule.String() == "android/soong/android.writeFile" {
- metadata = params.Args["content"]
- }
- }
+ metadata := android.ContentFromFileRuleForTests(t, result.TestContext,
+ module.Output(data.IntermediatePath.String()))
metadataList := make([]*code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership, 0, 2)
teamId := "12345"
@@ -63,9 +56,7 @@ func TestCodeMetadata(t *testing.T) {
CodeMetadataMetadata := code_metadata_internal_proto.CodeMetadataInternal{TargetOwnershipList: metadataList}
protoData, _ := proto.Marshal(&CodeMetadataMetadata)
- rawData := string(protoData)
- formattedData := strings.ReplaceAll(rawData, "\n", "\\n")
- expectedMetadata := "'" + formattedData + "\\n'"
+ expectedMetadata := string(protoData)
if metadata != expectedMetadata {
t.Errorf(
diff --git a/java/config/config.go b/java/config/config.go
index d80ed4142..6a945ac9c 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -95,13 +95,11 @@ func init() {
"-JXX:TieredStopAtLevel=1",
"-JDcom.android.tools.r8.emitRecordAnnotationsInDex",
"-JDcom.android.tools.r8.emitPermittedSubclassesAnnotationsInDex",
- "-JDcom.android.tools.r8.emitRecordAnnotationsExInDex",
}, dexerJavaVmFlagsList...))
exportedVars.ExportStringListStaticVariable("R8Flags", append([]string{
"-JXmx4096M",
"-JDcom.android.tools.r8.emitRecordAnnotationsInDex",
"-JDcom.android.tools.r8.emitPermittedSubclassesAnnotationsInDex",
- "-JDcom.android.tools.r8.emitRecordAnnotationsExInDex",
}, dexerJavaVmFlagsList...))
exportedVars.ExportStringListStaticVariable("CommonJdkFlags", []string{
diff --git a/java/dex.go b/java/dex.go
index cdae0a2df..fbb841860 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -223,6 +223,13 @@ func (d *dexer) dexCommonFlags(ctx android.ModuleContext,
if err != nil {
ctx.PropertyErrorf("min_sdk_version", "%s", err)
}
+ if effectiveVersion.FinalOrFutureInt() >= 35 {
+ // V is 35, but we have not bumped the SDK version yet, so check for both.
+ if ctx.Config().PlatformSdkVersion().FinalInt() >= 35 ||
+ ctx.Config().PlatformSdkCodename() == "VanillaIceCream" {
+ flags = append([]string{"-JDcom.android.tools.r8.dexContainerExperiment"}, flags...)
+ }
+ }
// If the specified SDK level is 10000, then configure the compiler to use the
// current platform SDK level and to compile the build as a platform build.
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 0f69dc3a4..bd3cce412 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -79,18 +79,25 @@ func (install *dexpreopterInstall) SubModuleName() string {
func (install dexpreopterInstall) ToMakeEntries() android.AndroidMkEntries {
return android.AndroidMkEntries{
Class: "ETC",
- SubName: install.SubModuleName(),
OutputFile: android.OptionalPathForPath(install.outputPathOnHost),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.SetString("LOCAL_MODULE", install.FullModuleName())
entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice)
entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false")
+ // Unset LOCAL_SOONG_INSTALLED_MODULE so that this does not default to the primary .apex file
+ // Without this, installation of the dexpreopt artifacts get skipped
+ entries.SetString("LOCAL_SOONG_INSTALLED_MODULE", "")
},
},
}
}
+type Dexpreopter struct {
+ dexpreopter
+}
+
type dexpreopter struct {
dexpreoptProperties DexpreoptProperties
importDexpreoptProperties ImportDexpreoptProperties
@@ -258,6 +265,17 @@ func (d *dexpreopter) getInstallPath(
return defaultInstallPath
}
+// DexpreoptPrebuiltApexSystemServerJars generates the dexpreopt artifacts from a jar file that has been deapexed from a prebuilt apex
+func (d *Dexpreopter) DexpreoptPrebuiltApexSystemServerJars(ctx android.ModuleContext, libraryName string, di *android.DeapexerInfo) {
+ // A single prebuilt apex can have multiple apex system jars
+ // initialize the output path for this dex jar
+ dc := dexpreopt.GetGlobalConfig(ctx)
+ d.installPath = android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexpreopt.GetSystemServerDexLocation(ctx, dc, libraryName), "/"))
+ // generate the rules for creating the .odex and .vdex files for this system server jar
+ dexJarFile := di.PrebuiltExportPath(ApexRootRelativePathToJavaLib(libraryName))
+ d.dexpreopt(ctx, dexJarFile)
+}
+
func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.WritablePath) {
global := dexpreopt.GetGlobalConfig(ctx)
@@ -346,11 +364,15 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
d.dexpreoptProperties.Dex_preopt_result.Profile_guided = profileClassListing.Valid()
+ // A single apex can have multiple system server jars
+ // Use the dexJar to create a unique scope for each
+ dexJarStem := strings.TrimSuffix(dexJarFile.Base(), dexJarFile.Ext())
+
// Full dexpreopt config, used to create dexpreopt build rules.
dexpreoptConfig := &dexpreopt.ModuleConfig{
Name: moduleName(ctx),
DexLocation: dexLocation,
- BuildPath: android.PathForModuleOut(ctx, "dexpreopt", moduleName(ctx)+".jar").OutputPath,
+ BuildPath: android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, moduleName(ctx)+".jar").OutputPath,
DexPath: dexJarFile,
ManifestPath: android.OptionalPathForPath(d.manifestFile),
UncompressedDex: d.uncompressedDex,
@@ -380,7 +402,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
PresignedPrebuilt: d.isPresignedPrebuilt,
}
- d.configPath = android.PathForModuleOut(ctx, "dexpreopt", "dexpreopt.config")
+ d.configPath = android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, "dexpreopt.config")
dexpreopt.WriteModuleConfig(ctx, dexpreoptConfig, d.configPath)
if d.dexpreoptDisabled(ctx) {
@@ -394,7 +416,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
// dependencies to create a per-app list, and use `rsync --checksum` to prevent the file's mtime
// from being changed if the contents don't change. This avoids unnecessary dexpreopt reruns.
productPackages := android.PathForModuleInPartitionInstall(ctx, "", "product_packages.txt")
- appProductPackages := android.PathForModuleOut(ctx, "dexpreopt", "product_packages.txt")
+ appProductPackages := android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, "product_packages.txt")
appProductPackagesStaging := appProductPackages.ReplaceExtension(ctx, "txt.tmp")
clcNames, _ := dexpreopt.ComputeClassLoaderContextDependencies(dexpreoptConfig.ClassLoaderContexts)
sort.Strings(clcNames) // The order needs to be deterministic.
@@ -416,7 +438,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
Text("rsync --checksum").
Input(appProductPackagesStaging).
Output(appProductPackages)
- productPackagesRule.Restat().Build("product_packages", "dexpreopt product_packages")
+ productPackagesRule.Restat().Build("product_packages."+dexJarStem, "dexpreopt product_packages")
dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(
ctx, globalSoong, global, dexpreoptConfig, appProductPackages)
@@ -425,9 +447,11 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
return
}
- dexpreoptRule.Build("dexpreopt", "dexpreopt")
+ dexpreoptRule.Build("dexpreopt"+"."+dexJarStem, "dexpreopt")
- isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx))
+ // The current ctx might be of a deapexer module created by a prebuilt apex
+ // Use the path of the dex file to determine the library name
+ isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(dexJarStem)
for _, install := range dexpreoptRule.Installs() {
// Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT.
@@ -452,7 +476,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
// The installs will be handled by Make as sub-modules of the java library.
d.builtInstalledForApex = append(d.builtInstalledForApex, dexpreopterInstall{
name: arch + "-" + installBase,
- moduleName: moduleName(ctx),
+ moduleName: dexJarStem,
outputPathOnHost: install.From,
installDirOnDevice: installPath,
installFileOnDevice: installBase,
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 5a19945b4..82cece346 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -21,6 +21,7 @@ import (
"android/soong/android"
"android/soong/dexpreopt"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -224,8 +225,9 @@ var artApexNames = []string{
}
var (
- dexpreoptBootJarDepTag = bootclasspathDependencyTag{name: "dexpreopt-boot-jar"}
- dexBootJarsFragmentsKey = android.NewOnceKey("dexBootJarsFragments")
+ dexpreoptBootJarDepTag = bootclasspathDependencyTag{name: "dexpreopt-boot-jar"}
+ dexBootJarsFragmentsKey = android.NewOnceKey("dexBootJarsFragments")
+ apexContributionsMetadataDepTag = dependencyTag{name: "all_apex_contributions"}
)
func init() {
@@ -502,6 +504,11 @@ type dexpreoptBootJars struct {
dexpreoptConfigForMake android.WritablePath
}
+func (dbj *dexpreoptBootJars) DepsMutator(ctx android.BottomUpMutatorContext) {
+ // Create a dependency on all_apex_contributions to determine the selected mainline module
+ ctx.AddDependency(ctx.Module(), apexContributionsMetadataDepTag, "all_apex_contributions")
+}
+
func DexpreoptBootJarsMutator(ctx android.BottomUpMutatorContext) {
if _, ok := ctx.Module().(*dexpreoptBootJars); !ok {
return
@@ -520,6 +527,14 @@ func DexpreoptBootJarsMutator(ctx android.BottomUpMutatorContext) {
}
// For accessing the boot jars.
addDependenciesOntoBootImageModules(ctx, config.modules, dexpreoptBootJarDepTag)
+ // Create a dependency on the apex selected using RELEASE_APEX_CONTRIBUTIONS_*
+ // TODO: b/308174306 - Remove the direct depedendency edge to the java_library (source/prebuilt) once all mainline modules
+ // have been flagged using RELEASE_APEX_CONTRIBUTIONS_*
+ apexes := []string{}
+ for i := 0; i < config.modules.Len(); i++ {
+ apexes = append(apexes, config.modules.Apex(i))
+ }
+ addDependenciesOntoSelectedBootImageApexes(ctx, android.FirstUniqueStrings(apexes)...)
}
if ctx.OtherModuleExists("platform-bootclasspath") {
@@ -532,6 +547,28 @@ func DexpreoptBootJarsMutator(ctx android.BottomUpMutatorContext) {
}
}
+// Create a dependency from dex_bootjars to the specific apexes selected using all_apex_contributions
+// This dependency will be used to get the path to the deapexed dex boot jars and profile (via a provider)
+func addDependenciesOntoSelectedBootImageApexes(ctx android.BottomUpMutatorContext, apexes ...string) {
+ psi := android.PrebuiltSelectionInfoMap{}
+ ctx.VisitDirectDepsWithTag(apexContributionsMetadataDepTag, func(am android.Module) {
+ if info, exists := android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider); exists {
+ psi = info
+ }
+ })
+ for _, apex := range apexes {
+ for _, selected := range psi.GetSelectedModulesForApiDomain(apex) {
+ // We need to add a dep on only the apex listed in `contents` of the selected apex_contributions module
+ // This is not available in a structured format in `apex_contributions`, so this hack adds a dep on all `contents`
+ // (some modules like art.module.public.api do not have an apex variation since it is a pure stub module that does not get installed)
+ apexVariationOfSelected := append(ctx.Target().Variations(), blueprint.Variation{Mutator: "apex", Variation: apex})
+ if ctx.OtherModuleDependencyVariantExists(apexVariationOfSelected, selected) {
+ ctx.AddFarVariationDependencies(apexVariationOfSelected, dexpreoptBootJarDepTag, selected)
+ }
+ }
+ }
+}
+
func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.Module {
return ctx.Config().Once(dexBootJarsFragmentsKey, func() interface{} {
fragments := make(map[string]android.Module)
@@ -662,36 +699,67 @@ func getModulesForImage(ctx android.ModuleContext, imageConfig *bootImageConfig)
// extractEncodedDexJarsFromModulesOrBootclasspathFragments gets the hidden API encoded dex jars for
// the given modules.
func extractEncodedDexJarsFromModulesOrBootclasspathFragments(ctx android.ModuleContext, apexJarModulePairs []apexJarModulePair) bootDexJarByModule {
+ apexNameToApexExportInfoMap := getApexNameToApexExportsInfoMap(ctx)
encodedDexJarsByModuleName := bootDexJarByModule{}
for _, pair := range apexJarModulePairs {
- var path android.Path
- if android.IsConfiguredJarForPlatform(pair.apex) || android.IsModulePrebuilt(pair.jarModule) {
- // This gives us the dex jar with the hidden API flags encoded from the monolithic hidden API
- // files or the dex jar extracted from a prebuilt APEX. We can't use this for a boot jar for
- // a source APEX because there is no guarantee that it is the same as the jar packed into the
- // APEX. In practice, they are the same when we are building from a full source tree, but they
- // are different when we are building from a thin manifest (e.g., master-art), where there is
- // no monolithic hidden API files at all.
- path = retrieveEncodedBootDexJarFromModule(ctx, pair.jarModule)
+ dexJarPath := getDexJarForApex(ctx, pair, apexNameToApexExportInfoMap)
+ encodedDexJarsByModuleName.addPath(pair.jarModule, dexJarPath)
+ }
+ return encodedDexJarsByModuleName
+}
+
+type apexNameToApexExportsInfoMap map[string]android.ApexExportsInfo
+
+// javaLibraryPathOnHost returns the path to the java library which is exported by the apex for hiddenapi and dexpreopt and a boolean indicating whether the java library exists
+// For prebuilt apexes, this is created by deapexing the prebuilt apex
+func (m *apexNameToApexExportsInfoMap) javaLibraryDexPathOnHost(ctx android.ModuleContext, apex string, javalib string) (android.Path, bool) {
+ if info, exists := (*m)[apex]; exists {
+ if dex, exists := info.LibraryNameToDexJarPathOnHost[javalib]; exists {
+ return dex, true
} else {
- // Use exactly the same jar that is packed into the APEX.
- fragment := getBootclasspathFragmentByApex(ctx, pair.apex)
- if fragment == nil {
- ctx.ModuleErrorf("Boot jar '%[1]s' is from APEX '%[2]s', but a bootclasspath_fragment for "+
- "APEX '%[2]s' doesn't exist or is not added as a dependency of dex_bootjars",
- pair.jarModule.Name(),
- pair.apex)
- }
- bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, fragment, BootclasspathFragmentApexContentInfoProvider)
- jar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(pair.jarModule)
- if err != nil {
- ctx.ModuleErrorf("%s", err)
- }
- path = jar
+ ctx.ModuleErrorf("Apex %s does not provide a dex boot jar for library %s\n", apex, javalib)
}
- encodedDexJarsByModuleName.addPath(pair.jarModule, path)
}
- return encodedDexJarsByModuleName
+ // An apex entry could not be found. Return false.
+ // TODO: b/308174306 - When all the mainline modules have been flagged, make this a hard error
+ return nil, false
+}
+
+// Returns the java libraries exported by the apex for hiddenapi and dexpreopt
+// This information can come from two mechanisms
+// 1. New: Direct deps to _selected_ apexes. The apexes return a ApexExportsInfo
+// 2. Legacy: An edge to java_library or java_import (java_sdk_library) module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes
+// TODO: b/308174306 - Once all mainline modules have been flagged, drop (2)
+func getDexJarForApex(ctx android.ModuleContext, pair apexJarModulePair, apexNameToApexExportsInfoMap apexNameToApexExportsInfoMap) android.Path {
+ if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, pair.apex, android.RemoveOptionalPrebuiltPrefix(pair.jarModule.Name())); found {
+ return dex
+ }
+ // TODO: b/308174306 - Remove the legacy mechanism
+ if android.IsConfiguredJarForPlatform(pair.apex) || android.IsModulePrebuilt(pair.jarModule) {
+ // This gives us the dex jar with the hidden API flags encoded from the monolithic hidden API
+ // files or the dex jar extracted from a prebuilt APEX. We can't use this for a boot jar for
+ // a source APEX because there is no guarantee that it is the same as the jar packed into the
+ // APEX. In practice, they are the same when we are building from a full source tree, but they
+ // are different when we are building from a thin manifest (e.g., master-art), where there is
+ // no monolithic hidden API files at all.
+ return retrieveEncodedBootDexJarFromModule(ctx, pair.jarModule)
+ } else {
+ // Use exactly the same jar that is packed into the APEX.
+ fragment := getBootclasspathFragmentByApex(ctx, pair.apex)
+ if fragment == nil {
+ ctx.ModuleErrorf("Boot jar '%[1]s' is from APEX '%[2]s', but a bootclasspath_fragment for "+
+ "APEX '%[2]s' doesn't exist or is not added as a dependency of dex_bootjars",
+ pair.jarModule.Name(),
+ pair.apex)
+ }
+ bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, fragment, BootclasspathFragmentApexContentInfoProvider)
+ jar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(pair.jarModule)
+ if err != nil {
+ ctx.ModuleErrorf("%s", err)
+ }
+ return jar
+ }
+ return nil
}
// copyBootJarsToPredefinedLocations generates commands that will copy boot jars to predefined
@@ -823,6 +891,37 @@ type bootImageVariantOutputs struct {
config *bootImageVariant
}
+// Returns the profile file for an apex
+// This information can come from two mechanisms
+// 1. New: Direct deps to _selected_ apexes. The apexes return a BootclasspathFragmentApexContentInfo
+// 2. Legacy: An edge to bootclasspath_fragment module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes
+// TODO: b/308174306 - Once all mainline modules have been flagged, drop (2)
+func getProfilePathForApex(ctx android.ModuleContext, apexName string, apexNameToBcpInfoMap map[string]android.ApexExportsInfo) android.Path {
+ if info, exists := apexNameToBcpInfoMap[apexName]; exists {
+ return info.ProfilePathOnHost
+ }
+ // TODO: b/308174306 - Remove the legacy mechanism
+ fragment := getBootclasspathFragmentByApex(ctx, apexName)
+ if fragment == nil {
+ ctx.ModuleErrorf("Boot image config imports profile from '%[2]s', but a "+
+ "bootclasspath_fragment for APEX '%[2]s' doesn't exist or is not added as a "+
+ "dependency of dex_bootjars",
+ apexName)
+ return nil
+ }
+ return fragment.(commonBootclasspathFragment).getProfilePath()
+}
+
+func getApexNameToApexExportsInfoMap(ctx android.ModuleContext) apexNameToApexExportsInfoMap {
+ apexNameToApexExportsInfoMap := apexNameToApexExportsInfoMap{}
+ ctx.VisitDirectDepsWithTag(dexpreoptBootJarDepTag, func(am android.Module) {
+ if info, exists := android.OtherModuleProvider(ctx, am, android.ApexExportsInfoProvider); exists {
+ apexNameToApexExportsInfoMap[info.ApexName] = info
+ }
+ })
+ return apexNameToApexExportsInfoMap
+}
+
// Generate boot image build rules for a specific target.
func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, profile android.Path) bootImageVariantOutputs {
@@ -865,6 +964,8 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
invocationPath := outputPath.ReplaceExtension(ctx, "invocation")
+ apexNameToApexExportsInfoMap := getApexNameToApexExportsInfoMap(ctx)
+
cmd.Tool(globalSoong.Dex2oat).
Flag("--avoid-storing-invocation").
FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath).
@@ -877,16 +978,7 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
}
for _, apex := range image.profileImports {
- fragment := getBootclasspathFragmentByApex(ctx, apex)
- if fragment == nil {
- ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but a "+
- "bootclasspath_fragment for APEX '%[2]s' doesn't exist or is not added as a "+
- "dependency of dex_bootjars",
- image.name,
- apex)
- return bootImageVariantOutputs{}
- }
- importedProfile := fragment.(commonBootclasspathFragment).getProfilePath()
+ importedProfile := getProfilePathForApex(ctx, apex, apexNameToApexExportsInfoMap)
if importedProfile == nil {
ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but '%[2]s' "+
"doesn't provide a profile",
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 2bd696c3d..254b2c1b0 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -45,7 +45,7 @@ var (
frameworkBootImageName = "boot"
mainlineBootImageName = "mainline"
bootImageStem = "boot"
- profileInstallPathInApex = "etc/boot-image.prof"
+ ProfileInstallPathInApex = "etc/boot-image.prof"
)
// getImageNames returns an ordered list of image names. The order doesn't matter but needs to be
diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go
index fedd5640e..73e33f4fb 100644
--- a/java/dexpreopt_test.go
+++ b/java/dexpreopt_test.go
@@ -410,7 +410,7 @@ func TestAndroidMkEntriesForApex(t *testing.T) {
verifyEntries(t,
"entriesList[0]",
"service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
- "/dexpreopt/oat/arm64/javalib.odex",
+ "/dexpreopt/service-foo/oat/arm64/javalib.odex",
"/system/framework/oat/arm64",
"apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
entriesList[0])
@@ -418,7 +418,7 @@ func TestAndroidMkEntriesForApex(t *testing.T) {
verifyEntries(t,
"entriesList[1]",
"service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
- "/dexpreopt/oat/arm64/javalib.vdex",
+ "/dexpreopt/service-foo/oat/arm64/javalib.vdex",
"/system/framework/oat/arm64",
"apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
entriesList[1])
@@ -459,7 +459,7 @@ func TestGenerateProfileEvenIfDexpreoptIsDisabled(t *testing.T) {
ctx := result.TestContext
dexpreopt := ctx.ModuleForTests("foo", "android_common").MaybeRule("dexpreopt")
- expected := []string{"out/soong/.intermediates/foo/android_common/dexpreopt/profile.prof"}
+ expected := []string{"out/soong/.intermediates/foo/android_common/dexpreopt/foo/profile.prof"}
android.AssertArrayString(t, "outputs", expected, dexpreopt.AllOutputs())
}
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index 17cad8958..7bcaca1d4 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -213,7 +213,7 @@ func TestDroidstubsSandbox(t *testing.T) {
}
manifest := android.RuleBuilderSboxProtoForTests(t, ctx, m.Output("metalava.sbox.textproto"))
- if g, w := manifest.Commands[0].GetCommand(), "reference __SBOX_SANDBOX_DIR__/out/.intermediates/foo/gen/foo.txt"; !strings.Contains(g, w) {
+ if g, w := manifest.Commands[0].GetCommand(), "reference __SBOX_SANDBOX_DIR__/out/soong/.intermediates/foo/gen/foo.txt"; !strings.Contains(g, w) {
t.Errorf("Expected command to contain %q, got %q", w, g)
}
}
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index 8011f343b..c3caa084f 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -19,6 +19,7 @@ import (
"strings"
"android/soong/android"
+ "android/soong/dexpreopt"
"github.com/google/blueprint"
)
@@ -947,6 +948,7 @@ type HiddenAPIOutput struct {
HiddenAPIFlagOutput
// The map from base module name to the path to the encoded boot dex file.
+ // This field is not available in prebuilt apexes
EncodedBootDexFilesByModule bootDexJarByModule
}
@@ -1249,9 +1251,27 @@ func buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, suffix s
}
// extractBootDexJarsFromModules extracts the boot dex jars from the supplied modules.
+// This information can come from two mechanisms
+// 1. New: Direct deps to _selected_ apexes. The apexes contain a ApexExportsInfo
+// 2. Legacy: An edge to java_sdk_library(_import) module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes
+// TODO: b/308174306 - Once all mainline modules have been flagged, drop (2)
func extractBootDexJarsFromModules(ctx android.ModuleContext, contents []android.Module) bootDexJarByModule {
bootDexJars := bootDexJarByModule{}
+
+ apexNameToApexExportsInfoMap := getApexNameToApexExportsInfoMap(ctx)
+ // For ART and mainline module jars, query apexNameToApexExportsInfoMap to get the dex file
+ apexJars := dexpreopt.GetGlobalConfig(ctx).ArtApexJars.AppendList(&dexpreopt.GetGlobalConfig(ctx).ApexBootJars)
+ for i := 0; i < apexJars.Len(); i++ {
+ if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, apexJars.Apex(i), apexJars.Jar(i)); found {
+ bootDexJars[apexJars.Jar(i)] = dex
+ }
+ }
+
+ // TODO - b/308174306: Drop the legacy mechanism
for _, module := range contents {
+ if _, exists := bootDexJars[android.RemoveOptionalPrebuiltPrefix(module.Name())]; exists {
+ continue
+ }
hiddenAPIModule := hiddenAPIModuleFromModule(ctx, module)
if hiddenAPIModule == nil {
continue
diff --git a/java/java.go b/java/java.go
index 630318e6d..2a4fafa8b 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2100,6 +2100,7 @@ type Import struct {
// output file containing classes.dex and resources
dexJarFile OptionalDexJarPath
+ dexJarFileErr error
dexJarInstallFile android.Path
combinedClasspathFile android.Path
@@ -2250,15 +2251,18 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
if ai.ForPrebuiltApex {
// Get the path of the dex implementation jar from the `deapexer` module.
- di := android.FindDeapexerProviderForModule(ctx)
- if di == nil {
- return // An error has been reported by FindDeapexerProviderForModule.
+ di, err := android.FindDeapexerProviderForModule(ctx)
+ if err != nil {
+ // An error was found, possibly due to multiple apexes in the tree that export this library
+ // Defer the error till a client tries to call DexJarBuildPath
+ j.dexJarFileErr = err
+ return
}
- dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(j.BaseModuleName())
+ dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(j.BaseModuleName())
if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil {
dexJarFile := makeDexJarPathFromPath(dexOutputPath)
j.dexJarFile = dexJarFile
- installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName()))
+ installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, ApexRootRelativePathToJavaLib(j.BaseModuleName()))
j.dexJarInstallFile = installPath
j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, installPath)
@@ -2375,6 +2379,9 @@ func (j *Import) ImplementationAndResourcesJars() android.Paths {
}
func (j *Import) DexJarBuildPath() OptionalDexJarPath {
+ if j.dexJarFileErr != nil {
+ panic(j.dexJarFileErr.Error())
+ }
return j.dexJarFile
}
@@ -2415,7 +2422,7 @@ func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
// java_sdk_library_import with the specified base module name requires to be exported from a
// prebuilt_apex/apex_set.
func requiredFilesFromPrebuiltApexForImport(name string, d *dexpreopter) []string {
- dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(name)
+ dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(name)
// Add the dex implementation jar to the set of exported files.
files := []string{
dexJarFileApexRootRelative,
@@ -2426,9 +2433,9 @@ func requiredFilesFromPrebuiltApexForImport(name string, d *dexpreopter) []strin
return files
}
-// apexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for
+// ApexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for
// the java library with the specified name.
-func apexRootRelativePathToJavaLib(name string) string {
+func ApexRootRelativePathToJavaLib(name string) string {
return filepath.Join("javalib", name+".jar")
}
diff --git a/java/java_test.go b/java/java_test.go
index e21018c39..b9dc453b3 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -618,8 +618,6 @@ func TestPrebuilts(t *testing.T) {
android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_library", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
entries = android.AndroidMkEntriesForTest(t, ctx, barModule.Module())[0]
android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
- entries = android.AndroidMkEntriesForTest(t, ctx, ctx.ModuleForTests("sdklib", "android_common").Module())[0]
- android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_sdk_library_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
}
func assertDeepEquals(t *testing.T, message string, expected interface{}, actual interface{}) {
@@ -2433,7 +2431,7 @@ func TestSdkLibraryProvidesSystemModulesToApiLibrary(t *testing.T) {
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest)
manifestCommand := sboxProto.Commands[0].GetCommand()
- classPathFlag := "--classpath __SBOX_SANDBOX_DIR__/out/.intermediates/bar/android_common/turbine-combined/bar.jar"
+ classPathFlag := "--classpath __SBOX_SANDBOX_DIR__/out/soong/.intermediates/bar/android_common/turbine-combined/bar.jar"
android.AssertStringDoesContain(t, "command expected to contain classpath flag", manifestCommand, classPathFlag)
}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 88d1ae8c0..4db426e0d 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -106,6 +106,9 @@ func (b *platformBootclasspathModule) OutputFiles(tag string) (android.Paths, er
}
func (b *platformBootclasspathModule) DepsMutator(ctx android.BottomUpMutatorContext) {
+ // Create a dependency on all_apex_contributions to determine the selected mainline module
+ ctx.AddDependency(ctx.Module(), apexContributionsMetadataDepTag, "all_apex_contributions")
+
b.hiddenAPIDepsMutator(ctx)
if !dexpreopt.IsDex2oatNeeded(ctx) {
@@ -130,6 +133,8 @@ func (b *platformBootclasspathModule) hiddenAPIDepsMutator(ctx android.BottomUpM
func (b *platformBootclasspathModule) BootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependencies on all the ART jars.
global := dexpreopt.GetGlobalConfig(ctx)
+ addDependenciesOntoSelectedBootImageApexes(ctx, "com.android.art")
+ // TODO: b/308174306 - Remove the mechanism of depending on the java_sdk_library(_import) directly
addDependenciesOntoBootImageModules(ctx, global.ArtApexJars, platformBootclasspathArtBootJarDepTag)
// Add dependencies on all the non-updatable jars, which are on the platform or in non-updatable
@@ -138,6 +143,12 @@ func (b *platformBootclasspathModule) BootclasspathDepsMutator(ctx android.Botto
// Add dependencies on all the updatable jars, except the ART jars.
apexJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars
+ apexes := []string{}
+ for i := 0; i < apexJars.Len(); i++ {
+ apexes = append(apexes, apexJars.Apex(i))
+ }
+ addDependenciesOntoSelectedBootImageApexes(ctx, android.FirstUniqueStrings(apexes)...)
+ // TODO: b/308174306 - Remove the mechanism of depending on the java_sdk_library(_import) directly
addDependenciesOntoBootImageModules(ctx, apexJars, platformBootclasspathApexBootJarDepTag)
// Add dependencies on all the fragments.
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 0584281a5..ef34fb6cd 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -2378,7 +2378,8 @@ type SdkLibraryImport struct {
xmlPermissionsFileModule *sdkLibraryXml
// Build path to the dex implementation jar obtained from the prebuilt_apex, if any.
- dexJarFile OptionalDexJarPath
+ dexJarFile OptionalDexJarPath
+ dexJarFileErr error
// Expected install file path of the source module(sdk_library)
// or dex implementation jar obtained from the prebuilt_apex, if any.
@@ -2591,14 +2592,6 @@ func (module *SdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext)
}
}
-func (module *SdkLibraryImport) AndroidMkEntries() []android.AndroidMkEntries {
- // For an SDK library imported from a prebuilt APEX, we don't need a Make module for itself, as we
- // don't need to install it. However, we need to add its dexpreopt outputs as sub-modules, if it
- // is preopted.
- dexpreoptEntries := module.dexpreopter.AndroidMkEntriesForApex()
- return append(dexpreoptEntries, android.AndroidMkEntries{Disabled: true})
-}
-
var _ android.ApexModule = (*SdkLibraryImport)(nil)
// Implements android.ApexModule
@@ -2695,11 +2688,14 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
if ai.ForPrebuiltApex {
// Get the path of the dex implementation jar from the `deapexer` module.
- di := android.FindDeapexerProviderForModule(ctx)
- if di == nil {
- return // An error has been reported by FindDeapexerProviderForModule.
+ di, err := android.FindDeapexerProviderForModule(ctx)
+ if err != nil {
+ // An error was found, possibly due to multiple apexes in the tree that export this library
+ // Defer the error till a client tries to call DexJarBuildPath
+ module.dexJarFileErr = err
+ return
}
- dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(module.BaseModuleName())
+ dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(module.BaseModuleName())
if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil {
dexJarFile := makeDexJarPathFromPath(dexOutputPath)
module.dexJarFile = dexJarFile
@@ -2759,6 +2755,9 @@ func (module *SdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleCont
func (module *SdkLibraryImport) DexJarBuildPath() OptionalDexJarPath {
// The dex implementation jar extracted from the .apex file should be used in preference to the
// source.
+ if module.dexJarFileErr != nil {
+ panic(module.dexJarFileErr.Error())
+ }
if module.dexJarFile.IsSet() {
return module.dexJarFile
}
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 0965fc2c7..63419d6b1 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -950,6 +950,7 @@ func TestJavaSdkLibraryImport_WithSource(t *testing.T) {
})
CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{
+ `all_apex_contributions`,
`prebuilt_sdklib.stubs`,
`sdklib.impl`,
// This should be prebuilt_sdklib.stubs but is set to sdklib.stubs because the
@@ -1022,6 +1023,7 @@ func testJavaSdkLibraryImport_Preferred(t *testing.T, prefer string, preparer an
})
CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{
+ `all_apex_contributions`,
`dex2oatd`,
`prebuilt_sdklib.stubs`,
`prebuilt_sdklib.stubs.source`,
@@ -1085,9 +1087,6 @@ func TestSdkLibraryImport_MetadataModuleSupersedesPreferred(t *testing.T) {
"prebuilt_sdklib.source_preferred_using_legacy_flags",
],
}
- all_apex_contributions {
- name: "all_apex_contributions",
- }
java_sdk_library {
name: "sdklib.prebuilt_preferred_using_legacy_flags",
srcs: ["a.java"],
@@ -1169,9 +1168,6 @@ func TestSdkLibraryImport_MetadataModuleSupersedesPreferred(t *testing.T) {
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("sdklib.source_preferred_using_legacy_flags", "sdklib.prebuilt_preferred_using_legacy_flags"),
- android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
- android.RegisterApexContributionsBuildComponents(ctx)
- }),
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.BuildFlags = map[string]string{
"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_mainline_module_contributions",
diff --git a/java/system_modules.go b/java/system_modules.go
index 1c7917109..f3446483b 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -55,7 +55,8 @@ var (
`${config.MergeZipsCmd} -j ${workDir}/module.jar ${workDir}/classes.jar $in && ` +
// Note: The version of the java.base module created must match the version
// of the jlink tool which consumes it.
- `${config.JmodCmd} create --module-version ${config.JlinkVersion} --target-platform android ` +
+ // Use LINUX-OTHER to be compatible with JDK 21+ (b/294137077)
+ `${config.JmodCmd} create --module-version ${config.JlinkVersion} --target-platform LINUX-OTHER ` +
` --class-path ${workDir}/module.jar ${workDir}/jmod/java.base.jmod && ` +
`${config.JlinkCmd} --module-path ${workDir}/jmod --add-modules java.base --output ${outDir} ` +
// Note: The system-modules jlink plugin is disabled because (a) it is not
diff --git a/java/test_spec_test.go b/java/test_spec_test.go
index f628b4b74..4144dad69 100644
--- a/java/test_spec_test.go
+++ b/java/test_spec_test.go
@@ -29,12 +29,10 @@ func TestTestSpec(t *testing.T) {
}`
result := runTestSpecTest(t, android.FixtureExpectsNoErrors, bp)
- module := result.ModuleForTests(
- "module-name", "",
- ).Module().(*soongTesting.TestSpecModule)
+ module := result.ModuleForTests("module-name", "")
// Check that the provider has the right contents
- data, _ := android.SingletonModuleProvider(result, module, soongTesting.TestSpecProviderKey)
+ data, _ := android.SingletonModuleProvider(result, module.Module(), soongTesting.TestSpecProviderKey)
if !strings.HasSuffix(
data.IntermediatePath.String(), "/intermediateTestSpecMetadata.pb",
) {
@@ -44,13 +42,8 @@ func TestTestSpec(t *testing.T) {
)
}
- buildParamsSlice := module.BuildParamsForTests()
- var metadata = ""
- for _, params := range buildParamsSlice {
- if params.Rule.String() == "android/soong/android.writeFile" {
- metadata = params.Args["content"]
- }
- }
+ metadata := android.ContentFromFileRuleForTests(t, result.TestContext,
+ module.Output(data.IntermediatePath.String()))
metadataList := make([]*test_spec_proto.TestSpec_OwnershipMetadata, 0, 2)
teamId := "12345"
@@ -70,9 +63,7 @@ func TestTestSpec(t *testing.T) {
}
testSpecMetadata := test_spec_proto.TestSpec{OwnershipMetadataList: metadataList}
protoData, _ := proto.Marshal(&testSpecMetadata)
- rawData := string(protoData)
- formattedData := strings.ReplaceAll(rawData, "\n", "\\n")
- expectedMetadata := "'" + formattedData + "\\n'"
+ expectedMetadata := string(protoData)
if metadata != expectedMetadata {
t.Errorf(
diff --git a/java/testing.go b/java/testing.go
index d55cffc40..5959c49e4 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -383,6 +383,7 @@ func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
RegisterSystemModulesBuildComponents(ctx)
registerSystemserverClasspathBuildComponents(ctx)
registerLintBuildComponents(ctx)
+ android.RegisterApexContributionsBuildComponents(ctx)
}
// gatherRequiredDepsForTest gathers the module definitions used by
@@ -570,6 +571,11 @@ func gatherRequiredDepsForTest() string {
}
`
+ bp += `
+ all_apex_contributions {
+ name: "all_apex_contributions",
+ }
+`
return bp
}