Break up app.go.

Test: m nothing + TreeHugger
Change-Id: I64c6d7f10530c424bc282d8111dfaf9159426f00
diff --git a/java/app.go b/java/app.go
index bcb610c..4369865 100755
--- a/java/app.go
+++ b/java/app.go
@@ -14,13 +14,12 @@
 
 package java
 
-// This file contains the module types for compiling Android apps.
+// This file contains the module implementations for android_app, android_test, and some more
+// related module types, including their override variants.
 
 import (
 	"path/filepath"
-	"reflect"
 	"sort"
-	"strconv"
 	"strings"
 
 	"github.com/google/blueprint"
@@ -32,12 +31,8 @@
 	"android/soong/tradefed"
 )
 
-var supportedDpis = []string{"ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"}
-
 func init() {
 	RegisterAppBuildComponents(android.InitRegistrationContext)
-
-	initAndroidAppImportVariantGroupTypes()
 }
 
 func RegisterAppBuildComponents(ctx android.RegistrationContext) {
@@ -47,139 +42,6 @@
 	ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
 	ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
 	ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
-	ctx.RegisterModuleType("override_runtime_resource_overlay", OverrideRuntimeResourceOverlayModuleFactory)
-	ctx.RegisterModuleType("android_app_import", AndroidAppImportFactory)
-	ctx.RegisterModuleType("android_test_import", AndroidTestImportFactory)
-	ctx.RegisterModuleType("runtime_resource_overlay", RuntimeResourceOverlayFactory)
-	ctx.RegisterModuleType("android_app_set", AndroidApkSetFactory)
-}
-
-type AndroidAppSetProperties struct {
-	// APK Set path
-	Set *string
-
-	// Specifies that this app should be installed to the priv-app directory,
-	// where the system will grant it additional privileges not available to
-	// normal apps.
-	Privileged *bool
-
-	// APKs in this set use prerelease SDK version
-	Prerelease *bool
-
-	// Names of modules to be overridden. Listed modules can only be other apps
-	//	(in Make or Soong).
-	Overrides []string
-}
-
-type AndroidAppSet struct {
-	android.ModuleBase
-	android.DefaultableModuleBase
-	prebuilt android.Prebuilt
-
-	properties   AndroidAppSetProperties
-	packedOutput android.WritablePath
-	installFile  string
-	apkcertsFile android.ModuleOutPath
-}
-
-func (as *AndroidAppSet) Name() string {
-	return as.prebuilt.Name(as.ModuleBase.Name())
-}
-
-func (as *AndroidAppSet) IsInstallable() bool {
-	return true
-}
-
-func (as *AndroidAppSet) Prebuilt() *android.Prebuilt {
-	return &as.prebuilt
-}
-
-func (as *AndroidAppSet) Privileged() bool {
-	return Bool(as.properties.Privileged)
-}
-
-func (as *AndroidAppSet) OutputFile() android.Path {
-	return as.packedOutput
-}
-
-func (as *AndroidAppSet) InstallFile() string {
-	return as.installFile
-}
-
-func (as *AndroidAppSet) APKCertsFile() android.Path {
-	return as.apkcertsFile
-}
-
-var TargetCpuAbi = map[string]string{
-	"arm":    "ARMEABI_V7A",
-	"arm64":  "ARM64_V8A",
-	"x86":    "X86",
-	"x86_64": "X86_64",
-}
-
-func SupportedAbis(ctx android.ModuleContext) []string {
-	abiName := func(targetIdx int, deviceArch string) string {
-		if abi, found := TargetCpuAbi[deviceArch]; found {
-			return abi
-		}
-		ctx.ModuleErrorf("Target %d has invalid Arch: %s", targetIdx, deviceArch)
-		return "BAD_ABI"
-	}
-
-	var result []string
-	for i, target := range ctx.Config().Targets[android.Android] {
-		result = append(result, abiName(i, target.Arch.ArchType.String()))
-	}
-	return result
-}
-
-func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	as.packedOutput = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
-	as.apkcertsFile = android.PathForModuleOut(ctx, "apkcerts.txt")
-	// We are assuming here that the install file in the APK
-	// set has `.apk` suffix. If it doesn't the build will fail.
-	// APK sets containing APEX files are handled elsewhere.
-	as.installFile = as.BaseModuleName() + ".apk"
-	screenDensities := "all"
-	if dpis := ctx.Config().ProductAAPTPrebuiltDPI(); len(dpis) > 0 {
-		screenDensities = strings.ToUpper(strings.Join(dpis, ","))
-	}
-	// TODO(asmundak): handle locales.
-	// TODO(asmundak): do we support device features
-	ctx.Build(pctx,
-		android.BuildParams{
-			Rule:           extractMatchingApks,
-			Description:    "Extract APKs from APK set",
-			Output:         as.packedOutput,
-			ImplicitOutput: as.apkcertsFile,
-			Inputs:         android.Paths{as.prebuilt.SingleSourcePath(ctx)},
-			Args: map[string]string{
-				"abis":              strings.Join(SupportedAbis(ctx), ","),
-				"allow-prereleased": strconv.FormatBool(proptools.Bool(as.properties.Prerelease)),
-				"screen-densities":  screenDensities,
-				"sdk-version":       ctx.Config().PlatformSdkVersion().String(),
-				"stem":              as.BaseModuleName(),
-				"apkcerts":          as.apkcertsFile.String(),
-				"partition":         as.PartitionTag(ctx.DeviceConfig()),
-			},
-		})
-}
-
-// android_app_set extracts a set of APKs based on the target device
-// configuration and installs this set as "split APKs".
-// The extracted set always contains an APK whose name is
-// _module_name_.apk and every split APK matching target device.
-// The extraction of the density-specific splits depends on
-// PRODUCT_AAPT_PREBUILT_DPI variable. If present (its value should
-// be a list density names: LDPI, MDPI, HDPI, etc.), only listed
-// splits will be extracted. Otherwise all density-specific splits
-// will be extracted.
-func AndroidApkSetFactory() android.Module {
-	module := &AndroidAppSet{}
-	module.AddProperties(&module.properties)
-	InitJavaModule(module, android.DeviceSupported)
-	android.InitSingleSourcePrebuiltModule(module, &module.properties, "Set")
-	return module
 }
 
 // AndroidManifest.xml merging
@@ -273,15 +135,6 @@
 	Rename_resources_package *bool
 }
 
-// runtime_resource_overlay properties that can be overridden by override_runtime_resource_overlay
-type OverridableRuntimeResourceOverlayProperties struct {
-	// the package name of this app. The package name in the manifest file is used if one was not given.
-	Package_name *string
-
-	// the target package name of this overlay app. The target package name in the manifest file is used if one was not given.
-	Target_package_name *string
-}
-
 type AndroidApp struct {
 	Library
 	aapt
@@ -1298,629 +1151,6 @@
 	return m
 }
 
-type OverrideRuntimeResourceOverlay struct {
-	android.ModuleBase
-	android.OverrideModuleBase
-}
-
-func (i *OverrideRuntimeResourceOverlay) GenerateAndroidBuildActions(_ android.ModuleContext) {
-	// All the overrides happen in the base module.
-	// TODO(jungjw): Check the base module type.
-}
-
-// override_runtime_resource_overlay is used to create a module based on another
-// runtime_resource_overlay module by overriding some of its properties.
-func OverrideRuntimeResourceOverlayModuleFactory() android.Module {
-	m := &OverrideRuntimeResourceOverlay{}
-	m.AddProperties(&OverridableRuntimeResourceOverlayProperties{})
-
-	android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
-	android.InitOverrideModule(m)
-	return m
-}
-
-type AndroidAppImport struct {
-	android.ModuleBase
-	android.DefaultableModuleBase
-	android.ApexModuleBase
-	prebuilt android.Prebuilt
-
-	properties   AndroidAppImportProperties
-	dpiVariants  interface{}
-	archVariants interface{}
-
-	outputFile  android.Path
-	certificate Certificate
-
-	dexpreopter
-
-	usesLibrary usesLibrary
-
-	preprocessed bool
-
-	installPath android.InstallPath
-
-	hideApexVariantFromMake bool
-}
-
-type AndroidAppImportProperties struct {
-	// A prebuilt apk to import
-	Apk *string
-
-	// The name of a certificate in the default certificate directory or an android_app_certificate
-	// module name in the form ":module". Should be empty if presigned or default_dev_cert is set.
-	Certificate *string
-
-	// Set this flag to true if the prebuilt apk is already signed. The certificate property must not
-	// be set for presigned modules.
-	Presigned *bool
-
-	// Name of the signing certificate lineage file.
-	Lineage *string
-
-	// Sign with the default system dev certificate. Must be used judiciously. Most imported apps
-	// need to either specify a specific certificate or be presigned.
-	Default_dev_cert *bool
-
-	// Specifies that this app should be installed to the priv-app directory,
-	// where the system will grant it additional privileges not available to
-	// normal apps.
-	Privileged *bool
-
-	// Names of modules to be overridden. Listed modules can only be other binaries
-	// (in Make or Soong).
-	// This does not completely prevent installation of the overridden binaries, but if both
-	// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
-	// from PRODUCT_PACKAGES.
-	Overrides []string
-
-	// Optional name for the installed app. If unspecified, it is derived from the module name.
-	Filename *string
-}
-
-func (a *AndroidAppImport) IsInstallable() bool {
-	return true
-}
-
-// Updates properties with variant-specific values.
-func (a *AndroidAppImport) processVariants(ctx android.LoadHookContext) {
-	config := ctx.Config()
-
-	dpiProps := reflect.ValueOf(a.dpiVariants).Elem().FieldByName("Dpi_variants")
-	// Try DPI variant matches in the reverse-priority order so that the highest priority match
-	// overwrites everything else.
-	// TODO(jungjw): Can we optimize this by making it priority order?
-	for i := len(config.ProductAAPTPrebuiltDPI()) - 1; i >= 0; i-- {
-		MergePropertiesFromVariant(ctx, &a.properties, dpiProps, config.ProductAAPTPrebuiltDPI()[i])
-	}
-	if config.ProductAAPTPreferredConfig() != "" {
-		MergePropertiesFromVariant(ctx, &a.properties, dpiProps, config.ProductAAPTPreferredConfig())
-	}
-
-	archProps := reflect.ValueOf(a.archVariants).Elem().FieldByName("Arch")
-	archType := ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType
-	MergePropertiesFromVariant(ctx, &a.properties, archProps, archType.Name)
-
-	if String(a.properties.Apk) == "" {
-		// Disable this module since the apk property is still empty after processing all matching
-		// variants. This likely means there is no matching variant, and the default variant doesn't
-		// have an apk property value either.
-		a.Disable()
-	}
-}
-
-func MergePropertiesFromVariant(ctx android.EarlyModuleContext,
-	dst interface{}, variantGroup reflect.Value, variant string) {
-	src := variantGroup.FieldByName(proptools.FieldNameForProperty(variant))
-	if !src.IsValid() {
-		return
-	}
-
-	err := proptools.ExtendMatchingProperties([]interface{}{dst}, src.Interface(), nil, proptools.OrderAppend)
-	if err != nil {
-		if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
-			ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
-		} else {
-			panic(err)
-		}
-	}
-}
-
-func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) {
-	cert := android.SrcIsModule(String(a.properties.Certificate))
-	if cert != "" {
-		ctx.AddDependency(ctx.Module(), certificateTag, cert)
-	}
-
-	a.usesLibrary.deps(ctx, true)
-}
-
-func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
-	ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) {
-	// Test apps don't need their JNI libraries stored uncompressed. As a matter of fact, messing
-	// with them may invalidate pre-existing signature data.
-	if ctx.InstallInTestcases() && (Bool(a.properties.Presigned) || a.preprocessed) {
-		ctx.Build(pctx, android.BuildParams{
-			Rule:   android.Cp,
-			Output: outputPath,
-			Input:  inputPath,
-		})
-		return
-	}
-	rule := android.NewRuleBuilder(pctx, ctx)
-	rule.Command().
-		Textf(`if (zipinfo %s 'lib/*.so' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath).
-		BuiltTool("zip2zip").
-		FlagWithInput("-i ", inputPath).
-		FlagWithOutput("-o ", outputPath).
-		FlagWithArg("-0 ", "'lib/**/*.so'").
-		Textf(`; else cp -f %s %s; fi`, inputPath, outputPath)
-	rule.Build("uncompress-embedded-jni-libs", "Uncompress embedded JIN libs")
-}
-
-// Returns whether this module should have the dex file stored uncompressed in the APK.
-func (a *AndroidAppImport) shouldUncompressDex(ctx android.ModuleContext) bool {
-	if ctx.Config().UnbundledBuild() || a.preprocessed {
-		return false
-	}
-
-	// Uncompress dex in APKs of privileged apps
-	if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
-		return true
-	}
-
-	return shouldUncompressDex(ctx, &a.dexpreopter)
-}
-
-func (a *AndroidAppImport) uncompressDex(
-	ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) {
-	rule := android.NewRuleBuilder(pctx, ctx)
-	rule.Command().
-		Textf(`if (zipinfo %s '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath).
-		BuiltTool("zip2zip").
-		FlagWithInput("-i ", inputPath).
-		FlagWithOutput("-o ", outputPath).
-		FlagWithArg("-0 ", "'classes*.dex'").
-		Textf(`; else cp -f %s %s; fi`, inputPath, outputPath)
-	rule.Build("uncompress-dex", "Uncompress dex files")
-}
-
-func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	a.generateAndroidBuildActions(ctx)
-}
-
-func (a *AndroidAppImport) InstallApkName() string {
-	return a.BaseModuleName()
-}
-
-func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext) {
-	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
-	if !apexInfo.IsForPlatform() {
-		a.hideApexVariantFromMake = true
-	}
-
-	numCertPropsSet := 0
-	if String(a.properties.Certificate) != "" {
-		numCertPropsSet++
-	}
-	if Bool(a.properties.Presigned) {
-		numCertPropsSet++
-	}
-	if Bool(a.properties.Default_dev_cert) {
-		numCertPropsSet++
-	}
-	if numCertPropsSet != 1 {
-		ctx.ModuleErrorf("One and only one of certficate, presigned, and default_dev_cert properties must be set")
-	}
-
-	_, certificates := collectAppDeps(ctx, a, false, false)
-
-	// TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK
-	// TODO: LOCAL_PACKAGE_SPLITS
-
-	srcApk := a.prebuilt.SingleSourcePath(ctx)
-
-	if a.usesLibrary.enforceUsesLibraries() {
-		srcApk = a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk)
-	}
-
-	// TODO: Install or embed JNI libraries
-
-	// Uncompress JNI libraries in the apk
-	jnisUncompressed := android.PathForModuleOut(ctx, "jnis-uncompressed", ctx.ModuleName()+".apk")
-	a.uncompressEmbeddedJniLibs(ctx, srcApk, jnisUncompressed.OutputPath)
-
-	var installDir android.InstallPath
-	if Bool(a.properties.Privileged) {
-		installDir = android.PathForModuleInstall(ctx, "priv-app", a.BaseModuleName())
-	} else if ctx.InstallInTestcases() {
-		installDir = android.PathForModuleInstall(ctx, a.BaseModuleName(), ctx.DeviceConfig().DeviceArch())
-	} else {
-		installDir = android.PathForModuleInstall(ctx, "app", a.BaseModuleName())
-	}
-
-	a.dexpreopter.installPath = installDir.Join(ctx, a.BaseModuleName()+".apk")
-	a.dexpreopter.isPresignedPrebuilt = Bool(a.properties.Presigned)
-	a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
-
-	a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
-	a.dexpreopter.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
-
-	a.dexpreopter.dexpreopt(ctx, jnisUncompressed)
-	if a.dexpreopter.uncompressedDex {
-		dexUncompressed := android.PathForModuleOut(ctx, "dex-uncompressed", ctx.ModuleName()+".apk")
-		a.uncompressDex(ctx, jnisUncompressed, dexUncompressed.OutputPath)
-		jnisUncompressed = dexUncompressed
-	}
-
-	apkFilename := proptools.StringDefault(a.properties.Filename, a.BaseModuleName()+".apk")
-
-	// TODO: Handle EXTERNAL
-
-	// Sign or align the package if package has not been preprocessed
-	if a.preprocessed {
-		a.outputFile = srcApk
-		a.certificate = PresignedCertificate
-	} else if !Bool(a.properties.Presigned) {
-		// If the certificate property is empty at this point, default_dev_cert must be set to true.
-		// Which makes processMainCert's behavior for the empty cert string WAI.
-		certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
-		if len(certificates) != 1 {
-			ctx.ModuleErrorf("Unexpected number of certificates were extracted: %q", certificates)
-		}
-		a.certificate = certificates[0]
-		signed := android.PathForModuleOut(ctx, "signed", apkFilename)
-		var lineageFile android.Path
-		if lineage := String(a.properties.Lineage); lineage != "" {
-			lineageFile = android.PathForModuleSrc(ctx, lineage)
-		}
-		SignAppPackage(ctx, signed, jnisUncompressed, certificates, nil, lineageFile)
-		a.outputFile = signed
-	} else {
-		alignedApk := android.PathForModuleOut(ctx, "zip-aligned", apkFilename)
-		TransformZipAlign(ctx, alignedApk, jnisUncompressed)
-		a.outputFile = alignedApk
-		a.certificate = PresignedCertificate
-	}
-
-	// TODO: Optionally compress the output apk.
-
-	if apexInfo.IsForPlatform() {
-		a.installPath = ctx.InstallFile(installDir, apkFilename, a.outputFile)
-	}
-
-	// TODO: androidmk converter jni libs
-}
-
-func (a *AndroidAppImport) Prebuilt() *android.Prebuilt {
-	return &a.prebuilt
-}
-
-func (a *AndroidAppImport) Name() string {
-	return a.prebuilt.Name(a.ModuleBase.Name())
-}
-
-func (a *AndroidAppImport) OutputFile() android.Path {
-	return a.outputFile
-}
-
-func (a *AndroidAppImport) JacocoReportClassesFile() android.Path {
-	return nil
-}
-
-func (a *AndroidAppImport) Certificate() Certificate {
-	return a.certificate
-}
-
-var dpiVariantGroupType reflect.Type
-var archVariantGroupType reflect.Type
-
-func initAndroidAppImportVariantGroupTypes() {
-	dpiVariantGroupType = createVariantGroupType(supportedDpis, "Dpi_variants")
-
-	archNames := make([]string, len(android.ArchTypeList()))
-	for i, archType := range android.ArchTypeList() {
-		archNames[i] = archType.Name
-	}
-	archVariantGroupType = createVariantGroupType(archNames, "Arch")
-}
-
-// Populates all variant struct properties at creation time.
-func (a *AndroidAppImport) populateAllVariantStructs() {
-	a.dpiVariants = reflect.New(dpiVariantGroupType).Interface()
-	a.AddProperties(a.dpiVariants)
-
-	a.archVariants = reflect.New(archVariantGroupType).Interface()
-	a.AddProperties(a.archVariants)
-}
-
-func (a *AndroidAppImport) Privileged() bool {
-	return Bool(a.properties.Privileged)
-}
-
-func (a *AndroidAppImport) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
-	// android_app_import might have extra dependencies via uses_libs property.
-	// Don't track the dependency as we don't automatically add those libraries
-	// to the classpath. It should be explicitly added to java_libs property of APEX
-	return false
-}
-
-func (a *AndroidAppImport) sdkVersion() sdkSpec {
-	return sdkSpecFrom("")
-}
-
-func (a *AndroidAppImport) minSdkVersion() sdkSpec {
-	return sdkSpecFrom("")
-}
-
-var _ android.ApexModule = (*AndroidAppImport)(nil)
-
-// Implements android.ApexModule
-func (j *AndroidAppImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
-	sdkVersion android.ApiLevel) error {
-	// Do not check for prebuilts against the min_sdk_version of enclosing APEX
-	return nil
-}
-
-func createVariantGroupType(variants []string, variantGroupName string) reflect.Type {
-	props := reflect.TypeOf((*AndroidAppImportProperties)(nil))
-
-	variantFields := make([]reflect.StructField, len(variants))
-	for i, variant := range variants {
-		variantFields[i] = reflect.StructField{
-			Name: proptools.FieldNameForProperty(variant),
-			Type: props,
-		}
-	}
-
-	variantGroupStruct := reflect.StructOf(variantFields)
-	return reflect.StructOf([]reflect.StructField{
-		{
-			Name: variantGroupName,
-			Type: variantGroupStruct,
-		},
-	})
-}
-
-// android_app_import imports a prebuilt apk with additional processing specified in the module.
-// DPI-specific apk source files can be specified using dpi_variants. Example:
-//
-//     android_app_import {
-//         name: "example_import",
-//         apk: "prebuilts/example.apk",
-//         dpi_variants: {
-//             mdpi: {
-//                 apk: "prebuilts/example_mdpi.apk",
-//             },
-//             xhdpi: {
-//                 apk: "prebuilts/example_xhdpi.apk",
-//             },
-//         },
-//         certificate: "PRESIGNED",
-//     }
-func AndroidAppImportFactory() android.Module {
-	module := &AndroidAppImport{}
-	module.AddProperties(&module.properties)
-	module.AddProperties(&module.dexpreoptProperties)
-	module.AddProperties(&module.usesLibrary.usesLibraryProperties)
-	module.populateAllVariantStructs()
-	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
-		module.processVariants(ctx)
-	})
-
-	android.InitApexModule(module)
-	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
-	android.InitDefaultableModule(module)
-	android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk")
-
-	return module
-}
-
-type androidTestImportProperties struct {
-	// Whether the prebuilt apk can be installed without additional processing. Default is false.
-	Preprocessed *bool
-}
-
-type AndroidTestImport struct {
-	AndroidAppImport
-
-	testProperties testProperties
-
-	testImportProperties androidTestImportProperties
-
-	data android.Paths
-}
-
-func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	a.preprocessed = Bool(a.testImportProperties.Preprocessed)
-
-	a.generateAndroidBuildActions(ctx)
-
-	a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
-}
-
-func (a *AndroidTestImport) InstallInTestcases() bool {
-	return true
-}
-
-// 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.testProperties)
-	module.AddProperties(&module.testImportProperties)
-	module.populateAllVariantStructs()
-	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
-		module.processVariants(ctx)
-	})
-
-	module.dexpreopter.isTest = true
-
-	android.InitApexModule(module)
-	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
-	android.InitDefaultableModule(module)
-	android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk")
-
-	return module
-}
-
-type RuntimeResourceOverlay struct {
-	android.ModuleBase
-	android.DefaultableModuleBase
-	android.OverridableModuleBase
-	aapt
-
-	properties            RuntimeResourceOverlayProperties
-	overridableProperties OverridableRuntimeResourceOverlayProperties
-
-	certificate Certificate
-
-	outputFile android.Path
-	installDir android.InstallPath
-}
-
-type RuntimeResourceOverlayProperties struct {
-	// the name of a certificate in the default certificate directory or an android_app_certificate
-	// module name in the form ":module".
-	Certificate *string
-
-	// Name of the signing certificate lineage file.
-	Lineage *string
-
-	// optional theme name. If specified, the overlay package will be applied
-	// only when the ro.boot.vendor.overlay.theme system property is set to the same value.
-	Theme *string
-
-	// if not blank, set to the version of the sdk to compile against.
-	// Defaults to compiling against the current platform.
-	Sdk_version *string
-
-	// if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
-	// Defaults to sdk_version if not set.
-	Min_sdk_version *string
-
-	// list of android_library modules whose resources are extracted and linked against statically
-	Static_libs []string
-
-	// list of android_app modules whose resources are extracted and linked against
-	Resource_libs []string
-
-	// Names of modules to be overridden. Listed modules can only be other overlays
-	// (in Make or Soong).
-	// This does not completely prevent installation of the overridden overlays, but if both
-	// overlays would be installed by default (in PRODUCT_PACKAGES) the other overlay will be removed
-	// from PRODUCT_PACKAGES.
-	Overrides []string
-}
-
-// RuntimeResourceOverlayModule interface is used by the apex package to gather information from
-// a RuntimeResourceOverlay module.
-type RuntimeResourceOverlayModule interface {
-	android.Module
-	OutputFile() android.Path
-	Certificate() Certificate
-	Theme() string
-}
-
-func (r *RuntimeResourceOverlay) DepsMutator(ctx android.BottomUpMutatorContext) {
-	sdkDep := decodeSdkDep(ctx, sdkContext(r))
-	if sdkDep.hasFrameworkLibs() {
-		r.aapt.deps(ctx, sdkDep)
-	}
-
-	cert := android.SrcIsModule(String(r.properties.Certificate))
-	if cert != "" {
-		ctx.AddDependency(ctx.Module(), certificateTag, cert)
-	}
-
-	ctx.AddVariationDependencies(nil, staticLibTag, r.properties.Static_libs...)
-	ctx.AddVariationDependencies(nil, libTag, r.properties.Resource_libs...)
-}
-
-func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	// Compile and link resources
-	r.aapt.hasNoCode = true
-	// Do not remove resources without default values nor dedupe resource configurations with the same value
-	aaptLinkFlags := []string{"--no-resource-deduping", "--no-resource-removal"}
-	// Allow the override of "package name" and "overlay target package name"
-	manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
-	if overridden || r.overridableProperties.Package_name != nil {
-		// The product override variable has a priority over the package_name property.
-		if !overridden {
-			manifestPackageName = *r.overridableProperties.Package_name
-		}
-		aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, false)...)
-	}
-	if r.overridableProperties.Target_package_name != nil {
-		aaptLinkFlags = append(aaptLinkFlags,
-			"--rename-overlay-target-package "+*r.overridableProperties.Target_package_name)
-	}
-	r.aapt.buildActions(ctx, r, nil, aaptLinkFlags...)
-
-	// Sign the built package
-	_, certificates := collectAppDeps(ctx, r, false, false)
-	certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx)
-	signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk")
-	var lineageFile android.Path
-	if lineage := String(r.properties.Lineage); lineage != "" {
-		lineageFile = android.PathForModuleSrc(ctx, lineage)
-	}
-	SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil, lineageFile)
-	r.certificate = certificates[0]
-
-	r.outputFile = signed
-	r.installDir = android.PathForModuleInstall(ctx, "overlay", String(r.properties.Theme))
-	ctx.InstallFile(r.installDir, r.outputFile.Base(), r.outputFile)
-}
-
-func (r *RuntimeResourceOverlay) sdkVersion() sdkSpec {
-	return sdkSpecFrom(String(r.properties.Sdk_version))
-}
-
-func (r *RuntimeResourceOverlay) systemModules() string {
-	return ""
-}
-
-func (r *RuntimeResourceOverlay) minSdkVersion() sdkSpec {
-	if r.properties.Min_sdk_version != nil {
-		return sdkSpecFrom(*r.properties.Min_sdk_version)
-	}
-	return r.sdkVersion()
-}
-
-func (r *RuntimeResourceOverlay) targetSdkVersion() sdkSpec {
-	return r.sdkVersion()
-}
-
-func (r *RuntimeResourceOverlay) Certificate() Certificate {
-	return r.certificate
-}
-
-func (r *RuntimeResourceOverlay) OutputFile() android.Path {
-	return r.outputFile
-}
-
-func (r *RuntimeResourceOverlay) Theme() string {
-	return String(r.properties.Theme)
-}
-
-// runtime_resource_overlay generates a resource-only apk file that can overlay application and
-// system resources at run time.
-func RuntimeResourceOverlayFactory() android.Module {
-	module := &RuntimeResourceOverlay{}
-	module.AddProperties(
-		&module.properties,
-		&module.aaptProperties,
-		&module.overridableProperties)
-
-	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
-	android.InitDefaultableModule(module)
-	android.InitOverridableModule(module, &module.properties.Overrides)
-	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