Add soong build restrictions for libcore targets

Add soong build restrictions for libcore targets to stop
other targets depending on internals.

Test: cd build/soong/; ./build_test.bash --products aosp_arm
Bug: 113148576
Change-Id: I2c15924fbecaf0c2076d08de65814a6dcb790e73
diff --git a/android/neverallow.go b/android/neverallow.go
index d3a2801..f6caebc 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -45,35 +45,85 @@
 	ctx.BottomUp("neverallow", neverallowMutator).Parallel()
 }
 
-var neverallows = []*rule{
-	neverallow().
-		in("vendor", "device").
-		with("vndk.enabled", "true").
-		without("vendor", "true").
-		because("the VNDK can never contain a library that is device dependent."),
-	neverallow().
-		with("vndk.enabled", "true").
-		without("vendor", "true").
-		without("owner", "").
-		because("a VNDK module can never have an owner."),
-	neverallow().
-		notIn("libcore", "development", "external/apache-harmony", "external/apache-xml", "external/bouncycastle", "external/conscrypt", "external/icu", "external/okhttp", "external/wycheproof").
-		with("no_standard_libs", "true"),
+var neverallows = createNeverAllows()
 
-	// TODO(b/67974785): always enforce the manifest
-	neverallow().
-		without("name", "libhidltransport").
-		with("product_variables.enforce_vintf_manifest.cflags", "*").
-		because("manifest enforcement should be independent of ."),
+func createNeverAllows() []*rule {
+	rules := []*rule{}
+	rules = append(rules, createTrebleRules()...)
+	rules = append(rules, createLibcoreRules()...)
+	return rules
+}
 
-	// TODO(b/67975799): vendor code should always use /vendor/bin/sh
-	neverallow().
-		without("name", "libc_bionic_ndk").
-		with("product_variables.treble_linker_namespaces.cflags", "*").
-		because("nothing should care if linker namespaces are enabled or not"),
+func createTrebleRules() []*rule {
+	return []*rule{
+		neverallow().
+			in("vendor", "device").
+			with("vndk.enabled", "true").
+			without("vendor", "true").
+			because("the VNDK can never contain a library that is device dependent."),
+		neverallow().
+			with("vndk.enabled", "true").
+			without("vendor", "true").
+			without("owner", "").
+			because("a VNDK module can never have an owner."),
 
-	// Example:
-	// *neverallow().with("Srcs", "main.cpp"),
+		// TODO(b/67974785): always enforce the manifest
+		neverallow().
+			without("name", "libhidltransport").
+			with("product_variables.enforce_vintf_manifest.cflags", "*").
+			because("manifest enforcement should be independent of ."),
+
+		// TODO(b/67975799): vendor code should always use /vendor/bin/sh
+		neverallow().
+			without("name", "libc_bionic_ndk").
+			with("product_variables.treble_linker_namespaces.cflags", "*").
+			because("nothing should care if linker namespaces are enabled or not"),
+
+		// Example:
+		// *neverallow().with("Srcs", "main.cpp"))
+	}
+}
+
+func createLibcoreRules() []*rule {
+	var coreLibraryProjects = []string{
+		"libcore",
+		"external/apache-harmony",
+		"external/apache-xml",
+		"external/bouncycastle",
+		"external/conscrypt",
+		"external/icu",
+		"external/okhttp",
+		"external/wycheproof",
+	}
+
+	var coreModules = []string{
+		"core-all",
+		"core-oj",
+		"core-libart",
+		"core-simple",
+		"okhttp",
+		"bouncycastle",
+		"conscrypt",
+		"apache-xml",
+	}
+
+	// Core library constraints. Prevent targets adding dependencies on core
+	// library internals, which could lead to compatibility issues with the ART
+	// mainline module. They should use core.platform.api.stubs instead.
+	rules := []*rule{
+		neverallow().
+			notIn(append(coreLibraryProjects, "development")...).
+			with("no_standard_libs", "true"),
+	}
+
+	for _, m := range coreModules {
+		r := neverallow().
+			notIn(coreLibraryProjects...).
+			with("libs", m).
+			because("Only core libraries projects can depend on " + m)
+		rules = append(rules, r)
+	}
+	return rules
 }
 
 func neverallowMutator(ctx BottomUpMutatorContext) {
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index a278365..9e4886c 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -137,6 +137,17 @@
 		},
 		expectedError: "",
 	},
+	{
+		name: "dependency on core-libart",
+		fs: map[string][]byte{
+			"Blueprints": []byte(`
+				java_library {
+					name: "needs_core_libart",
+					libs: ["core-libart"],
+				}`),
+		},
+		expectedError: "Only core libraries projects can depend on core-libart",
+	},
 }
 
 func TestNeverallow(t *testing.T) {
@@ -164,6 +175,7 @@
 func testNeverallow(t *testing.T, config Config, fs map[string][]byte) (*TestContext, []error) {
 	ctx := NewTestContext()
 	ctx.RegisterModuleType("cc_library", ModuleFactoryAdaptor(newMockCcLibraryModule))
+	ctx.RegisterModuleType("java_library", ModuleFactoryAdaptor(newMockJavaLibraryModule))
 	ctx.PostDepsMutators(registerNeverallowMutator)
 	ctx.Register()
 
@@ -178,7 +190,7 @@
 	return ctx, errs
 }
 
-type mockProperties struct {
+type mockCcLibraryProperties struct {
 	Vendor_available *bool
 
 	Vndk struct {
@@ -200,7 +212,7 @@
 
 type mockCcLibraryModule struct {
 	ModuleBase
-	properties mockProperties
+	properties mockCcLibraryProperties
 }
 
 func newMockCcLibraryModule() Module {
@@ -215,3 +227,25 @@
 
 func (p *mockCcLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
 }
+
+type mockJavaLibraryProperties struct {
+	Libs []string
+}
+
+type mockJavaLibraryModule struct {
+	ModuleBase
+	properties mockJavaLibraryProperties
+}
+
+func newMockJavaLibraryModule() Module {
+	m := &mockJavaLibraryModule{}
+	m.AddProperties(&m.properties)
+	InitAndroidModule(m)
+	return m
+}
+
+func (p *mockJavaLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
+}
+
+func (p *mockJavaLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
+}