bootclasspath_fragment must only depend on source contents

This change ensures that bootclasspath_fragment only depends on source
modules and prebuilt_bootclasspath_fragment only depends on prebuilt
modules.

It does that in two ways:
1. It adds the dependencies in ComponentDepsMutator method which is
   called before any renaming of prebuilts is done which makes it very
   easy to add a dependency directly onto either the source or prebuilt
   as required.
2. It uses a tag which prevents dependencies on a source module from
   being replaced with a dependency on a prebuilt module which ensures
   that a dependency on the source modules is not replaced with a
   dependency on a prebuilt module.

Bug: 177892522
Test: m nothing
Change-Id: Ibcfae39083afbc07fcf729ead3ed5f5d020845bf
diff --git a/apex/apex.go b/apex/apex.go
index 6f02c47..efeb0e2 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1924,7 +1924,7 @@
 					// Rlib is statically linked, but it might have shared lib
 					// dependencies. Track them.
 					return true
-				} else if java.IsbootImageContentDepTag(depTag) {
+				} else if java.IsBootclasspathFragmentContentDepTag(depTag) {
 					// Add the contents of the bootclasspath fragment to the apex.
 					switch child.(type) {
 					case *java.Library, *java.SdkLibrary:
diff --git a/apex/boot_image_test.go b/apex/boot_image_test.go
index e18c2ea..dab72f7 100644
--- a/apex/boot_image_test.go
+++ b/apex/boot_image_test.go
@@ -216,6 +216,22 @@
 			],
 		}
 
+		java_import {
+			name: "foo",
+			jars: ["foo.jar"],
+			apex_available: [
+				"com.android.art",
+			],
+		}
+
+		java_import {
+			name: "bar",
+			jars: ["bar.jar"],
+			apex_available: [
+				"com.android.art",
+			],
+		}
+
 		// Make sure that a preferred prebuilt doesn't affect the apex.
 		prebuilt_boot_image {
 			name: "mybootclasspathfragment",
diff --git a/java/boot_image.go b/java/boot_image.go
index 78215f0..192b16b 100644
--- a/java/boot_image.go
+++ b/java/boot_image.go
@@ -53,7 +53,7 @@
 	ctx.RegisterModuleType("prebuilt_bootclasspath_fragment", prebuiltBootImageFactory)
 }
 
-type bootImageContentDependencyTag struct {
+type bootclasspathFragmentContentDependencyTag struct {
 	blueprint.BaseDependencyTag
 }
 
@@ -62,16 +62,22 @@
 // This is a temporary workaround to make it easier to migrate to boot image modules with proper
 // dependencies.
 // TODO(b/177892522): Remove this and add needed visibility.
-func (b bootImageContentDependencyTag) ExcludeFromVisibilityEnforcement() {
+func (b bootclasspathFragmentContentDependencyTag) ExcludeFromVisibilityEnforcement() {
+}
+
+// The bootclasspath_fragment contents must never depend on prebuilts.
+func (b bootclasspathFragmentContentDependencyTag) ReplaceSourceWithPrebuilt() bool {
+	return false
 }
 
 // The tag used for the dependency between the boot image module and its contents.
-var bootImageContentDepTag = bootImageContentDependencyTag{}
+var bootclasspathFragmentContentDepTag = bootclasspathFragmentContentDependencyTag{}
 
-var _ android.ExcludeFromVisibilityEnforcementTag = bootImageContentDepTag
+var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathFragmentContentDepTag
+var _ android.ReplaceSourceWithPrebuilt = bootclasspathFragmentContentDepTag
 
-func IsbootImageContentDepTag(tag blueprint.DependencyTag) bool {
-	return tag == bootImageContentDepTag
+func IsBootclasspathFragmentContentDepTag(tag blueprint.DependencyTag) bool {
+	return tag == bootclasspathFragmentContentDepTag
 }
 
 type bootImageProperties struct {
@@ -187,7 +193,7 @@
 
 func (b *BootImageModule) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
 	tag := ctx.OtherModuleDependencyTag(dep)
-	if tag == bootImageContentDepTag {
+	if IsBootclasspathFragmentContentDepTag(tag) {
 		// Boot image contents are automatically added to apex.
 		return true
 	}
@@ -202,8 +208,26 @@
 	return nil
 }
 
+// ComponentDepsMutator adds dependencies onto modules before any prebuilt modules without a
+// corresponding source module are renamed. This means that adding a dependency using a name without
+// a prebuilt_ prefix will always resolve to a source module and when using a name with that prefix
+// it will always resolve to a prebuilt module.
+func (b *BootImageModule) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
+	module := ctx.Module()
+	_, isSourceModule := module.(*BootImageModule)
+
+	for _, name := range b.properties.Contents {
+		// A bootclasspath_fragment must depend only on other source modules, while the
+		// prebuilt_bootclasspath_fragment must only depend on other prebuilt modules.
+		if !isSourceModule {
+			name = android.PrebuiltNameFromSource(name)
+		}
+		ctx.AddDependency(module, bootclasspathFragmentContentDepTag, name)
+	}
+
+}
+
 func (b *BootImageModule) DepsMutator(ctx android.BottomUpMutatorContext) {
-	ctx.AddDependency(ctx.Module(), bootImageContentDepTag, b.properties.Contents...)
 
 	if SkipDexpreoptBootJars(ctx) {
 		return