Merge changes Ife12ba69,Ibf910262

* changes:
  Implement android_test_import
  AndroidMkEntries minor refactoring.
diff --git a/android/androidmk.go b/android/androidmk.go
index 1f1bd70..124523f 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -79,12 +79,14 @@
 	header bytes.Buffer
 	footer bytes.Buffer
 
-	AddCustomEntries func(name, prefix, moduleDir string, entries *AndroidMkEntries)
+	ExtraEntries []AndroidMkExtraEntriesFunc
 
 	EntryMap   map[string][]string
 	entryOrder []string
 }
 
+type AndroidMkExtraEntriesFunc func(entries *AndroidMkEntries)
+
 func (a *AndroidMkEntries) SetString(name, value string) {
 	if _, ok := a.EntryMap[name]; !ok {
 		a.entryOrder = append(a.entryOrder, name)
@@ -246,9 +248,8 @@
 			prefix = "2ND_" + prefix
 		}
 	}
-	blueprintDir := filepath.Dir(bpPath)
-	if a.AddCustomEntries != nil {
-		a.AddCustomEntries(name, prefix, blueprintDir, a)
+	for _, extra := range a.ExtraEntries {
+		extra(a)
 	}
 
 	// Write to footer.
diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go
index 9722a25..d29ed16 100644
--- a/android/prebuilt_etc.go
+++ b/android/prebuilt_etc.go
@@ -155,16 +155,18 @@
 		Class:      "ETC",
 		SubName:    nameSuffix,
 		OutputFile: OptionalPathForPath(p.outputFilePath),
-		AddCustomEntries: func(name, prefix, moduleDir string, entries *AndroidMkEntries) {
-			entries.SetString("LOCAL_MODULE_TAGS", "optional")
-			entries.SetString("LOCAL_MODULE_PATH", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
-			entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
-			entries.SetString("LOCAL_UNINSTALLABLE_MODULE", strconv.FormatBool(!p.Installable()))
-			if p.additionalDependencies != nil {
-				for _, path := range *p.additionalDependencies {
-					entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", path.String())
+		ExtraEntries: []AndroidMkExtraEntriesFunc{
+			func(entries *AndroidMkEntries) {
+				entries.SetString("LOCAL_MODULE_TAGS", "optional")
+				entries.SetString("LOCAL_MODULE_PATH", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
+				entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
+				entries.SetString("LOCAL_UNINSTALLABLE_MODULE", strconv.FormatBool(!p.Installable()))
+				if p.additionalDependencies != nil {
+					for _, path := range *p.additionalDependencies {
+						entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", path.String())
+					}
 				}
-			}
+			},
 		},
 	}
 }
diff --git a/android/sh_binary.go b/android/sh_binary.go
index 2855aa0..ba0c8be 100644
--- a/android/sh_binary.go
+++ b/android/sh_binary.go
@@ -133,8 +133,10 @@
 		Class:      "EXECUTABLES",
 		OutputFile: OptionalPathForPath(s.outputFilePath),
 		Include:    "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
-		AddCustomEntries: func(name, prefix, moduleDir string, entries *AndroidMkEntries) {
-			s.customAndroidMkEntries(entries)
+		ExtraEntries: []AndroidMkExtraEntriesFunc{
+			func(entries *AndroidMkEntries) {
+				s.customAndroidMkEntries(entries)
+			},
 		},
 	}
 }
@@ -156,20 +158,22 @@
 		Class:      "NATIVE_TESTS",
 		OutputFile: OptionalPathForPath(s.outputFilePath),
 		Include:    "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
-		AddCustomEntries: func(name, prefix, moduleDir string, entries *AndroidMkEntries) {
-			s.customAndroidMkEntries(entries)
+		ExtraEntries: []AndroidMkExtraEntriesFunc{
+			func(entries *AndroidMkEntries) {
+				s.customAndroidMkEntries(entries)
 
-			entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", s.testProperties.Test_suites...)
-			entries.SetString("LOCAL_TEST_CONFIG", String(s.testProperties.Test_config))
-			for _, d := range s.data {
-				rel := d.Rel()
-				path := d.String()
-				if !strings.HasSuffix(path, rel) {
-					panic(fmt.Errorf("path %q does not end with %q", path, rel))
+				entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", s.testProperties.Test_suites...)
+				entries.SetString("LOCAL_TEST_CONFIG", String(s.testProperties.Test_config))
+				for _, d := range s.data {
+					rel := d.Rel()
+					path := d.String()
+					if !strings.HasSuffix(path, rel) {
+						panic(fmt.Errorf("path %q does not end with %q", path, rel))
+					}
+					path = strings.TrimSuffix(path, rel)
+					entries.AddStrings("LOCAL_TEST_DATA", path+":"+rel)
 				}
-				path = strings.TrimSuffix(path, rel)
-				entries.AddStrings("LOCAL_TEST_DATA", path+":"+rel)
-			}
+			},
 		},
 	}
 }
diff --git a/apex/apex.go b/apex/apex.go
index 806158a..832188d 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1687,11 +1687,13 @@
 		Class:      "ETC",
 		OutputFile: android.OptionalPathForPath(p.inputApex),
 		Include:    "$(BUILD_PREBUILT)",
-		AddCustomEntries: func(name, prefix, moduleDir string, entries *android.AndroidMkEntries) {
-			entries.SetString("LOCAL_MODULE_PATH", filepath.Join("$(OUT_DIR)", p.installDir.RelPathString()))
-			entries.SetString("LOCAL_MODULE_STEM", p.installFilename)
-			entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable())
-			entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", p.properties.Overrides...)
+		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+			func(entries *android.AndroidMkEntries) {
+				entries.SetString("LOCAL_MODULE_PATH", filepath.Join("$(OUT_DIR)", p.installDir.RelPathString()))
+				entries.SetString("LOCAL_MODULE_STEM", p.installFilename)
+				entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable())
+				entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", p.properties.Overrides...)
+			},
 		},
 	}
 }
diff --git a/java/androidmk.go b/java/androidmk.go
index c00e070..0e8e422 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -122,6 +122,15 @@
 	}
 }
 
+func testSuiteComponentEntries(entries *android.AndroidMkEntries, test_suites []string) {
+	entries.SetString("LOCAL_MODULE_TAGS", "tests")
+	if len(test_suites) > 0 {
+		entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", test_suites...)
+	} else {
+		entries.SetString("LOCAL_COMPATIBILITY_SUITE", "null-suite")
+	}
+}
+
 func (j *Test) AndroidMk() android.AndroidMkData {
 	data := j.Library.AndroidMk()
 	data.Extra = append(data.Extra, func(w io.Writer, outputFile android.Path) {
@@ -614,22 +623,33 @@
 		Class:      "APPS",
 		OutputFile: android.OptionalPathForPath(a.outputFile),
 		Include:    "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
-		AddCustomEntries: func(name, prefix, moduleDir string, entries *android.AndroidMkEntries) {
-			entries.SetBoolIfTrue("LOCAL_PRIVILEGED_MODULE", Bool(a.properties.Privileged))
-			if a.certificate != nil {
-				entries.SetString("LOCAL_CERTIFICATE", a.certificate.Pem.String())
-			} else {
-				entries.SetString("LOCAL_CERTIFICATE", "PRESIGNED")
-			}
-			entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", a.properties.Overrides...)
-			if len(a.dexpreopter.builtInstalled) > 0 {
-				entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", a.dexpreopter.builtInstalled)
-			}
-			entries.AddStrings("LOCAL_INSTALLED_MODULE_STEM", a.installPath.Rel())
+		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+			func(entries *android.AndroidMkEntries) {
+				entries.SetBoolIfTrue("LOCAL_PRIVILEGED_MODULE", Bool(a.properties.Privileged))
+				if a.certificate != nil {
+					entries.SetString("LOCAL_CERTIFICATE", a.certificate.Pem.String())
+				} else {
+					entries.SetString("LOCAL_CERTIFICATE", "PRESIGNED")
+				}
+				entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", a.properties.Overrides...)
+				if len(a.dexpreopter.builtInstalled) > 0 {
+					entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", a.dexpreopter.builtInstalled)
+				}
+				entries.AddStrings("LOCAL_INSTALLED_MODULE_STEM", a.installPath.Rel())
+			},
 		},
 	}
 }
 
+func (a *AndroidTestImport) AndroidMkEntries() android.AndroidMkEntries {
+	entries := a.AndroidAppImport.AndroidMkEntries()
+	entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+		testSuiteComponentEntries(entries, a.testProperties.Test_suites)
+		androidMkEntriesWriteTestData(a.data, entries)
+	})
+	return entries
+}
+
 func androidMkWriteTestData(data android.Paths, ret *android.AndroidMkData) {
 	var testFiles []string
 	for _, d := range data {
@@ -641,3 +661,11 @@
 		})
 	}
 }
+
+func androidMkEntriesWriteTestData(data android.Paths, entries *android.AndroidMkEntries) {
+	var testFiles []string
+	for _, d := range data {
+		testFiles = append(testFiles, d.String()+":"+d.Rel())
+	}
+	entries.AddStrings("LOCAL_COMPATIBILITY_SUPPORT_FILES", testFiles...)
+}
diff --git a/java/app.go b/java/app.go
index f5a5da0..7df4358 100644
--- a/java/app.go
+++ b/java/app.go
@@ -39,6 +39,7 @@
 	android.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
 	android.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
 	android.RegisterModuleType("android_app_import", AndroidAppImportFactory)
+	android.RegisterModuleType("android_test_import", AndroidTestImportFactory)
 
 	initAndroidAppImportVariantGroupTypes()
 }
@@ -866,6 +867,10 @@
 }
 
 func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	a.generateAndroidBuildActions(ctx)
+}
+
+func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext) {
 	numCertPropsSet := 0
 	if String(a.properties.Certificate) != "" {
 		numCertPropsSet++
@@ -1024,6 +1029,39 @@
 	return module
 }
 
+type AndroidTestImport struct {
+	AndroidAppImport
+
+	testProperties testProperties
+
+	data android.Paths
+}
+
+func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	a.generateAndroidBuildActions(ctx)
+
+	a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
+}
+
+// android_test_import imports a prebuilt test apk with additional processing specified in the
+// module. DPI or arch variant configurations can be made as with android_app_import.
+func AndroidTestImportFactory() android.Module {
+	module := &AndroidTestImport{}
+	module.AddProperties(&module.properties)
+	module.AddProperties(&module.dexpreoptProperties)
+	module.AddProperties(&module.usesLibrary.usesLibraryProperties)
+	module.AddProperties(&module.testProperties)
+	module.populateAllVariantStructs()
+	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+		module.processVariants(ctx)
+	})
+
+	InitJavaModule(module, android.DeviceSupported)
+	android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk")
+
+	return module
+}
+
 type UsesLibraryProperties struct {
 	// A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
 	Uses_libs []string
diff --git a/java/app_test.go b/java/app_test.go
index be1ff29..f2aaec3 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1381,6 +1381,34 @@
 	}
 }
 
+func TestAndroidTestImport(t *testing.T) {
+	ctx, config := testJava(t, `
+		android_test_import {
+			name: "foo",
+			apk: "prebuilts/apk/app.apk",
+			presigned: true,
+			data: [
+				"testdata/data",
+			],
+		}
+		`)
+
+	test := ctx.ModuleForTests("foo", "android_common").Module().(*AndroidTestImport)
+
+	// Check android mks.
+	entries := android.AndroidMkEntriesForTest(t, config, "", test)
+	expected := []string{"tests"}
+	actual := entries.EntryMap["LOCAL_MODULE_TAGS"]
+	if !reflect.DeepEqual(expected, actual) {
+		t.Errorf("Unexpected module tags - expected: %q, actual: %q", expected, actual)
+	}
+	expected = []string{"testdata/data:testdata/data"}
+	actual = entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
+	if !reflect.DeepEqual(expected, actual) {
+		t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual)
+	}
+}
+
 func TestStl(t *testing.T) {
 	ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
 		cc_library {
diff --git a/java/java_test.go b/java/java_test.go
index 5fcdf96..c55e325 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -66,6 +66,7 @@
 	ctx.RegisterModuleType("android_library", android.ModuleFactoryAdaptor(AndroidLibraryFactory))
 	ctx.RegisterModuleType("android_test", android.ModuleFactoryAdaptor(AndroidTestFactory))
 	ctx.RegisterModuleType("android_test_helper_app", android.ModuleFactoryAdaptor(AndroidTestHelperAppFactory))
+	ctx.RegisterModuleType("android_test_import", android.ModuleFactoryAdaptor(AndroidTestImportFactory))
 	ctx.RegisterModuleType("java_binary", android.ModuleFactoryAdaptor(BinaryFactory))
 	ctx.RegisterModuleType("java_binary_host", android.ModuleFactoryAdaptor(BinaryHostFactory))
 	ctx.RegisterModuleType("java_device_for_host", android.ModuleFactoryAdaptor(DeviceForHostFactory))
@@ -200,6 +201,8 @@
 
 		"cert/new_cert.x509.pem": nil,
 		"cert/new_cert.pk8":      nil,
+
+		"testdata/data": nil,
 	}
 
 	for k, v := range fs {
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index 792edf3..f1da203 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -77,9 +77,11 @@
 		Class:      "ETC",
 		OutputFile: android.OptionalPathForPath(p.configFile),
 		Include:    "$(BUILD_PREBUILT)",
-		AddCustomEntries: func(name, prefix, moduleDir string, entries *android.AndroidMkEntries) {
-			entries.SetString("LOCAL_MODULE_PATH", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
-			entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.configFile.Base())
+		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+			func(entries *android.AndroidMkEntries) {
+				entries.SetString("LOCAL_MODULE_PATH", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
+				entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.configFile.Base())
+			},
 		},
 	}
 }