Merge "Revert "Revert "Revert "Add path interposer""""
diff --git a/androidmk/cmd/androidmk/androidmk_test.go b/androidmk/cmd/androidmk/androidmk_test.go
index a54a4d2..ed5ae02 100644
--- a/androidmk/cmd/androidmk/androidmk_test.go
+++ b/androidmk/cmd/androidmk/androidmk_test.go
@@ -378,6 +378,33 @@
 }
 `,
 	},
+	{
+		desc: "Convert LOCAL_MODULE_TAGS tests to java_test",
+		in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := tests
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := tests
+include $(BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := tests
+include $(BUILD_HOST_JAVA_LIBRARY)
+`,
+
+		expected: `
+java_test {
+}
+
+android_test {
+}
+
+java_test_host {
+}
+`,
+	},
 
 	{
 		desc: "Input containing escaped quotes",
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index ee00907..05be3bd 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -45,12 +45,43 @@
 // A FixRequest specifies the details of which fixes to apply to an individual file
 // A FixRequest doesn't specify whether to do a dry run or where to write the results; that's in cmd/bpfix.go
 type FixRequest struct {
-	simplifyKnownRedundantVariables           bool
-	rewriteIncorrectAndroidmkPrebuilts        bool
-	rewriteIncorrectAndroidmkAndroidLibraries bool
-	mergeMatchingModuleProperties             bool
-	reorderCommonProperties                   bool
-	removeTags                                bool
+	steps []fixStep
+}
+
+type fixStep struct {
+	name string
+	fix  func(f *Fixer) error
+}
+
+var fixSteps = []fixStep{
+	{
+		name: "simplifyKnownRedundantVariables",
+		fix:  runPatchListMod(simplifyKnownPropertiesDuplicatingEachOther),
+	},
+	{
+		name: "rewriteIncorrectAndroidmkPrebuilts",
+		fix:  rewriteIncorrectAndroidmkPrebuilts,
+	},
+	{
+		name: "rewriteIncorrectAndroidmkAndroidLibraries",
+		fix:  rewriteIncorrectAndroidmkAndroidLibraries,
+	},
+	{
+		name: "rewriteTestModuleTypes",
+		fix:  rewriteTestModuleTypes,
+	},
+	{
+		name: "mergeMatchingModuleProperties",
+		fix:  runPatchListMod(mergeMatchingModuleProperties),
+	},
+	{
+		name: "reorderCommonProperties",
+		fix:  runPatchListMod(reorderCommonProperties),
+	},
+	{
+		name: "removeTags",
+		fix:  runPatchListMod(removeTags),
+	},
 }
 
 func NewFixRequest() FixRequest {
@@ -58,13 +89,8 @@
 }
 
 func (r FixRequest) AddAll() (result FixRequest) {
-	result = r
-	result.simplifyKnownRedundantVariables = true
-	result.rewriteIncorrectAndroidmkPrebuilts = true
-	result.rewriteIncorrectAndroidmkAndroidLibraries = true
-	result.mergeMatchingModuleProperties = true
-	result.reorderCommonProperties = true
-	result.removeTags = true
+	result.steps = append([]fixStep(nil), r.steps...)
+	result.steps = append(result.steps, fixSteps...)
 	return result
 }
 
@@ -148,43 +174,8 @@
 }
 
 func (f *Fixer) fixTreeOnce(config FixRequest) error {
-	if config.simplifyKnownRedundantVariables {
-		err := f.runPatchListMod(simplifyKnownPropertiesDuplicatingEachOther)
-		if err != nil {
-			return err
-		}
-	}
-
-	if config.rewriteIncorrectAndroidmkPrebuilts {
-		err := f.rewriteIncorrectAndroidmkPrebuilts()
-		if err != nil {
-			return err
-		}
-	}
-
-	if config.rewriteIncorrectAndroidmkAndroidLibraries {
-		err := f.rewriteIncorrectAndroidmkAndroidLibraries()
-		if err != nil {
-			return err
-		}
-	}
-
-	if config.mergeMatchingModuleProperties {
-		err := f.runPatchListMod(mergeMatchingModuleProperties)
-		if err != nil {
-			return err
-		}
-	}
-
-	if config.reorderCommonProperties {
-		err := f.runPatchListMod(reorderCommonProperties)
-		if err != nil {
-			return err
-		}
-	}
-
-	if config.removeTags {
-		err := f.runPatchListMod(removeTags)
+	for _, fix := range config.steps {
+		err := fix.fix(f)
 		if err != nil {
 			return err
 		}
@@ -198,7 +189,7 @@
 		"export_include_dirs", "local_include_dirs")
 }
 
-func (f *Fixer) rewriteIncorrectAndroidmkPrebuilts() error {
+func rewriteIncorrectAndroidmkPrebuilts(f *Fixer) error {
 	for _, def := range f.tree.Defs {
 		mod, ok := def.(*parser.Module)
 		if !ok {
@@ -234,7 +225,7 @@
 	return nil
 }
 
-func (f *Fixer) rewriteIncorrectAndroidmkAndroidLibraries() error {
+func rewriteIncorrectAndroidmkAndroidLibraries(f *Fixer) error {
 	for _, def := range f.tree.Defs {
 		mod, ok := def.(*parser.Module)
 		if !ok {
@@ -269,45 +260,87 @@
 	return nil
 }
 
-func (f *Fixer) runPatchListMod(modFunc func(mod *parser.Module, buf []byte, patchlist *parser.PatchList) error) error {
-	// Make sure all the offsets are accurate
-	buf, err := f.reparse()
-	if err != nil {
-		return err
-	}
-
-	var patchlist parser.PatchList
+// rewriteTestModuleTypes looks for modules that are identifiable as tests but for which Make doesn't have a separate
+// module class, and moves them to the appropriate Soong module type.
+func rewriteTestModuleTypes(f *Fixer) error {
 	for _, def := range f.tree.Defs {
 		mod, ok := def.(*parser.Module)
 		if !ok {
 			continue
 		}
 
-		err := modFunc(mod, buf, &patchlist)
-		if err != nil {
-			return err
+		if !strings.HasPrefix(mod.Type, "java_") && !strings.HasPrefix(mod.Type, "android_") {
+			continue
+		}
+
+		hasInstrumentationFor := hasNonEmptyLiteralStringProperty(mod, "instrumentation_for")
+		tags, _ := getLiteralListPropertyValue(mod, "tags")
+
+		var hasTestsTag bool
+		for _, tag := range tags {
+			if tag == "tests" {
+				hasTestsTag = true
+			}
+		}
+
+		isTest := hasInstrumentationFor || hasTestsTag
+
+		if isTest {
+			switch mod.Type {
+			case "android_app":
+				mod.Type = "android_test"
+			case "java_library":
+				mod.Type = "java_test"
+			case "java_library_host":
+				mod.Type = "java_test_host"
+			}
 		}
 	}
 
-	newBuf := new(bytes.Buffer)
-	err = patchlist.Apply(bytes.NewReader(buf), newBuf)
-	if err != nil {
-		return err
-	}
-
-	// Save a copy of the buffer to print for errors below
-	bufCopy := append([]byte(nil), newBuf.Bytes()...)
-
-	newTree, err := parse(f.tree.Name, newBuf)
-	if err != nil {
-		return fmt.Errorf("Failed to parse: %v\nBuffer:\n%s", err, string(bufCopy))
-	}
-
-	f.tree = newTree
-
 	return nil
 }
 
+func runPatchListMod(modFunc func(mod *parser.Module, buf []byte, patchlist *parser.PatchList) error) func(*Fixer) error {
+	return func(f *Fixer) error {
+		// Make sure all the offsets are accurate
+		buf, err := f.reparse()
+		if err != nil {
+			return err
+		}
+
+		var patchlist parser.PatchList
+		for _, def := range f.tree.Defs {
+			mod, ok := def.(*parser.Module)
+			if !ok {
+				continue
+			}
+
+			err := modFunc(mod, buf, &patchlist)
+			if err != nil {
+				return err
+			}
+		}
+
+		newBuf := new(bytes.Buffer)
+		err = patchlist.Apply(bytes.NewReader(buf), newBuf)
+		if err != nil {
+			return err
+		}
+
+		// Save a copy of the buffer to print for errors below
+		bufCopy := append([]byte(nil), newBuf.Bytes()...)
+
+		newTree, err := parse(f.tree.Name, newBuf)
+		if err != nil {
+			return fmt.Errorf("Failed to parse: %v\nBuffer:\n%s", err, string(bufCopy))
+		}
+
+		f.tree = newTree
+
+		return nil
+	}
+}
+
 var commonPropertyPriorities = []string{
 	"name",
 	"defaults",
@@ -394,26 +427,34 @@
 				// force installation for -eng builds.
 				`
 		case "tests":
-			if strings.Contains(mod.Type, "cc_test") || strings.Contains(mod.Type, "cc_library_static") {
+			switch {
+			case strings.Contains(mod.Type, "cc_test"),
+				strings.Contains(mod.Type, "cc_library_static"),
+				strings.Contains(mod.Type, "java_test"),
+				mod.Type == "android_test":
 				continue
-			} else if strings.Contains(mod.Type, "cc_lib") {
+			case strings.Contains(mod.Type, "cc_lib"):
 				replaceStr += `// WARNING: Module tags are not supported in Soong.
 					// To make a shared library only for tests, use the "cc_test_library" module
 					// type. If you don't use gtest, set "gtest: false".
 					`
-			} else if strings.Contains(mod.Type, "cc_bin") {
+			case strings.Contains(mod.Type, "cc_bin"):
 				replaceStr += `// WARNING: Module tags are not supported in Soong.
 					// For native test binaries, use the "cc_test" module type. Some differences:
 					//  - If you don't use gtest, set "gtest: false"
 					//  - Binaries will be installed into /data/nativetest[64]/<name>/<name>
 					//  - Both 32 & 64 bit versions will be built (as appropriate)
 					`
-			} else if strings.Contains(mod.Type, "java_lib") {
+			case strings.Contains(mod.Type, "java_lib"):
 				replaceStr += `// WARNING: Module tags are not supported in Soong.
 					// For JUnit or similar tests, use the "java_test" module type. A dependency on
 					// Junit will be added by default, if it is using some other runner, set "junit: false".
 					`
-			} else {
+			case mod.Type == "android_app":
+				replaceStr += `// WARNING: Module tags are not supported in Soong.
+					// For JUnit or instrumentataion app tests, use the "android_test" module type.
+					`
+			default:
 				replaceStr += `// WARNING: Module tags are not supported in Soong.
 					// In most cases, tests are now identified by their module type:
 					// cc_test, java_test, python_test
@@ -563,6 +604,11 @@
 	return found && len(list.Values) > 0
 }
 
+func hasNonEmptyLiteralStringProperty(mod *parser.Module, name string) bool {
+	s, found := getLiteralStringPropertyValue(mod, name)
+	return found && len(s) > 0
+}
+
 func getLiteralListProperty(mod *parser.Module, name string) (list *parser.List, found bool) {
 	prop, ok := mod.GetProperty(name)
 	if !ok {
@@ -572,6 +618,40 @@
 	return list, ok
 }
 
+func getLiteralListPropertyValue(mod *parser.Module, name string) (list []string, found bool) {
+	listValue, ok := getLiteralListProperty(mod, name)
+	if !ok {
+		return nil, false
+	}
+	for _, v := range listValue.Values {
+		stringValue, ok := v.(*parser.String)
+		if !ok {
+			return nil, false
+		}
+		list = append(list, stringValue.Value)
+	}
+
+	return list, true
+}
+
+func getLiteralStringProperty(mod *parser.Module, name string) (s *parser.String, found bool) {
+	prop, ok := mod.GetProperty(name)
+	if !ok {
+		return nil, false
+	}
+	s, ok = prop.Value.(*parser.String)
+	return s, ok
+}
+
+func getLiteralStringPropertyValue(mod *parser.Module, name string) (s string, found bool) {
+	stringValue, ok := getLiteralStringProperty(mod, name)
+	if !ok {
+		return "", false
+	}
+
+	return stringValue.Value, true
+}
+
 func propertyIndex(props []*parser.Property, propertyName string) int {
 	for i, prop := range props {
 		if prop.Name == propertyName {
diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go
index 654ccf9..6ba93f6 100644
--- a/bpfix/bpfix/bpfix_test.go
+++ b/bpfix/bpfix/bpfix_test.go
@@ -66,7 +66,7 @@
 	fixer := NewFixer(tree)
 
 	// apply simplifications
-	err := fixer.runPatchListMod(simplifyKnownPropertiesDuplicatingEachOther)
+	err := runPatchListMod(simplifyKnownPropertiesDuplicatingEachOther)(fixer)
 	if len(errs) > 0 {
 		t.Fatal(err)
 	}
@@ -251,7 +251,7 @@
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
 			runPass(t, test.in, test.out, func(fixer *Fixer) error {
-				return fixer.runPatchListMod(mergeMatchingModuleProperties)
+				return runPatchListMod(mergeMatchingModuleProperties)(fixer)
 			})
 		})
 	}
@@ -337,7 +337,7 @@
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
 			runPass(t, test.in, test.out, func(fixer *Fixer) error {
-				return fixer.runPatchListMod(reorderCommonProperties)
+				return runPatchListMod(reorderCommonProperties)(fixer)
 			})
 		})
 	}
@@ -490,9 +490,9 @@
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
 			runPass(t, test.in, test.out, func(fixer *Fixer) error {
-				return fixer.runPatchListMod(func(mod *parser.Module, buf []byte, patchList *parser.PatchList) error {
+				return runPatchListMod(func(mod *parser.Module, buf []byte, patchList *parser.PatchList) error {
 					return removeMatchingModuleListProperties(mod, patchList, "bar", "foo")
-				})
+				})(fixer)
 			})
 		})
 	}
diff --git a/cc/cc.go b/cc/cc.go
index a885c91..e261d40 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1554,16 +1554,35 @@
 	}
 
 	if genrule, ok := mctx.Module().(*genrule.Module); ok {
-		if props, ok := genrule.Extra.(*VendorProperties); ok {
+		if props, ok := genrule.Extra.(*GenruleExtraProperties); ok {
+			var coreVariantNeeded bool = false
+			var vendorVariantNeeded bool = false
+			var recoveryVariantNeeded bool = false
 			if mctx.DeviceConfig().VndkVersion() == "" {
-				mctx.CreateVariations(coreMode)
+				coreVariantNeeded = true
 			} else if Bool(props.Vendor_available) {
-				mctx.CreateVariations(coreMode, vendorMode)
+				coreVariantNeeded = true
+				vendorVariantNeeded = true
 			} else if mctx.SocSpecific() || mctx.DeviceSpecific() {
-				mctx.CreateVariations(vendorMode)
+				vendorVariantNeeded = true
 			} else {
-				mctx.CreateVariations(coreMode)
+				coreVariantNeeded = true
 			}
+			if Bool(props.Recovery_available) {
+				recoveryVariantNeeded = true
+			}
+
+			var variants []string
+			if coreVariantNeeded {
+				variants = append(variants, coreMode)
+			}
+			if vendorVariantNeeded {
+				variants = append(variants, vendorMode)
+			}
+			if recoveryVariantNeeded {
+				variants = append(variants, recoveryMode)
+			}
+			mctx.CreateVariations(variants...)
 		}
 	}
 
diff --git a/cc/compiler.go b/cc/compiler.go
index b410115..8f119cf 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -258,6 +258,8 @@
 	CheckBadCompilerFlags(ctx, "cppflags", compiler.Properties.Cppflags)
 	CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
 	CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)
+	CheckBadCompilerFlags(ctx, "vendor.cflags", compiler.Properties.Target.Vendor.Cflags)
+	CheckBadCompilerFlags(ctx, "recovery.cflags", compiler.Properties.Target.Recovery.Cflags)
 
 	esc := proptools.NinjaAndShellEscape
 
@@ -454,6 +456,10 @@
 		flags.CFlags = append(flags.CFlags, esc(compiler.Properties.Target.Vendor.Cflags)...)
 	}
 
+	if ctx.inRecovery() {
+		flags.CFlags = append(flags.CFlags, esc(compiler.Properties.Target.Recovery.Cflags)...)
+	}
+
 	// We can enforce some rules more strictly in the code we own. strict
 	// indicates if this is code that we can be stricter with. If we have
 	// rules that we want to apply to *our* code (but maybe can't for
diff --git a/cc/gen.go b/cc/gen.go
index f22a783..c794f5c 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -25,7 +25,7 @@
 )
 
 func init() {
-	pctx.SourcePathVariable("lexCmd", "prebuilts/misc/${config.HostPrebuiltTag}/flex/flex-2.5.39")
+	pctx.SourcePathVariable("lexCmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/flex")
 	pctx.SourcePathVariable("yaccCmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/bison")
 	pctx.SourcePathVariable("yaccDataDir", "prebuilts/build-tools/common/bison")
 
diff --git a/cc/genrule.go b/cc/genrule.go
index 51c0d16..a672992 100644
--- a/cc/genrule.go
+++ b/cc/genrule.go
@@ -23,13 +23,18 @@
 	android.RegisterModuleType("cc_genrule", genRuleFactory)
 }
 
+type GenruleExtraProperties struct {
+	Vendor_available   *bool
+	Recovery_available *bool
+}
+
 // 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.
 func genRuleFactory() android.Module {
 	module := genrule.NewGenRule()
 
-	module.Extra = &VendorProperties{}
+	module.Extra = &GenruleExtraProperties{}
 	module.AddProperties(module.Extra)
 
 	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibBoth)
diff --git a/cc/libbuildversion/Android.bp b/cc/libbuildversion/Android.bp
index fd563e6..825b920 100644
--- a/cc/libbuildversion/Android.bp
+++ b/cc/libbuildversion/Android.bp
@@ -1,6 +1,7 @@
 cc_library_static {
     name: "libbuildversion",
     host_supported: true,
+    recovery_available: true,
     srcs: ["libbuildversion.cpp"],
     export_include_dirs: ["include"],
     cflags: ["-fvisibility=hidden"],
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index 9fabc97..0ee0f05 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -26,7 +26,7 @@
 )
 
 var (
-	preprocessBionicHeaders = pctx.AndroidStaticRule("preprocessBionicHeaders",
+	versionBionicHeaders = pctx.AndroidStaticRule("versionBionicHeaders",
 		blueprint.RuleParams{
 			// The `&& touch $out` isn't really necessary, but Blueprint won't
 			// let us have only implicit outputs.
@@ -45,7 +45,7 @@
 	return getNdkSysrootBase(ctx).Join(ctx, "usr/include")
 }
 
-type headerProperies struct {
+type headerProperties struct {
 	// Base directory of the headers being installed. As an example:
 	//
 	// ndk_headers {
@@ -65,6 +65,9 @@
 	// List of headers to install. Glob compatible. Common case is "include/**/*.h".
 	Srcs []string
 
+	// Source paths that should be excluded from the srcs glob.
+	Exclude_srcs []string
+
 	// Path to the NOTICE file associated with the headers.
 	License *string
 }
@@ -72,7 +75,7 @@
 type headerModule struct {
 	android.ModuleBase
 
-	properties headerProperies
+	properties headerProperties
 
 	installPaths android.Paths
 	licensePath  android.ModuleSrcPath
@@ -128,7 +131,7 @@
 		return
 	}
 
-	srcFiles := ctx.ExpandSources(m.properties.Srcs, nil)
+	srcFiles := ctx.ExpandSources(m.properties.Srcs, m.properties.Exclude_srcs)
 	for _, header := range srcFiles {
 		installDir := getHeaderInstallDir(ctx, header, String(m.properties.From),
 			String(m.properties.To))
@@ -154,10 +157,10 @@
 	return module
 }
 
-type preprocessedHeaderProperies struct {
+type versionedHeaderProperties struct {
 	// Base directory of the headers being installed. As an example:
 	//
-	// preprocessed_ndk_headers {
+	// versioned_ndk_headers {
 	//     name: "foo",
 	//     from: "include",
 	//     to: "",
@@ -181,19 +184,19 @@
 // module does not have the srcs property, and operates on a full directory (the `from` property).
 //
 // Note that this is really only built to handle bionic/libc/include.
-type preprocessedHeaderModule struct {
+type versionedHeaderModule struct {
 	android.ModuleBase
 
-	properties preprocessedHeaderProperies
+	properties versionedHeaderProperties
 
 	installPaths android.Paths
 	licensePath  android.ModuleSrcPath
 }
 
-func (m *preprocessedHeaderModule) DepsMutator(ctx android.BottomUpMutatorContext) {
+func (m *versionedHeaderModule) DepsMutator(ctx android.BottomUpMutatorContext) {
 }
 
-func (m *preprocessedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (m *versionedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	if String(m.properties.License) == "" {
 		ctx.PropertyErrorf("license", "field is required")
 	}
@@ -248,7 +251,7 @@
 
 	timestampFile := android.PathForModuleOut(ctx, "versioner.timestamp")
 	ctx.Build(pctx, android.BuildParams{
-		Rule:            preprocessBionicHeaders,
+		Rule:            versionBionicHeaders,
 		Description:     "versioner preprocess " + srcDir.Rel(),
 		Output:          timestampFile,
 		Implicits:       append(srcFiles, depsGlob...),
@@ -263,8 +266,8 @@
 	return timestampFile
 }
 
-func preprocessedNdkHeadersFactory() android.Module {
-	module := &preprocessedHeaderModule{}
+func versionedNdkHeadersFactory() android.Module {
+	module := &versionedHeaderModule{}
 
 	module.AddProperties(&module.properties)
 
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index c7ba588..1a46702 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -59,7 +59,7 @@
 func init() {
 	android.RegisterModuleType("ndk_headers", ndkHeadersFactory)
 	android.RegisterModuleType("ndk_library", ndkLibraryFactory)
-	android.RegisterModuleType("preprocessed_ndk_headers", preprocessedNdkHeadersFactory)
+	android.RegisterModuleType("versioned_ndk_headers", versionedNdkHeadersFactory)
 	android.RegisterSingletonType("ndk", NdkSingleton)
 
 	pctx.Import("android/soong/common")
@@ -107,7 +107,7 @@
 			licensePaths = append(licensePaths, m.licensePath)
 		}
 
-		if m, ok := module.(*preprocessedHeaderModule); ok {
+		if m, ok := module.(*versionedHeaderModule); ok {
 			installPaths = append(installPaths, m.installPaths...)
 			licensePaths = append(licensePaths, m.licensePath)
 		}
diff --git a/java/aar.go b/java/aar.go
index 66f1cab..21e38a4 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -354,6 +354,7 @@
 	proguardFlags         android.WritablePath
 	exportPackage         android.WritablePath
 	extraAaptPackagesFile android.WritablePath
+	manifest              android.WritablePath
 
 	exportedStaticPackages android.Paths
 }
@@ -413,12 +414,12 @@
 	extractedResDir := extractedAARDir.Join(ctx, "res")
 	a.classpathFile = extractedAARDir.Join(ctx, "classes.jar")
 	a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
-	manifest := extractedAARDir.Join(ctx, "AndroidManifest.xml")
+	a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
 
 	ctx.Build(pctx, android.BuildParams{
 		Rule:        unzipAAR,
 		Input:       aar,
-		Outputs:     android.WritablePaths{a.classpathFile, a.proguardFlags, manifest},
+		Outputs:     android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest},
 		Description: "unzip AAR",
 		Args: map[string]string{
 			"expectedDirs": extractedResDir.String(),
@@ -446,8 +447,8 @@
 		"--auto-add-overlay",
 	}
 
-	linkFlags = append(linkFlags, "--manifest "+manifest.String())
-	linkDeps = append(linkDeps, manifest)
+	linkFlags = append(linkFlags, "--manifest "+a.manifest.String())
+	linkDeps = append(linkDeps, a.manifest)
 
 	transitiveStaticLibs, libDeps, libFlags := aaptLibs(ctx, String(a.properties.Sdk_version))
 
diff --git a/java/androidmk.go b/java/androidmk.go
index 88dc6ef..0840198 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -136,6 +136,7 @@
 				fmt.Fprintln(w, "LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE :=", prebuilt.exportPackage.String())
 				fmt.Fprintln(w, "LOCAL_SOONG_EXPORT_PROGUARD_FLAGS :=", prebuilt.proguardFlags.String())
 				fmt.Fprintln(w, "LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES :=", prebuilt.extraAaptPackagesFile.String())
+				fmt.Fprintln(w, "LOCAL_FULL_MANIFEST_FILE :=", prebuilt.manifest.String())
 				fmt.Fprintln(w, "LOCAL_SDK_VERSION :=", String(prebuilt.properties.Sdk_version))
 			},
 		},
@@ -228,6 +229,19 @@
 	}
 }
 
+func (a *AndroidTest) AndroidMk() android.AndroidMkData {
+	data := a.AndroidApp.AndroidMk()
+	data.Extra = append(data.Extra, func(w io.Writer, outputFile android.Path) {
+		fmt.Fprintln(w, "LOCAL_MODULE_TAGS := tests")
+		if len(a.testProperties.Test_suites) > 0 {
+			fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=",
+				strings.Join(a.testProperties.Test_suites, " "))
+		}
+	})
+
+	return data
+}
+
 func (a *AndroidLibrary) AndroidMk() android.AndroidMkData {
 	data := a.Library.AndroidMk()
 
diff --git a/java/app.go b/java/app.go
index ae0592a..37109b5 100644
--- a/java/app.go
+++ b/java/app.go
@@ -26,6 +26,7 @@
 
 func init() {
 	android.RegisterModuleType("android_app", AndroidAppFactory)
+	android.RegisterModuleType("android_test", AndroidTestFactory)
 }
 
 // AndroidManifest.xml merging
@@ -50,8 +51,6 @@
 
 	// list of resource labels to generate individual resource packages
 	Package_splits []string
-
-	Instrumentation_for *string
 }
 
 type AndroidApp struct {
@@ -61,6 +60,8 @@
 	certificate certificate
 
 	appProperties appProperties
+
+	extraLinkFlags []string
 }
 
 func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
@@ -85,14 +86,11 @@
 }
 
 func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	var linkFlags []string
-	if String(a.appProperties.Instrumentation_for) != "" {
-		linkFlags = append(linkFlags,
-			"--rename-instrumentation-target-package",
-			String(a.appProperties.Instrumentation_for))
-	} else {
-		a.properties.Instrument = true
-	}
+	a.generateAndroidBuildActions(ctx)
+}
+
+func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
+	linkFlags := append([]string(nil), a.extraLinkFlags...)
 
 	hasProduct := false
 	for _, f := range a.aaptProperties.Aaptflags {
@@ -188,6 +186,8 @@
 	module.Module.deviceProperties.Optimize.Enabled = proptools.BoolPtr(true)
 	module.Module.deviceProperties.Optimize.Shrink = proptools.BoolPtr(true)
 
+	module.Module.properties.Instrument = true
+
 	module.AddProperties(
 		&module.Module.properties,
 		&module.Module.deviceProperties,
@@ -198,3 +198,43 @@
 	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
 	return module
 }
+
+type appTestProperties struct {
+	Instrumentation_for *string
+}
+
+type AndroidTest struct {
+	AndroidApp
+
+	appTestProperties appTestProperties
+
+	testProperties testProperties
+}
+
+func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	if String(a.appTestProperties.Instrumentation_for) != "" {
+		a.AndroidApp.extraLinkFlags = append(a.AndroidApp.extraLinkFlags,
+			"--rename-instrumentation-target-package",
+			String(a.appTestProperties.Instrumentation_for))
+	}
+
+	a.generateAndroidBuildActions(ctx)
+}
+
+func AndroidTestFactory() android.Module {
+	module := &AndroidTest{}
+
+	module.Module.deviceProperties.Optimize.Enabled = proptools.BoolPtr(true)
+
+	module.AddProperties(
+		&module.Module.properties,
+		&module.Module.deviceProperties,
+		&module.Module.protoProperties,
+		&module.aaptProperties,
+		&module.appProperties,
+		&module.appTestProperties)
+
+	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+
+	return module
+}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index b34c393..cda50f0 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -110,6 +110,14 @@
 
 	// if not blank, set to the version of the sdk to compile against
 	Sdk_version *string `android:"arch_variant"`
+
+	Aidl struct {
+		// Top level directories to pass to aidl tool
+		Include_dirs []string
+
+		// Directories rooted at the Android.bp file to pass to aidl tool
+		Local_include_dirs []string
+	}
 }
 
 type ApiToCheck struct {
@@ -310,6 +318,60 @@
 	}
 }
 
+func (j *Javadoc) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags {
+	var flags javaBuilderFlags
+
+	// aidl flags.
+	aidlFlags := j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
+	if len(aidlFlags) > 0 {
+		// optimization.
+		ctx.Variable(pctx, "aidlFlags", strings.Join(aidlFlags, " "))
+		flags.aidlFlags = "$aidlFlags"
+	}
+
+	return flags
+}
+
+func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
+	aidlIncludeDirs android.Paths) []string {
+
+	aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
+	aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
+
+	var flags []string
+	if aidlPreprocess.Valid() {
+		flags = append(flags, "-p"+aidlPreprocess.String())
+	} else {
+		flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
+	}
+
+	flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
+	flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
+	if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
+		flags = append(flags, "-I"+src.String())
+	}
+
+	return flags
+}
+
+func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
+	flags javaBuilderFlags) android.Paths {
+
+	outSrcFiles := make(android.Paths, 0, len(srcFiles))
+
+	for _, srcFile := range srcFiles {
+		switch srcFile.Ext() {
+		case ".aidl":
+			javaFile := genAidl(ctx, srcFile, flags.aidlFlags)
+			outSrcFiles = append(outSrcFiles, javaFile)
+		default:
+			outSrcFiles = append(outSrcFiles, srcFile)
+		}
+	}
+
+	return outSrcFiles
+}
+
 func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
 	var deps deps
 
@@ -388,6 +450,8 @@
 	// do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
 	// may contain filegroup or genrule.
 	srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
+	flags := j.collectBuilderFlags(ctx, deps)
+	srcFiles = j.genSources(ctx, srcFiles, flags)
 
 	// srcs may depend on some genrule output.
 	j.srcJars = srcFiles.FilterByExt(".srcjar")
diff --git a/java/java.go b/java/java.go
index a4cb65b..02fdc00 100644
--- a/java/java.go
+++ b/java/java.go
@@ -212,8 +212,8 @@
 	}
 
 	Optimize struct {
-		// If false, disable all optimization.  Defaults to true for apps, false for
-		// libraries and tests.
+		// If false, disable all optimization.  Defaults to true for android_app and android_test
+		// modules, false for java_library and java_test modules.
 		Enabled *bool
 
 		// If true, optimize for size by removing unused code.  Defaults to true for apps,
diff --git a/java/java_test.go b/java/java_test.go
index fe1c3d7..baf4b72 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -200,6 +200,7 @@
 
 		"bar-doc/a.java":                 nil,
 		"bar-doc/b.java":                 nil,
+		"bar-doc/IFoo.aidl":              nil,
 		"bar-doc/known_oj_tags.txt":      nil,
 		"external/doclava/templates-sdk": nil,
 
@@ -921,6 +922,7 @@
 		    name: "bar-doc",
 		    srcs: [
 		        "bar-doc/*.java",
+		        "bar-doc/IFoo.aidl",
 		    ],
 		    exclude_srcs: [
 		        "bar-doc/b.java"
@@ -943,6 +945,14 @@
 	if stubsJar != barDoc.Output.String() {
 		t.Errorf("expected stubs Jar [%q], got %q", stubsJar, barDoc.Output.String())
 	}
+	inputs := ctx.ModuleForTests("bar-doc", "android_common").Rule("javadoc").Inputs
+	var javaSrcs []string
+	for _, i := range inputs {
+		javaSrcs = append(javaSrcs, i.Base())
+	}
+	if len(javaSrcs) != 2 || javaSrcs[0] != "a.java" || javaSrcs[1] != "IFoo.java" {
+		t.Errorf("inputs of bar-doc must be []string{\"a.java\", \"IFoo.java\", but was %#v.", javaSrcs)
+	}
 }
 
 func TestJarGenrules(t *testing.T) {