Merge "Add libc_nomalloc to mixed builds denylist."
diff --git a/apex/apex.go b/apex/apex.go
index 790f2e8..da4f472 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2153,7 +2153,10 @@
 
 	// Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
 	// hidden API encpding.
-	dexBootJar := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
+	dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
+	if err != nil {
+		ctx.ModuleErrorf("%s", err)
+	}
 
 	// Create an apexFile as for a normal java module but with the dex boot jar provided by the
 	// bootclasspath_fragment.
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index 7f5e15c..9a8c7d0 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -512,7 +512,10 @@
 
 	checkFragmentExportedDexJar := func(name string, expectedDexJar string) {
 		module := result.Module(name, "android_common_apex10000")
-		dexJar := info.DexBootJarPathForContentModule(module)
+		dexJar, err := info.DexBootJarPathForContentModule(module)
+		if err != nil {
+			t.Error(err)
+		}
 		android.AssertPathRelativeToTopEquals(t, name+" dex", expectedDexJar, dexJar)
 
 		expectedCopyCommand := fmt.Sprintf("&& cp -f %s out/soong/.intermediates/myapex/android_common_myapex_image/image.apex/javalib/%s.jar", expectedDexJar, name)
diff --git a/java/base.go b/java/base.go
index 0d2f1ac..f7989b8 100644
--- a/java/base.go
+++ b/java/base.go
@@ -1217,12 +1217,6 @@
 				return
 			}
 
-			// Initialize the hiddenapi structure.
-			j.initHiddenAPI(ctx, dexOutputFile, j.implementationJarFile, j.dexProperties.Uncompress_dex)
-
-			// Encode hidden API flags in dex file.
-			dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)
-
 			// merge dex jar with resources if necessary
 			if j.resourceJar != nil {
 				jars := android.Paths{dexOutputFile, j.resourceJar}
@@ -1238,6 +1232,12 @@
 				}
 			}
 
+			// Initialize the hiddenapi structure.
+			j.initHiddenAPI(ctx, dexOutputFile, j.implementationJarFile, j.dexProperties.Uncompress_dex)
+
+			// Encode hidden API flags in dex file, if needed.
+			dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)
+
 			j.dexJarFile = dexOutputFile
 
 			// Dexpreopting
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 5d8a8e5..6b395fb 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -273,6 +273,10 @@
 	// Will be nil if the BootclasspathFragmentApexContentInfo has not been provided for a specific module. That can occur
 	// when SkipDexpreoptBootJars(ctx) returns true.
 	imageConfig *bootImageConfig
+
+	// Map from the name of the context module (as returned by Name()) to the hidden API encoded dex
+	// jar path.
+	contentModuleDexJarPaths map[string]android.Path
 }
 
 func (i BootclasspathFragmentApexContentInfo) Modules() android.ConfiguredJarList {
@@ -299,10 +303,14 @@
 // DexBootJarPathForContentModule returns the path to the dex boot jar for specified module.
 //
 // The dex boot jar is one which has had hidden API encoding performed on it.
-func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(module android.Module) android.Path {
-	j := module.(UsesLibraryDependency)
-	dexJar := j.DexJarBuildPath()
-	return dexJar
+func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(module android.Module) (android.Path, error) {
+	name := module.Name()
+	if dexJar, ok := i.contentModuleDexJarPaths[name]; ok {
+		return dexJar, nil
+	} else {
+		return nil, fmt.Errorf("unknown bootclasspath_fragment content module %s, expected one of %s",
+			name, strings.Join(android.SortedStringKeys(i.contentModuleDexJarPaths), ", "))
+	}
 }
 
 func (b *BootclasspathFragmentModule) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
@@ -380,6 +388,28 @@
 	// Perform hidden API processing.
 	b.generateHiddenAPIBuildActions(ctx, contents)
 
+	// Verify that the image_name specified on a bootclasspath_fragment is valid even if this is a
+	// prebuilt which will not use the image config.
+	imageConfig := b.getImageConfig(ctx)
+
+	// A prebuilt fragment cannot contribute to the apex.
+	if !android.IsModulePrebuilt(ctx.Module()) {
+		// Provide the apex content info.
+		b.provideApexContentInfo(ctx, imageConfig, contents)
+	}
+}
+
+// provideApexContentInfo creates, initializes and stores the apex content info for use by other
+// modules.
+func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, contents []android.Module) {
+	// Construct the apex content info from the config.
+	info := BootclasspathFragmentApexContentInfo{
+		imageConfig: imageConfig,
+	}
+
+	// Populate the apex content info with paths to the dex jars.
+	b.populateApexContentInfoDexJars(ctx, &info, contents)
+
 	if !SkipDexpreoptBootJars(ctx) {
 		// Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
 		// GenerateSingletonBuildActions method as it cannot create it for itself.
@@ -387,11 +417,20 @@
 
 		// Only generate the boot image if the configuration does not skip it.
 		b.generateBootImageBuildActions(ctx, contents)
+	}
 
-		// Make the boot image info available for other modules
-		ctx.SetProvider(BootclasspathFragmentApexContentInfoProvider, BootclasspathFragmentApexContentInfo{
-			imageConfig: b.getImageConfig(ctx),
-		})
+	// Make the apex content info available for other modules.
+	ctx.SetProvider(BootclasspathFragmentApexContentInfoProvider, info)
+}
+
+// populateApexContentInfoDexJars adds paths to the dex jars provided by this fragment to the
+// apex content info.
+func (b *BootclasspathFragmentModule) populateApexContentInfoDexJars(ctx android.ModuleContext, info *BootclasspathFragmentApexContentInfo, contents []android.Module) {
+	info.contentModuleDexJarPaths = map[string]android.Path{}
+	for _, m := range contents {
+		j := m.(UsesLibraryDependency)
+		dexJar := j.DexJarBuildPath()
+		info.contentModuleDexJarPaths[m.Name()] = dexJar
 	}
 }
 
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index 1e83824..c9e3c29 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -235,7 +235,7 @@
 		  echo "--output-dex=$tmpDir/dex-output/$$(basename $${INPUT_DEX})";
 		done | xargs ${config.HiddenAPI} encode --api-flags=$flagsCsv $hiddenapiFlags &&
 		${config.SoongZipCmd} $soongZipFlags -o $tmpDir/dex.jar -C $tmpDir/dex-output -f "$tmpDir/dex-output/classes*.dex" &&
-		${config.MergeZipsCmd} -D -zipToNotStrip $tmpDir/dex.jar -stripFile "classes*.dex" -stripFile "**/*.uau" $out $tmpDir/dex.jar $in`,
+		${config.MergeZipsCmd} -j -D -zipToNotStrip $tmpDir/dex.jar -stripFile "classes*.dex" -stripFile "**/*.uau" $out $tmpDir/dex.jar $in`,
 	CommandDeps: []string{
 		"${config.HiddenAPI}",
 		"${config.SoongZipCmd}",