Revert "Use soong built autogenerated RROs"

Revert submission 3362490-autogen_app_overlay

Reason for revert: DroidMonitor: Potential culprit for http://b/382076898 - verifying through ABTD before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted.

Reverted changes: /q/submissionid:3362490-autogen_app_overlay

Change-Id: Ib3eb370625a4ab2cbf9a1337f82a1f0bc281a3a8
diff --git a/android/module.go b/android/module.go
index 6d2c39b..67dab4f 100644
--- a/android/module.go
+++ b/android/module.go
@@ -338,7 +338,6 @@
 		}
 		Android struct {
 			Compile_multilib *string
-			Enabled          *bool
 		}
 	}
 
diff --git a/java/aar.go b/java/aar.go
index 1e5c95a..e0e642e 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -588,16 +588,14 @@
 		}
 	}
 
+	for _, dir := range overlayDirs {
+		compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files,
+			compileFlags, a.filterProduct(), opts.aconfigTextFiles).Paths()...)
+	}
+
 	var compiledRro, compiledRroOverlay android.Paths
 	if opts.rroDirs != nil {
 		compiledRro, compiledRroOverlay = a.compileResInDir(ctx, *opts.rroDirs, compileFlags, opts.aconfigTextFiles)
-	} else {
-		// RRO enforcement is done based on module name. Compile the overlayDirs only if rroDirs is nil.
-		// This ensures that the autogenerated RROs do not compile the overlay dirs twice.
-		for _, dir := range overlayDirs {
-			compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files,
-				compileFlags, a.filterProduct(), opts.aconfigTextFiles).Paths()...)
-		}
 	}
 
 	var splitPackages android.WritablePaths
diff --git a/java/androidmk.go b/java/androidmk.go
index 35024c1..2ad30b1 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -307,11 +307,15 @@
 			Disabled: true,
 		}}
 	}
+	var required []string
+	if proptools.Bool(app.appProperties.Generate_product_characteristics_rro) {
+		required = []string{app.productCharacteristicsRROPackageName()}
+	}
 	return []android.AndroidMkEntries{android.AndroidMkEntries{
 		Class:      "APPS",
 		OutputFile: android.OptionalPathForPath(app.outputFile),
 		Include:    "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
-		Required:   app.requiredModuleNames,
+		Required:   required,
 		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
 			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
 				// App module names can be overridden.
@@ -346,6 +350,31 @@
 					entries.SetBoolIfTrue("LOCAL_NO_STANDARD_LIBRARIES", true)
 				}
 
+				filterRRO := func(filter overlayType) android.Paths {
+					var paths android.Paths
+					seen := make(map[android.Path]bool)
+					for _, d := range app.rroDirsDepSet.ToList() {
+						if d.overlayType == filter {
+							if seen[d.path] {
+								continue
+							}
+							seen[d.path] = true
+							paths = append(paths, d.path)
+						}
+					}
+					// Reverse the order, Soong stores rroDirs in aapt2 order (low to high priority), but Make
+					// expects it in LOCAL_RESOURCE_DIRS order (high to low priority).
+					return android.ReversePaths(paths)
+				}
+				deviceRRODirs := filterRRO(device)
+				if len(deviceRRODirs) > 0 {
+					entries.AddStrings("LOCAL_SOONG_DEVICE_RRO_DIRS", deviceRRODirs.Strings()...)
+				}
+				productRRODirs := filterRRO(product)
+				if len(productRRODirs) > 0 {
+					entries.AddStrings("LOCAL_SOONG_PRODUCT_RRO_DIRS", productRRODirs.Strings()...)
+				}
+
 				entries.SetBoolIfTrue("LOCAL_EXPORT_PACKAGE_RESOURCES", Bool(app.appProperties.Export_package_resources))
 
 				entries.SetPath("LOCAL_FULL_MANIFEST_FILE", app.manifestPath)
diff --git a/java/app.go b/java/app.go
index 34884d7..34a548e 100644
--- a/java/app.go
+++ b/java/app.go
@@ -223,8 +223,6 @@
 	javaApiUsedByOutputFile android.ModuleOutPath
 
 	privAppAllowlist android.OptionalPath
-
-	requiredModuleNames []string
 }
 
 func (a *AndroidApp) IsInstallable() bool {
@@ -423,24 +421,6 @@
 		TestHelperApp:   false,
 		EmbeddedJNILibs: embeddedJniLibs,
 	})
-
-	a.requiredModuleNames = a.getRequiredModuleNames(ctx)
-}
-
-func (a *AndroidApp) getRequiredModuleNames(ctx android.ModuleContext) []string {
-	var required []string
-	if proptools.Bool(a.appProperties.Generate_product_characteristics_rro) {
-		required = []string{a.productCharacteristicsRROPackageName()}
-	}
-	// Install the vendor overlay variant if this app is installed.
-	if len(filterRRO(a.rroDirsDepSet, device)) > 0 {
-		required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "vendor"))
-	}
-	// Install the product overlay variant if this app is installed.
-	if len(filterRRO(a.rroDirsDepSet, product)) > 0 {
-		required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "product"))
-	}
-	return required
 }
 
 func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
@@ -1397,11 +1377,6 @@
 			}
 		}
 		ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
-
-	})
-
-	module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
-		createInternalRuntimeOverlays(ctx, module.ModuleBase)
 	})
 
 	return module
@@ -1411,68 +1386,6 @@
 	return fmt.Sprintf("%s__%s__auto_generated_rro_%s", moduleName, ctx.Config().DeviceProduct(), partition)
 }
 
-type createModuleContext interface {
-	android.EarlyModuleContext
-	CreateModule(android.ModuleFactory, ...interface{}) android.Module
-}
-
-func createInternalRuntimeOverlays(ctx createModuleContext, a android.ModuleBase) {
-	if !ctx.Config().HasDeviceProduct() {
-		return
-	}
-	// vendor
-	vendorOverlayProps := struct {
-		Name                *string
-		Base                *string
-		Vendor              *bool
-		Product_specific    *bool
-		System_ext_specific *bool
-		Manifest            *string
-		Sdk_version         *string
-		Compile_multilib    *string
-		Enabled             proptools.Configurable[bool]
-	}{
-		Name:                proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "vendor")),
-		Base:                proptools.StringPtr(a.Name()),
-		Vendor:              proptools.BoolPtr(true),
-		Product_specific:    proptools.BoolPtr(false),
-		System_ext_specific: proptools.BoolPtr(false),
-		Manifest:            proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
-		Sdk_version:         proptools.StringPtr("current"),
-		Compile_multilib:    proptools.StringPtr("first"),
-		Enabled:             a.EnabledProperty().Clone(),
-	}
-	ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &vendorOverlayProps)
-
-	// product
-	productOverlayProps := struct {
-		Name                *string
-		Base                *string
-		Vendor              *bool
-		Proprietary         *bool
-		Soc_specific        *bool
-		Product_specific    *bool
-		System_ext_specific *bool
-		Manifest            *string
-		Sdk_version         *string
-		Compile_multilib    *string
-		Enabled             proptools.Configurable[bool]
-	}{
-		Name:                proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "product")),
-		Base:                proptools.StringPtr(a.Name()),
-		Vendor:              proptools.BoolPtr(false),
-		Proprietary:         proptools.BoolPtr(false),
-		Soc_specific:        proptools.BoolPtr(false),
-		Product_specific:    proptools.BoolPtr(true),
-		System_ext_specific: proptools.BoolPtr(false),
-		Manifest:            proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
-		Sdk_version:         proptools.StringPtr("current"),
-		Compile_multilib:    proptools.StringPtr("first"),
-		Enabled:             a.EnabledProperty().Clone(),
-	}
-	ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &productOverlayProps)
-}
-
 // A dictionary of values to be overridden in the manifest.
 type Manifest_values struct {
 	// Overrides the value of package_name in the manifest
@@ -1783,10 +1696,6 @@
 
 	android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
 	android.InitOverrideModule(m)
-	android.AddLoadHook(m, func(ctx android.LoadHookContext) {
-		createInternalRuntimeOverlays(ctx, m.ModuleBase)
-	})
-
 	return m
 }
 
diff --git a/java/app_test.go b/java/app_test.go
index 61b718d..3d83ea1 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -4727,74 +4727,3 @@
 		"out/soong/.intermediates/foo/android_common/aapt2/res/values_strings.(test.package.flag1).arsc.flat",
 	)
 }
-
-func TestAutogeneratedStaticRro(t *testing.T) {
-	t.Parallel()
-	bp := `
-android_app {
-	name: "foo",
-	srcs: ["foo.java"],
-	platform_apis: true,
-}
-override_android_app {
-	name: "override_foo",
-	base: "foo",
-}
-`
-	testCases := []struct {
-		desc               string
-		preparer           android.FixturePreparer
-		overlayApkExpected bool
-	}{
-		{
-			desc:               "No DEVICE_PACKAGE_OVERLAYS, no overlay .apk file",
-			overlayApkExpected: false,
-		},
-		{
-			desc:               "DEVICE_PACKAGE_OVERLAYS exists, but the directory is empty",
-			overlayApkExpected: false,
-			preparer: android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
-				variables.DeviceResourceOverlays = []string{"device/company/test_product"}
-			}),
-		},
-		{
-			desc:               "DEVICE_PACKAGE_OVERLAYS exists, directory is non-empty, but does not contain a matching resource dir",
-			overlayApkExpected: false,
-			preparer: android.GroupFixturePreparers(
-				android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
-					variables.DeviceResourceOverlays = []string{"device/company/test_product"}
-				}),
-				android.MockFS{
-					"res/foo.xml": nil,
-					"device/company/test_product/different_res/foo.xml": nil, // different dir
-				}.AddToFixture(),
-			),
-		},
-		{
-			desc:               "DEVICE_PACKAGE_OVERLAYS and the directory contain a matching resource dir",
-			overlayApkExpected: true,
-			preparer: android.GroupFixturePreparers(
-				android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
-					variables.DeviceResourceOverlays = []string{"device/company/test_product"}
-				}),
-				android.MockFS{
-					"res/foo.xml": nil,
-					"device/company/test_product/res/foo.xml": nil,
-				}.AddToFixture(),
-			),
-		},
-	}
-	for _, tc := range testCases {
-		result := android.GroupFixturePreparers(
-			PrepareForTestWithJavaDefaultModules,
-			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
-				variables.EnforceRROTargets = []string{"*"}
-			}),
-			android.OptionalFixturePreparer(tc.preparer),
-		).RunTestWithBp(t, bp)
-		vendorOverlayApk := result.ModuleForTests("foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").MaybeOutput("foo__test_product__auto_generated_rro_vendor.apk")
-		android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, vendorOverlayApk.Rule != nil)
-		overrideVendorOverlayApk := result.ModuleForTests("override_foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").MaybeOutput("override_foo__test_product__auto_generated_rro_vendor.apk")
-		android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.Rule != nil)
-	}
-}
diff --git a/java/rro_test.go b/java/rro_test.go
index 4d58bb4..4d79130 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -255,6 +255,103 @@
 	}
 }
 
+func TestEnforceRRO_propagatesToDependencies(t *testing.T) {
+	testCases := []struct {
+		name              string
+		enforceRROTargets []string
+		rroDirs           map[string][]string
+	}{
+		{
+			name:              "no RRO",
+			enforceRROTargets: nil,
+			rroDirs: map[string][]string{
+				"foo": nil,
+				"bar": nil,
+			},
+		},
+		{
+			name:              "enforce RRO on all",
+			enforceRROTargets: []string{"*"},
+			rroDirs: map[string][]string{
+				"foo": {"product/vendor/blah/overlay/lib2/res"},
+				"bar": {"product/vendor/blah/overlay/lib2/res"},
+			},
+		},
+		{
+			name:              "enforce RRO on foo",
+			enforceRROTargets: []string{"foo"},
+			rroDirs: map[string][]string{
+				"foo": {"product/vendor/blah/overlay/lib2/res"},
+				"bar": nil,
+			},
+		},
+	}
+
+	productResourceOverlays := []string{
+		"product/vendor/blah/overlay",
+	}
+
+	fs := android.MockFS{
+		"lib2/res/values/strings.xml":                             nil,
+		"product/vendor/blah/overlay/lib2/res/values/strings.xml": nil,
+	}
+
+	bp := `
+			android_app {
+				name: "foo",
+				sdk_version: "current",
+				resource_dirs: [],
+				static_libs: ["lib"],
+			}
+
+			android_app {
+				name: "bar",
+				sdk_version: "current",
+				resource_dirs: [],
+				static_libs: ["lib"],
+			}
+
+			android_library {
+				name: "lib",
+				sdk_version: "current",
+				resource_dirs: [],
+				static_libs: ["lib2"],
+			}
+
+			android_library {
+				name: "lib2",
+				sdk_version: "current",
+				resource_dirs: ["lib2/res"],
+			}
+		`
+
+	for _, testCase := range testCases {
+		t.Run(testCase.name, func(t *testing.T) {
+			result := android.GroupFixturePreparers(
+				PrepareForTestWithJavaDefaultModules,
+				fs.AddToFixture(),
+				android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+					variables.ProductResourceOverlays = productResourceOverlays
+					if testCase.enforceRROTargets != nil {
+						variables.EnforceRROTargets = testCase.enforceRROTargets
+					}
+				}),
+			).RunTestWithBp(t, bp)
+
+			modules := []string{"foo", "bar"}
+			for _, moduleName := range modules {
+				module := result.ModuleForTests(moduleName, "android_common")
+				mkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, module.Module())[0]
+				actualRRODirs := mkEntries.EntryMap["LOCAL_SOONG_PRODUCT_RRO_DIRS"]
+				if !reflect.DeepEqual(actualRRODirs, testCase.rroDirs[moduleName]) {
+					t.Errorf("exected %s LOCAL_SOONG_PRODUCT_RRO_DIRS entry: %v\ngot:%q",
+						moduleName, testCase.rroDirs[moduleName], actualRRODirs)
+				}
+			}
+		})
+	}
+}
+
 func TestRuntimeResourceOverlayPartition(t *testing.T) {
 	bp := `
 		runtime_resource_overlay {