Merge changes from topics "bp-bionic-cts-tests", "cts-per-testcase-directory"

* changes:
  Add data_bins property
  Support per-testcase directories in all test suites
  Add environment variables to cc_genrule commands
diff --git a/cc/androidmk.go b/cc/androidmk.go
index cd52363..243efe6 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -394,6 +394,8 @@
 		if Bool(test.Properties.Test_options.Unit_test) {
 			entries.SetBool("LOCAL_IS_UNIT_TEST", true)
 		}
+
+		entries.SetBoolIfTrue("LOCAL_COMPATIBILITY_PER_TESTCASE_DIRECTORY", Bool(test.Properties.Per_testcase_directory))
 	})
 
 	AndroidMkWriteTestData(test.data, entries)
diff --git a/cc/cc.go b/cc/cc.go
index 57e7887..b410834 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -95,6 +95,7 @@
 
 	// Used for data dependencies adjacent to tests
 	DataLibs []string
+	DataBins []string
 
 	// Used by DepsMutator to pass system_shared_libs information to check_elf_file.py.
 	SystemSharedLibs []string
@@ -718,6 +719,7 @@
 	staticVariantTag      = dependencyTag{name: "static variant"}
 	vndkExtDepTag         = dependencyTag{name: "vndk extends"}
 	dataLibDepTag         = dependencyTag{name: "data lib"}
+	dataBinDepTag         = dependencyTag{name: "data bin"}
 	runtimeDepTag         = installDependencyTag{name: "runtime lib"}
 	testPerSrcDepTag      = dependencyTag{name: "test_per_src"}
 	stubImplDepTag        = dependencyTag{name: "stub_impl"}
@@ -2274,6 +2276,8 @@
 		{Mutator: "link", Variation: "shared"},
 	}, dataLibDepTag, deps.DataLibs...)
 
+	actx.AddVariationDependencies(nil, dataBinDepTag, deps.DataBins...)
+
 	actx.AddVariationDependencies([]blueprint.Variation{
 		{Mutator: "link", Variation: "shared"},
 	}, runtimeDepTag, deps.RuntimeLibs...)
diff --git a/cc/genrule.go b/cc/genrule.go
index 9df5228..239064f 100644
--- a/cc/genrule.go
+++ b/cc/genrule.go
@@ -15,6 +15,8 @@
 package cc
 
 import (
+	"fmt"
+
 	"android/soong/android"
 	"android/soong/genrule"
 	"android/soong/snapshot"
@@ -36,13 +38,23 @@
 
 // cc_genrule is a genrule that can depend on other cc_* objects.
 // The cmd may be run multiple times, once for each of the different arch/etc
-// variations.
+// variations.  The following environment variables will be set when the command
+// execute:
+//
+//   CC_ARCH           the name of the architecture the command is being executed for
+//
+//   CC_MULTILIB       "lib32" if the architecture the command is being executed for is 32-bit,
+//                     "lib64" if it is 64-bit.
+//
+//   CC_NATIVE_BRIDGE  the name of the subdirectory that native bridge libraries are stored in if
+//                     the architecture has native bridge enabled, empty if it is disabled.
 func GenRuleFactory() android.Module {
 	module := genrule.NewGenRule()
 
 	extra := &GenruleExtraProperties{}
 	module.Extra = extra
 	module.ImageInterface = extra
+	module.CmdModifier = genruleCmdModifier
 	module.AddProperties(module.Extra)
 
 	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibBoth)
@@ -53,6 +65,13 @@
 	return module
 }
 
+func genruleCmdModifier(ctx android.ModuleContext, cmd string) string {
+	target := ctx.Target()
+	arch := target.Arch.ArchType
+	return fmt.Sprintf("CC_ARCH=%s CC_NATIVE_BRIDGE=%s CC_MULTILIB=%s && %s",
+		arch.Name, target.NativeBridgeRelativePath, arch.Multilib, cmd)
+}
+
 var _ android.ImageInterface = (*GenruleExtraProperties)(nil)
 
 func (g *GenruleExtraProperties) ImageMutatorBegin(ctx android.BaseModuleContext) {}
diff --git a/cc/genrule_test.go b/cc/genrule_test.go
index b6afb05..f25f704 100644
--- a/cc/genrule_test.go
+++ b/cc/genrule_test.go
@@ -115,3 +115,75 @@
 		t.Errorf(`want inputs %v, got %v`, expected, got)
 	}
 }
+
+func TestCmdPrefix(t *testing.T) {
+	bp := `
+		cc_genrule {
+			name: "gen",
+			cmd: "echo foo",
+			out: ["out"],
+			native_bridge_supported: true,
+		}
+		`
+
+	testCases := []struct {
+		name     string
+		variant  string
+		preparer android.FixturePreparer
+
+		arch         string
+		nativeBridge string
+		multilib     string
+	}{
+		{
+			name:     "arm",
+			variant:  "android_arm_armv7-a-neon",
+			arch:     "arm",
+			multilib: "lib32",
+		},
+		{
+			name:     "arm64",
+			variant:  "android_arm64_armv8-a",
+			arch:     "arm64",
+			multilib: "lib64",
+		},
+		{
+			name:    "nativebridge",
+			variant: "android_native_bridge_arm_armv7-a-neon",
+			preparer: android.FixtureModifyConfig(func(config android.Config) {
+				config.Targets[android.Android] = []android.Target{
+					{
+						Os:           android.Android,
+						Arch:         android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}},
+						NativeBridge: android.NativeBridgeDisabled,
+					},
+					{
+						Os:                       android.Android,
+						Arch:                     android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}},
+						NativeBridge:             android.NativeBridgeEnabled,
+						NativeBridgeHostArchName: "x86",
+						NativeBridgeRelativePath: "arm",
+					},
+				}
+			}),
+			arch:         "arm",
+			multilib:     "lib32",
+			nativeBridge: "arm",
+		},
+	}
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			result := android.GroupFixturePreparers(
+				PrepareForIntegrationTestWithCc,
+				android.OptionalFixturePreparer(tt.preparer),
+			).RunTestWithBp(t, bp)
+			gen := result.ModuleForTests("gen", tt.variant)
+			sboxProto := android.RuleBuilderSboxProtoForTests(t, gen.Output("genrule.sbox.textproto"))
+			cmd := *sboxProto.Commands[0].Command
+			android.AssertStringDoesContain(t, "incorrect CC_ARCH", cmd, "CC_ARCH="+tt.arch+" ")
+			android.AssertStringDoesContain(t, "incorrect CC_NATIVE_BRIDGE", cmd, "CC_NATIVE_BRIDGE="+tt.nativeBridge+" ")
+			android.AssertStringDoesContain(t, "incorrect CC_MULTILIB", cmd, "CC_MULTILIB="+tt.multilib+" ")
+		})
+	}
+}
diff --git a/cc/test.go b/cc/test.go
index 047a69e..c589165 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -80,6 +80,9 @@
 	// list of shared library modules that should be installed alongside the test
 	Data_libs []string `android:"arch_variant"`
 
+	// list of binary modules that should be installed alongside the test
+	Data_bins []string `android:"arch_variant"`
+
 	// list of compatibility suites (for example "cts", "vts") that the module should be
 	// installed into.
 	Test_suites []string `android:"arch_variant"`
@@ -115,6 +118,9 @@
 	// Add parameterized mainline modules to auto generated test config. The options will be
 	// handled by TradeFed to download and install the specified modules on the device.
 	Test_mainline_modules []string
+
+	// Install the test into a folder named for the module in all test suites.
+	Per_testcase_directory *bool
 }
 
 func init() {
@@ -347,6 +353,7 @@
 	deps = test.testDecorator.linkerDeps(ctx, deps)
 	deps = test.binaryDecorator.linkerDeps(ctx, deps)
 	deps.DataLibs = append(deps.DataLibs, test.Properties.Data_libs...)
+	deps.DataBins = append(deps.DataBins, test.Properties.Data_bins...)
 	return deps
 }
 
@@ -386,6 +393,18 @@
 					RelativeInstallPath: ccModule.installer.relativeInstallPath()})
 		}
 	})
+	ctx.VisitDirectDepsWithTag(dataBinDepTag, func(dep android.Module) {
+		depName := ctx.OtherModuleName(dep)
+		ccModule, ok := dep.(*Module)
+		if !ok {
+			ctx.ModuleErrorf("data_bin %q is not a cc module", depName)
+		}
+		if ccModule.OutputFile().Valid() {
+			test.data = append(test.data,
+				android.DataPath{SrcPath: ccModule.OutputFile().Path(),
+					RelativeInstallPath: ccModule.installer.relativeInstallPath()})
+		}
+	})
 
 	var configs []tradefed.Config
 	for _, module := range test.Properties.Test_mainline_modules {
diff --git a/genrule/genrule.go b/genrule/genrule.go
index f4bde70..96b610b 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -156,6 +156,11 @@
 	// For other packages to make their own genrules with extra
 	// properties
 	Extra interface{}
+
+	// CmdModifier can be set by wrappers around genrule to modify the command, for example to
+	// prefix environment variables to it.
+	CmdModifier func(ctx android.ModuleContext, cmd string) string
+
 	android.ImageInterface
 
 	properties generatorProperties
@@ -398,8 +403,13 @@
 	var outputFiles android.WritablePaths
 	var zipArgs strings.Builder
 
+	cmd := String(g.properties.Cmd)
+	if g.CmdModifier != nil {
+		cmd = g.CmdModifier(ctx, cmd)
+	}
+
 	// Generate tasks, either from genrule or gensrcs.
-	for _, task := range g.taskGenerator(ctx, String(g.properties.Cmd), srcFiles) {
+	for _, task := range g.taskGenerator(ctx, cmd, srcFiles) {
 		if len(task.out) == 0 {
 			ctx.ModuleErrorf("must have at least one output file")
 			return
diff --git a/java/androidmk.go b/java/androidmk.go
index 1914595..0f1a1ec 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -147,20 +147,21 @@
 }
 
 // Called for modules that are a component of a test suite.
-func testSuiteComponent(entries *android.AndroidMkEntries, test_suites []string) {
+func testSuiteComponent(entries *android.AndroidMkEntries, test_suites []string, perTestcaseDirectory bool) {
 	entries.SetString("LOCAL_MODULE_TAGS", "tests")
 	if len(test_suites) > 0 {
 		entries.AddCompatibilityTestSuites(test_suites...)
 	} else {
 		entries.AddCompatibilityTestSuites("null-suite")
 	}
+	entries.SetBoolIfTrue("LOCAL_COMPATIBILITY_PER_TESTCASE_DIRECTORY", perTestcaseDirectory)
 }
 
 func (j *Test) AndroidMkEntries() []android.AndroidMkEntries {
 	entriesList := j.Library.AndroidMkEntries()
 	entries := &entriesList[0]
 	entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
-		testSuiteComponent(entries, j.testProperties.Test_suites)
+		testSuiteComponent(entries, j.testProperties.Test_suites, Bool(j.testProperties.Per_testcase_directory))
 		if j.testConfig != nil {
 			entries.SetPath("LOCAL_FULL_TEST_CONFIG", j.testConfig)
 		}
@@ -188,7 +189,7 @@
 	entriesList := j.Library.AndroidMkEntries()
 	entries := &entriesList[0]
 	entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
-		testSuiteComponent(entries, j.testHelperLibraryProperties.Test_suites)
+		testSuiteComponent(entries, j.testHelperLibraryProperties.Test_suites, Bool(j.testHelperLibraryProperties.Per_testcase_directory))
 	})
 
 	return entriesList
@@ -450,7 +451,7 @@
 	entriesList := a.AndroidApp.AndroidMkEntries()
 	entries := &entriesList[0]
 	entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
-		testSuiteComponent(entries, a.testProperties.Test_suites)
+		testSuiteComponent(entries, a.testProperties.Test_suites, Bool(a.testProperties.Per_testcase_directory))
 		if a.testConfig != nil {
 			entries.SetPath("LOCAL_FULL_TEST_CONFIG", a.testConfig)
 		}
@@ -466,7 +467,7 @@
 	entriesList := a.AndroidApp.AndroidMkEntries()
 	entries := &entriesList[0]
 	entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
-		testSuiteComponent(entries, a.appTestHelperAppProperties.Test_suites)
+		testSuiteComponent(entries, a.appTestHelperAppProperties.Test_suites, Bool(a.appTestHelperAppProperties.Per_testcase_directory))
 		// introduce a flag variable to control the generation of the .config file
 		entries.SetString("LOCAL_DISABLE_TEST_CONFIG", "true")
 	})
@@ -677,7 +678,7 @@
 	entriesList := a.AndroidAppImport.AndroidMkEntries()
 	entries := &entriesList[0]
 	entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
-		testSuiteComponent(entries, a.testProperties.Test_suites)
+		testSuiteComponent(entries, a.testProperties.Test_suites, Bool(a.testProperties.Per_testcase_directory))
 		androidMkWriteTestData(a.data, entries)
 	})
 	return entriesList
diff --git a/java/app.go b/java/app.go
index 2fd6463..bc0f488 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1070,6 +1070,9 @@
 	// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
 	// explicitly.
 	Auto_gen_config *bool
+
+	// Install the test into a folder named for the module in all test suites.
+	Per_testcase_directory *bool
 }
 
 type AndroidTestHelperApp struct {
diff --git a/java/java.go b/java/java.go
index 23809df..e7928c8 100644
--- a/java/java.go
+++ b/java/java.go
@@ -781,6 +781,9 @@
 
 	// Names of modules containing JNI libraries that should be installed alongside the test.
 	Jni_libs []string
+
+	// Install the test into a folder named for the module in all test suites.
+	Per_testcase_directory *bool
 }
 
 type hostTestProperties struct {
@@ -792,6 +795,9 @@
 	// list of compatibility suites (for example "cts", "vts") that the module should be
 	// installed into.
 	Test_suites []string `android:"arch_variant"`
+
+	// Install the test into a folder named for the module in all test suites.
+	Per_testcase_directory *bool
 }
 
 type prebuiltTestProperties struct {