Merge "Add a rust_bindgen_host module type."
diff --git a/android/Android.bp b/android/Android.bp
index 6ddcc14..96f0983 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -39,6 +39,7 @@
         "paths.go",
         "phony.go",
         "prebuilt.go",
+        "prebuilt_build_tool.go",
         "proto.go",
         "register.go",
         "rule_builder.go",
diff --git a/android/androidmk.go b/android/androidmk.go
index 94b4b81..7e86140 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -126,6 +126,26 @@
 	}
 }
 
+func (a *AndroidMkEntries) SetPaths(name string, paths Paths) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.entryOrder = append(a.entryOrder, name)
+	}
+	a.EntryMap[name] = paths.Strings()
+}
+
+func (a *AndroidMkEntries) SetOptionalPaths(name string, paths Paths) {
+	if len(paths) > 0 {
+		a.SetPaths(name, paths)
+	}
+}
+
+func (a *AndroidMkEntries) AddPaths(name string, paths Paths) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.entryOrder = append(a.entryOrder, name)
+	}
+	a.EntryMap[name] = append(a.EntryMap[name], paths.Strings()...)
+}
+
 func (a *AndroidMkEntries) SetBoolIfTrue(name string, flag bool) {
 	if flag {
 		if _, ok := a.EntryMap[name]; !ok {
diff --git a/android/apex.go b/android/apex.go
index 47f07ca..a7570dc 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -65,9 +65,9 @@
 
 	apexModuleBase() *ApexModuleBase
 
-	// Marks that this module should be built for the specified APEXes.
+	// Marks that this module should be built for the specified APEX.
 	// Call this before apex.apexMutator is run.
-	BuildForApexes(apexes []ApexInfo)
+	BuildForApex(apex ApexInfo)
 
 	// Returns the APEXes that this module will be built for
 	ApexVariations() []ApexInfo
@@ -96,7 +96,7 @@
 	IsInstallableToApex() bool
 
 	// Mutate this module into one or more variants each of which is built
-	// for an APEX marked via BuildForApexes().
+	// for an APEX marked via BuildForApex().
 	CreateApexVariations(mctx BottomUpMutatorContext) []Module
 
 	// Tests if this module is available for the specified APEX or ":platform"
@@ -178,18 +178,15 @@
 	return nil
 }
 
-func (m *ApexModuleBase) BuildForApexes(apexes []ApexInfo) {
+func (m *ApexModuleBase) BuildForApex(apex ApexInfo) {
 	m.apexVariationsLock.Lock()
 	defer m.apexVariationsLock.Unlock()
-nextApex:
-	for _, apex := range apexes {
-		for _, v := range m.apexVariations {
-			if v.ApexName == apex.ApexName {
-				continue nextApex
-			}
+	for _, v := range m.apexVariations {
+		if v.ApexName == apex.ApexName {
+			return
 		}
-		m.apexVariations = append(m.apexVariations, apex)
 	}
+	m.apexVariations = append(m.apexVariations, apex)
 }
 
 func (m *ApexModuleBase) ApexVariations() []ApexInfo {
@@ -327,17 +324,15 @@
 // depended on by the specified APEXes. Directly depending means that a module
 // is explicitly listed in the build definition of the APEX via properties like
 // native_shared_libs, java_libs, etc.
-func UpdateApexDependency(apexes []ApexInfo, moduleName string, directDep bool) {
+func UpdateApexDependency(apex ApexInfo, moduleName string, directDep bool) {
 	apexNamesMapMutex.Lock()
 	defer apexNamesMapMutex.Unlock()
-	for _, apex := range apexes {
-		apexesForModule, ok := apexNamesMap()[moduleName]
-		if !ok {
-			apexesForModule = make(map[string]bool)
-			apexNamesMap()[moduleName] = apexesForModule
-		}
-		apexesForModule[apex.ApexName] = apexesForModule[apex.ApexName] || directDep
+	apexesForModule, ok := apexNamesMap()[moduleName]
+	if !ok {
+		apexesForModule = make(map[string]bool)
+		apexNamesMap()[moduleName] = apexesForModule
 	}
+	apexesForModule[apex.ApexName] = apexesForModule[apex.ApexName] || directDep
 }
 
 // TODO(b/146393795): remove this when b/146393795 is fixed
diff --git a/android/defs.go b/android/defs.go
index 4552224..83daa03 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -69,7 +69,7 @@
 	// A symlink rule.
 	Symlink = pctx.AndroidStaticRule("Symlink",
 		blueprint.RuleParams{
-			Command:     "ln -f -s $fromPath $out",
+			Command:     "rm -f $out && ln -f -s $fromPath $out",
 			Description: "symlink $out",
 		},
 		"fromPath")
diff --git a/android/prebuilt_build_tool.go b/android/prebuilt_build_tool.go
new file mode 100644
index 0000000..d457da4
--- /dev/null
+++ b/android/prebuilt_build_tool.go
@@ -0,0 +1,100 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+	"path"
+	"path/filepath"
+)
+
+func init() {
+	RegisterModuleType("prebuilt_build_tool", prebuiltBuildToolFactory)
+}
+
+type prebuiltBuildToolProperties struct {
+	// Source file to be executed for this build tool
+	Src *string `android:"path,arch_variant"`
+
+	// Extra files that should trigger rules using this tool to rebuild
+	Deps []string `android:"path,arch_variant"`
+}
+
+type prebuiltBuildTool struct {
+	ModuleBase
+	prebuilt Prebuilt
+
+	properties prebuiltBuildToolProperties
+
+	toolPath OptionalPath
+}
+
+func (t *prebuiltBuildTool) Name() string {
+	return t.prebuilt.Name(t.ModuleBase.Name())
+}
+
+func (t *prebuiltBuildTool) Prebuilt() *Prebuilt {
+	return &t.prebuilt
+}
+
+func (t *prebuiltBuildTool) DepsMutator(ctx BottomUpMutatorContext) {
+	if t.properties.Src == nil {
+		ctx.PropertyErrorf("src", "missing prebuilt source file")
+	}
+}
+
+func (t *prebuiltBuildTool) GenerateAndroidBuildActions(ctx ModuleContext) {
+	sourcePath := t.prebuilt.SingleSourcePath(ctx)
+	installedPath := PathForModuleOut(ctx, t.ModuleBase.Name())
+	deps := PathsForModuleSrc(ctx, t.properties.Deps)
+
+	var relPath string
+	if filepath.IsAbs(installedPath.String()) {
+		relPath = filepath.Join(absSrcDir, sourcePath.String())
+	} else {
+		var err error
+		relPath, err = filepath.Rel(path.Dir(installedPath.String()), sourcePath.String())
+		if err != nil {
+			ctx.ModuleErrorf("Unable to generate symlink between %q and %q: %s", installedPath.String(), sourcePath.String(), err)
+		}
+	}
+
+	ctx.Build(pctx, BuildParams{
+		Rule:      Symlink,
+		Output:    installedPath,
+		Input:     sourcePath,
+		Implicits: deps,
+		Args: map[string]string{
+			"fromPath": relPath,
+		},
+	})
+
+	t.toolPath = OptionalPathForPath(installedPath)
+}
+
+func (t *prebuiltBuildTool) HostToolPath() OptionalPath {
+	return t.toolPath
+}
+
+var _ HostToolProvider = &prebuiltBuildTool{}
+
+// prebuilt_build_tool is to declare prebuilts to be used during the build, particularly for use
+// in genrules with the "tools" property.
+func prebuiltBuildToolFactory() Module {
+	module := &prebuiltBuildTool{}
+	module.AddProperties(&module.properties)
+	InitSingleSourcePrebuiltModule(module, &module.properties, "Src")
+	InitAndroidArchModule(module, HostSupportedNoCross, MultilibFirst)
+	return module
+}
diff --git a/android/sdk.go b/android/sdk.go
index 2c38f56..28f5cd5 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -34,10 +34,8 @@
 	RequiredSdks() SdkRefs
 }
 
-// SdkAware is the interface that must be supported by any module to become a member of SDK or to be
-// built with SDK
-type SdkAware interface {
-	Module
+// Provided to improve code navigation with the IDE.
+type sdkAwareWithoutModule interface {
 	RequiredSdks
 
 	sdkBase() *SdkBase
@@ -48,6 +46,13 @@
 	BuildWithSdks(sdks SdkRefs)
 }
 
+// SdkAware is the interface that must be supported by any module to become a member of SDK or to be
+// built with SDK
+type SdkAware interface {
+	Module
+	sdkAwareWithoutModule
+}
+
 // SdkRef refers to a version of an SDK
 type SdkRef struct {
 	Name    string
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 10cc4b6..e739e2b 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -353,6 +353,10 @@
 				if apexType == imageApex {
 					fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).BUNDLE :=", a.bundleModuleFile.String())
 				}
+				if len(a.lintReports) > 0 {
+					fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).LINT_REPORTS :=",
+						strings.Join(a.lintReports.Strings(), " "))
+				}
 
 				if a.installedFilesFile != nil {
 					goal := "checkbuild"
diff --git a/apex/apex.go b/apex/apex.go
index d0c4e6e..fa986cd 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -669,7 +669,7 @@
 }
 
 func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
-	ctx.TopDown("apex_deps", apexDepsMutator)
+	ctx.TopDown("apex_deps", apexDepsMutator).Parallel()
 	ctx.BottomUp("apex", apexMutator).Parallel()
 	ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
 	ctx.BottomUp("apex_uses", apexUsesMutator).Parallel()
@@ -682,33 +682,30 @@
 	if !mctx.Module().Enabled() {
 		return
 	}
-	var apexBundles []android.ApexInfo
-	var directDep bool
-	if a, ok := mctx.Module().(*apexBundle); ok && !a.vndkApex {
-		apexBundles = []android.ApexInfo{{
-			ApexName:      mctx.ModuleName(),
-			MinSdkVersion: a.minSdkVersion(mctx),
-			Updatable:     a.Updatable(),
-		}}
-		directDep = true
-	} else if am, ok := mctx.Module().(android.ApexModule); ok {
-		apexBundles = am.ApexVariations()
-		directDep = false
-	}
-
-	if len(apexBundles) == 0 {
+	a, ok := mctx.Module().(*apexBundle)
+	if !ok || a.vndkApex {
 		return
 	}
-
-	cur := mctx.Module().(android.DepIsInSameApex)
-
-	mctx.VisitDirectDeps(func(child android.Module) {
-		depName := mctx.OtherModuleName(child)
-		if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() &&
-			(cur.DepIsInSameApex(mctx, child) || inAnySdk(child)) {
-			android.UpdateApexDependency(apexBundles, depName, directDep)
-			am.BuildForApexes(apexBundles)
+	apexInfo := android.ApexInfo{
+		ApexName:      mctx.ModuleName(),
+		MinSdkVersion: a.minSdkVersion(mctx),
+		Updatable:     a.Updatable(),
+	}
+	mctx.WalkDeps(func(child, parent android.Module) bool {
+		am, ok := child.(android.ApexModule)
+		if !ok || !am.CanHaveApexVariants() {
+			return false
 		}
+		if !parent.(android.DepIsInSameApex).DepIsInSameApex(mctx, child) && !inAnySdk(child) {
+			return false
+		}
+
+		depName := mctx.OtherModuleName(child)
+		// If the parent is apexBundle, this child is directly depended.
+		_, directDep := parent.(*apexBundle)
+		android.UpdateApexDependency(apexInfo, depName, directDep)
+		am.BuildForApex(apexInfo)
+		return true
 	})
 }
 
@@ -1154,6 +1151,7 @@
 	hostRequiredModuleNames   []string
 
 	jacocoReportClassesFile android.Path     // only for javalibs and apps
+	lintDepSets             java.LintDepSets // only for javalibs and apps
 	certificate             java.Certificate // only for apps
 	overriddenPackageName   string           // only for apps
 
@@ -1278,6 +1276,9 @@
 
 	// Struct holding the merged notice file paths in different formats
 	mergedNotices android.NoticeOutputs
+
+	// Optional list of lint report zip files for apexes that contain java or app modules
+	lintReports android.Paths
 }
 
 func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@@ -1666,9 +1667,16 @@
 type javaDependency interface {
 	DexJarBuildPath() android.Path
 	JacocoReportClassesFile() android.Path
+	LintDepSets() java.LintDepSets
+
 	Stem() string
 }
 
+var _ javaDependency = (*java.Library)(nil)
+var _ javaDependency = (*java.SdkLibrary)(nil)
+var _ javaDependency = (*java.DexImport)(nil)
+var _ javaDependency = (*java.SdkLibraryImport)(nil)
+
 func apexFileForJavaLibrary(ctx android.BaseModuleContext, lib javaDependency, module android.Module) apexFile {
 	dirInApex := "javalib"
 	fileToCopy := lib.DexJarBuildPath()
@@ -1676,6 +1684,7 @@
 	name := strings.TrimPrefix(module.Name(), "prebuilt_")
 	af := newApexFile(ctx, fileToCopy, name, dirInApex, javaSharedLib, module)
 	af.jacocoReportClassesFile = lib.JacocoReportClassesFile()
+	af.lintDepSets = lib.LintDepSets()
 	af.stem = lib.Stem() + ".jar"
 	return af
 }
@@ -2275,6 +2284,8 @@
 	a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
 
 	a.buildApexDependencyInfo(ctx)
+
+	a.buildLintReports(ctx)
 }
 
 // Enforce that Java deps of the apex are using stable SDKs to compile
diff --git a/apex/builder.go b/apex/builder.go
index a70c767..0a1ec3e 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -815,3 +815,12 @@
 		},
 	})
 }
+
+func (a *apexBundle) buildLintReports(ctx android.ModuleContext) {
+	depSetsBuilder := java.NewLintDepSetBuilder()
+	for _, fi := range a.filesInfo {
+		depSetsBuilder.Transitive(fi.lintDepSets)
+	}
+
+	a.lintReports = java.BuildModuleLintReportZips(ctx, depSetsBuilder.Build())
+}
diff --git a/cc/cc.go b/cc/cc.go
index fdf2879..bea851f 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -116,6 +116,8 @@
 	// Used for host bionic
 	LinkerFlagsFile string
 	DynamicLinker   string
+
+	Tools []string
 }
 
 type PathDeps struct {
@@ -158,6 +160,8 @@
 
 	// Path to the dynamic linker binary
 	DynamicLinker android.OptionalPath
+
+	Tools map[string]android.Path
 }
 
 // LocalOrGlobalFlags contains flags that need to have values set globally by the build system or locally by the module
@@ -425,6 +429,12 @@
 	XrefCcFiles() android.Paths
 }
 
+type ToolDependencyTag struct {
+	blueprint.BaseDependencyTag
+
+	Name string
+}
+
 var (
 	dataLibDepTag         = DependencyTag{Name: "data_lib", Library: true, Shared: true}
 	sharedExportDepTag    = DependencyTag{Name: "shared", Library: true, Shared: true, ReexportFlags: true}
@@ -1694,6 +1704,7 @@
 	deps.LateSharedLibs = android.LastUniqueStrings(deps.LateSharedLibs)
 	deps.HeaderLibs = android.LastUniqueStrings(deps.HeaderLibs)
 	deps.RuntimeLibs = android.LastUniqueStrings(deps.RuntimeLibs)
+	deps.Tools = android.LastUniqueStrings(deps.Tools)
 
 	for _, lib := range deps.ReexportSharedLibHeaders {
 		if !inList(lib, deps.SharedLibs) {
@@ -2037,6 +2048,11 @@
 			}, vndkExtDepTag, vndkdep.getVndkExtendsModuleName())
 		}
 	}
+
+	for _, tool := range deps.Tools {
+		actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(),
+			ToolDependencyTag{Name: tool}, tool)
+	}
 }
 
 func BeginMutator(ctx android.BottomUpMutatorContext) {
@@ -2215,10 +2231,38 @@
 		depPaths.ReexportedGeneratedHeaders = append(depPaths.ReexportedGeneratedHeaders, exporter.exportedGeneratedHeaders()...)
 	}
 
+	// For the dependency from platform to apex, use the latest stubs
+	c.apexSdkVersion = android.FutureApiLevel
+	if !c.IsForPlatform() {
+		c.apexSdkVersion = c.ApexProperties.Info.MinSdkVersion
+	}
+
+	if android.InList("hwaddress", ctx.Config().SanitizeDevice()) {
+		// In hwasan build, we override apexSdkVersion to the FutureApiLevel(10000)
+		// so that even Q(29/Android10) apexes could use the dynamic unwinder by linking the newer stubs(e.g libc(R+)).
+		// (b/144430859)
+		c.apexSdkVersion = android.FutureApiLevel
+	}
+
 	ctx.VisitDirectDeps(func(dep android.Module) {
 		depName := ctx.OtherModuleName(dep)
 		depTag := ctx.OtherModuleDependencyTag(dep)
 
+		if toolDep, ok := depTag.(ToolDependencyTag); ok {
+			if toolMod, ok := dep.(android.HostToolProvider); ok {
+				if depPaths.Tools == nil {
+					depPaths.Tools = make(map[string]android.Path)
+				}
+				toolPath := toolMod.HostToolPath()
+				if !toolPath.Valid() {
+					ctx.ModuleErrorf("Failed to find path for host tool %q", toolDep.Name)
+				}
+				depPaths.Tools[toolDep.Name] = toolPath.Path()
+			} else {
+				ctx.ModuleErrorf("Found module, but not host tool for %q", toolDep.Name)
+			}
+		}
+
 		ccDep, ok := dep.(LinkableInterface)
 		if !ok {
 
@@ -2303,19 +2347,6 @@
 			}
 		}
 
-		// For the dependency from platform to apex, use the latest stubs
-		c.apexSdkVersion = android.FutureApiLevel
-		if !c.IsForPlatform() {
-			c.apexSdkVersion = c.ApexProperties.Info.MinSdkVersion
-		}
-
-		if android.InList("hwaddress", ctx.Config().SanitizeDevice()) {
-			// In hwasan build, we override apexSdkVersion to the FutureApiLevel(10000)
-			// so that even Q(29/Android10) apexes could use the dynamic unwinder by linking the newer stubs(e.g libc(R+)).
-			// (b/144430859)
-			c.apexSdkVersion = android.FutureApiLevel
-		}
-
 		if depTag == staticUnwinderDepTag {
 			// Use static unwinder for legacy (min_sdk_version = 29) apexes (b/144430859)
 			if c.apexSdkVersion <= android.SdkVersion_Android10 {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 041c4a3..38a5c2d 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -612,7 +612,6 @@
 	}
 
 	outputPath := outputFiles[0].String()
-	testBinaryPath := testBinary.dataPaths()[0]
 
 	if !strings.HasSuffix(outputPath, "/main_test") {
 		t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
@@ -620,7 +619,7 @@
 	entries := android.AndroidMkEntriesForTest(t, config, "", module)[0]
 	if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
 		t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
-			" but was '%s'", testBinaryPath)
+			" but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
 	}
 }
 
@@ -2967,6 +2966,52 @@
 	}
 }
 
+func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) {
+	bp := `
+		cc_prebuilt_test_library_shared {
+			name: "test_lib",
+			relative_install_path: "foo/bar/baz",
+			srcs: ["srcpath/dontusethispath/baz.so"],
+		}
+
+		cc_test {
+			name: "main_test",
+			data_libs: ["test_lib"],
+			gtest: false,
+		}
+ `
+
+	config := TestConfig(buildDir, android.Android, nil, bp, nil)
+	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
+
+	ctx := testCcWithConfig(t, config)
+	module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
+	testBinary := module.(*Module).linker.(*testBinary)
+	outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
+	if err != nil {
+		t.Fatalf("Expected cc_test to produce output files, error: %s", err)
+	}
+	if len(outputFiles) != 1 {
+		t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
+	}
+	if len(testBinary.dataPaths()) != 1 {
+		t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths())
+	}
+
+	outputPath := outputFiles[0].String()
+
+	if !strings.HasSuffix(outputPath, "/main_test") {
+		t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
+	}
+	entries := android.AndroidMkEntriesForTest(t, config, "", module)[0]
+	if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
+		t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
+			" but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
+	}
+}
+
 func TestVersionedStubs(t *testing.T) {
 	ctx := testCc(t, `
 		cc_library_shared {
diff --git a/cc/compiler.go b/cc/compiler.go
index d5ea2c3..ba14dd5 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -251,6 +251,14 @@
 		deps.StaticLibs = append(deps.StaticLibs, "libomp")
 	}
 
+	if compiler.hasSrcExt(".y") || compiler.hasSrcExt(".yy") {
+		deps.Tools = append(deps.Tools, "bison", "m4")
+	}
+
+	if compiler.hasSrcExt(".l") || compiler.hasSrcExt(".ll") {
+		deps.Tools = append(deps.Tools, "flex", "m4")
+	}
+
 	return deps
 }
 
@@ -581,7 +589,7 @@
 
 	srcs := append(android.Paths(nil), compiler.srcsBeforeGen...)
 
-	srcs, genDeps := genSources(ctx, srcs, buildFlags)
+	srcs, genDeps := genSources(ctx, srcs, buildFlags, deps.Tools)
 	pathDeps = append(pathDeps, genDeps...)
 
 	compiler.pathDeps = pathDeps
diff --git a/cc/gen.go b/cc/gen.go
index b0aadc6..6f9036b 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -24,7 +24,6 @@
 )
 
 func init() {
-	pctx.SourcePathVariable("lexCmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/flex")
 	pctx.SourcePathVariable("m4Cmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/m4")
 
 	pctx.HostBinToolVariable("aidlCmd", "aidl-cpp")
@@ -32,12 +31,6 @@
 }
 
 var (
-	lex = pctx.AndroidStaticRule("lex",
-		blueprint.RuleParams{
-			Command:     "M4=$m4Cmd $lexCmd -o$out $in",
-			CommandDeps: []string{"$lexCmd", "$m4Cmd"},
-		})
-
 	sysprop = pctx.AndroidStaticRule("sysprop",
 		blueprint.RuleParams{
 			Command: "$syspropCmd --header-dir=$headerOutDir --public-header-dir=$publicOutDir " +
@@ -66,7 +59,8 @@
 }
 
 func genYacc(ctx android.ModuleContext, rule *android.RuleBuilder, yaccFile android.Path,
-	outFile android.ModuleGenPath, props *YaccProperties) (headerFiles android.Paths) {
+	outFile android.ModuleGenPath, props *YaccProperties,
+	tools map[string]android.Path) (headerFiles android.Paths) {
 
 	outDir := android.PathForModuleGen(ctx, "yacc")
 	headerFile := android.GenPathWithExt(ctx, "yacc", yaccFile, "h")
@@ -97,9 +91,17 @@
 		}
 	}
 
-	cmd.Text("BISON_PKGDATADIR=prebuilts/build-tools/common/bison").
-		FlagWithInput("M4=", ctx.Config().PrebuiltBuildTool(ctx, "m4")).
-		PrebuiltBuildTool(ctx, "bison").
+	bison, ok := tools["bison"]
+	if !ok {
+		ctx.ModuleErrorf("Unable to find bison")
+	}
+	m4, ok := tools["m4"]
+	if !ok {
+		ctx.ModuleErrorf("Unable to find m4")
+	}
+
+	cmd.FlagWithInput("M4=", m4).
+		Tool(bison).
 		Flag("-d").
 		Flags(flags).
 		FlagWithOutput("--defines=", headerFile).
@@ -153,13 +155,23 @@
 	}
 }
 
-func genLex(ctx android.ModuleContext, lexFile android.Path, outFile android.ModuleGenPath) {
-	ctx.Build(pctx, android.BuildParams{
-		Rule:        lex,
-		Description: "lex " + lexFile.Rel(),
-		Output:      outFile,
-		Input:       lexFile,
-	})
+func genLex(ctx android.ModuleContext, rule *android.RuleBuilder, lexFile android.Path,
+	outFile android.ModuleGenPath, tools map[string]android.Path) {
+
+	flex, ok := tools["flex"]
+	if !ok {
+		ctx.ModuleErrorf("Unable to find flex")
+	}
+	m4, ok := tools["m4"]
+	if !ok {
+		ctx.ModuleErrorf("Unable to find m4")
+	}
+
+	rule.Command().
+		FlagWithInput("M4=", m4).
+		Tool(flex).
+		FlagWithOutput("-o", outFile).
+		Input(lexFile)
 }
 
 func genSysprop(ctx android.ModuleContext, syspropFile android.Path) (android.Path, android.Paths) {
@@ -206,14 +218,22 @@
 	return rcFile, headerFile
 }
 
-func genSources(ctx android.ModuleContext, srcFiles android.Paths,
-	buildFlags builderFlags) (android.Paths, android.Paths) {
+func genSources(ctx android.ModuleContext, srcFiles android.Paths, buildFlags builderFlags,
+	tools map[string]android.Path) (android.Paths, android.Paths) {
 
 	var deps android.Paths
 	var rsFiles android.Paths
 
 	var aidlRule *android.RuleBuilder
 
+	var lexRule_ *android.RuleBuilder
+	lexRule := func() *android.RuleBuilder {
+		if lexRule_ == nil {
+			lexRule_ = android.NewRuleBuilder().Sbox(android.PathForModuleGen(ctx, "lex"))
+		}
+		return lexRule_
+	}
+
 	var yaccRule_ *android.RuleBuilder
 	yaccRule := func() *android.RuleBuilder {
 		if yaccRule_ == nil {
@@ -227,19 +247,19 @@
 		case ".y":
 			cFile := android.GenPathWithExt(ctx, "yacc", srcFile, "c")
 			srcFiles[i] = cFile
-			deps = append(deps, genYacc(ctx, yaccRule(), srcFile, cFile, buildFlags.yacc)...)
+			deps = append(deps, genYacc(ctx, yaccRule(), srcFile, cFile, buildFlags.yacc, tools)...)
 		case ".yy":
 			cppFile := android.GenPathWithExt(ctx, "yacc", srcFile, "cpp")
 			srcFiles[i] = cppFile
-			deps = append(deps, genYacc(ctx, yaccRule(), srcFile, cppFile, buildFlags.yacc)...)
+			deps = append(deps, genYacc(ctx, yaccRule(), srcFile, cppFile, buildFlags.yacc, tools)...)
 		case ".l":
 			cFile := android.GenPathWithExt(ctx, "lex", srcFile, "c")
 			srcFiles[i] = cFile
-			genLex(ctx, srcFile, cFile)
+			genLex(ctx, lexRule(), srcFile, cFile, tools)
 		case ".ll":
 			cppFile := android.GenPathWithExt(ctx, "lex", srcFile, "cpp")
 			srcFiles[i] = cppFile
-			genLex(ctx, srcFile, cppFile)
+			genLex(ctx, lexRule(), srcFile, cppFile, tools)
 		case ".proto":
 			ccFile, headerFile := genProto(ctx, srcFile, buildFlags)
 			srcFiles[i] = ccFile
@@ -271,6 +291,10 @@
 		aidlRule.Build(pctx, ctx, "aidl", "gen aidl")
 	}
 
+	if lexRule_ != nil {
+		lexRule_.Build(pctx, ctx, "lex", "gen lex")
+	}
+
 	if yaccRule_ != nil {
 		yaccRule_.Build(pctx, ctx, "yacc", "gen yacc")
 	}
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 0751f1c..653b43e 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -26,6 +26,7 @@
 	ctx.RegisterModuleType("cc_prebuilt_library", PrebuiltLibraryFactory)
 	ctx.RegisterModuleType("cc_prebuilt_library_shared", PrebuiltSharedLibraryFactory)
 	ctx.RegisterModuleType("cc_prebuilt_library_static", PrebuiltStaticLibraryFactory)
+	ctx.RegisterModuleType("cc_prebuilt_test_library_shared", PrebuiltSharedTestLibraryFactory)
 	ctx.RegisterModuleType("cc_prebuilt_object", prebuiltObjectFactory)
 	ctx.RegisterModuleType("cc_prebuilt_binary", prebuiltBinaryFactory)
 }
@@ -243,6 +244,16 @@
 	return module.Init()
 }
 
+// cc_prebuilt_test_library_shared installs a precompiled shared library
+// to be used as a data dependency of a test-related module (such as cc_test, or
+// cc_test_library).
+func PrebuiltSharedTestLibraryFactory() android.Module {
+	module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported)
+	library.BuildOnlyShared()
+	library.baseInstaller = NewTestInstaller()
+	return module.Init()
+}
+
 func NewPrebuiltSharedLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
 	module, library := NewPrebuiltLibrary(hod)
 	library.BuildOnlyShared()
diff --git a/java/Android.bp b/java/Android.bp
index 1fda7f7..fd06c46 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -38,6 +38,7 @@
         "java_resources.go",
         "kotlin.go",
         "lint.go",
+        "legacy_core_platform_api_usage.go",
         "platform_compat_config.go",
         "plugin.go",
         "prebuilt_apis.go",
diff --git a/java/androidmk.go b/java/androidmk.go
index 03994bf..25dd329 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -132,9 +132,7 @@
 					}
 					entries.SetString("LOCAL_MODULE_STEM", library.Stem())
 
-					entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveHTMLZip)
-					entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveTextZip)
-					entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveXMLZip)
+					entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", library.linter.reports)
 				},
 			},
 		}
@@ -394,9 +392,7 @@
 					entries.AddStrings("LOCAL_SOONG_BUILT_INSTALLED", extra.String()+":"+install)
 				}
 
-				entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveHTMLZip)
-				entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveTextZip)
-				entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveXMLZip)
+				entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", app.linter.reports)
 			},
 		},
 		ExtraFooters: []android.AndroidMkExtraFootersFunc{
diff --git a/java/config/config.go b/java/config/config.go
index 0fe74c8..d2f4513 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -30,6 +30,8 @@
 
 	LegacyCorePlatformBootclasspathLibraries = []string{"legacy.core.platform.api.stubs", "core-lambda-stubs"}
 	LegacyCorePlatformSystemModules          = "legacy-core-platform-api-stubs-system-modules"
+	StableCorePlatformBootclasspathLibraries = []string{"stable.core.platform.api.stubs", "core-lambda-stubs"}
+	StableCorePlatformSystemModules          = "stable-core-platform-api-stubs-system-modules"
 	FrameworkLibraries                       = []string{"ext", "framework"}
 	DefaultLambdaStubsLibrary                = "core-lambda-stubs"
 	SdkLambdaStubsPath                       = "prebuilts/sdk/tools/core-lambda-stubs.jar"
diff --git a/java/java.go b/java/java.go
index 367b09c..ef9613d 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1707,6 +1707,9 @@
 		j.linter.compileSdkVersion = lintSDKVersionString(j.sdkVersion())
 		j.linter.javaLanguageLevel = flags.javaVersion.String()
 		j.linter.kotlinLanguageLevel = "1.3"
+		if j.ApexName() != "" && ctx.Config().UnbundledBuildApps() {
+			j.linter.buildModuleReportZip = true
+		}
 		j.linter.lint(ctx)
 	}
 
@@ -2789,6 +2792,10 @@
 	return nil
 }
 
+func (a *DexImport) LintDepSets() LintDepSets {
+	return LintDepSets{}
+}
+
 func (j *DexImport) IsInstallable() bool {
 	return true
 }
diff --git a/java/legacy_core_platform_api_usage.go b/java/legacy_core_platform_api_usage.go
new file mode 100644
index 0000000..8af66d0
--- /dev/null
+++ b/java/legacy_core_platform_api_usage.go
@@ -0,0 +1,162 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+	"android/soong/android"
+	"android/soong/java/config"
+)
+
+var legacyCorePlatformApiModules = []string{
+	"ahat-test-dump",
+	"android.car",
+	"android.test.mock",
+	"android.test.mock.impl",
+	"AoapTestDeviceApp",
+	"AoapTestHostApp",
+	"api-stubs-docs",
+	"art_cts_jvmti_test_library",
+	"art-gtest-jars-MyClassNatives",
+	"BackupFrameworksServicesRoboTests",
+	"BandwidthEnforcementTest",
+	"BlockedNumberProvider",
+	"BluetoothInstrumentationTests",
+	"BluetoothMidiService",
+	"car-apps-common",
+	"CertInstaller",
+	"ConnectivityManagerTest",
+	"ContactsProvider",
+	"core-tests-support",
+	"CtsContentTestCases",
+	"CtsIkeTestCases",
+	"CtsLibcoreWycheproofBCTestCases",
+	"CtsMediaTestCases",
+	"CtsNetTestCases",
+	"CtsNetTestCasesLatestSdk",
+	"CtsSecurityTestCases",
+	"CtsUsageStatsTestCases",
+	"DisplayCutoutEmulationEmu01Overlay",
+	"DocumentsUIPerfTests",
+	"DocumentsUITests",
+	"DownloadProvider",
+	"DownloadProviderTests",
+	"DownloadProviderUi",
+	"DynamicSystemInstallationService",
+	"EmergencyInfo-lib",
+	"ethernet-service",
+	"EthernetServiceTests",
+	"ExternalStorageProvider",
+	"ExtServices",
+	"ExtServices-core",
+	"framework-all",
+	"framework-minus-apex",
+	"FrameworksCoreTests",
+	"FrameworksIkeTests",
+	"FrameworksNetCommonTests",
+	"FrameworksNetTests",
+	"FrameworksServicesRoboTests",
+	"FrameworksServicesTests",
+	"FrameworksUtilTests",
+	"hid",
+	"hidl_test_java_java",
+	"hwbinder",
+	"ims",
+	"KeyChain",
+	"ksoap2",
+	"LocalTransport",
+	"lockagent",
+	"mediaframeworktest",
+	"MediaProvider",
+	"MmsService",
+	"MtpDocumentsProvider",
+	"MultiDisplayProvider",
+	"NetworkStackIntegrationTestsLib",
+	"NetworkStackNextIntegrationTests",
+	"NetworkStackNextTests",
+	"NetworkStackTests",
+	"NetworkStackTestsLib",
+	"NfcNci",
+	"platform_library-docs",
+	"PrintSpooler",
+	"RollbackTest",
+	"services",
+	"services.accessibility",
+	"services.backup",
+	"services.core.unboosted",
+	"services.devicepolicy",
+	"services.print",
+	"services.usage",
+	"services.usb",
+	"Settings-core",
+	"SettingsLib",
+	"SettingsProvider",
+	"SettingsProviderTest",
+	"SettingsRoboTests",
+	"Shell",
+	"ShellTests",
+	"sl4a.Common",
+	"StatementService",
+	"SystemUI-core",
+	"SystemUISharedLib",
+	"SystemUI-tests",
+	"Telecom",
+	"TelecomUnitTests",
+	"telephony-common",
+	"TelephonyProvider",
+	"TelephonyProviderTests",
+	"TeleService",
+	"testables",
+	"TetheringTests",
+	"TetheringTestsLib",
+	"time_zone_distro_installer",
+	"time_zone_distro_installer-tests",
+	"time_zone_distro-tests",
+	"time_zone_updater",
+	"TvProvider",
+	"uiautomator-stubs-docs",
+	"UsbHostExternalManagementTestApp",
+	"UserDictionaryProvider",
+	"WallpaperBackup",
+	"wifi-service",
+}
+
+var legacyCorePlatformApiLookup = make(map[string]struct{})
+
+func init() {
+	for _, module := range legacyCorePlatformApiModules {
+		legacyCorePlatformApiLookup[module] = struct{}{}
+	}
+}
+
+func useLegacyCorePlatformApi(ctx android.EarlyModuleContext) bool {
+	_, found := legacyCorePlatformApiLookup[ctx.ModuleName()]
+	return found
+}
+
+func corePlatformSystemModules(ctx android.EarlyModuleContext) string {
+	if useLegacyCorePlatformApi(ctx) {
+		return config.LegacyCorePlatformSystemModules
+	} else {
+		return config.StableCorePlatformSystemModules
+	}
+}
+
+func corePlatformBootclasspathLibraries(ctx android.EarlyModuleContext) []string {
+	if useLegacyCorePlatformApi(ctx) {
+		return config.LegacyCorePlatformBootclasspathLibraries
+	} else {
+		return config.StableCorePlatformBootclasspathLibraries
+	}
+}
diff --git a/java/lint.go b/java/lint.go
index 5d2c4f6..6391067 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -69,28 +69,78 @@
 	outputs             lintOutputs
 	properties          LintProperties
 
+	reports android.Paths
+
 	buildModuleReportZip bool
 }
 
 type lintOutputs struct {
-	html android.ModuleOutPath
-	text android.ModuleOutPath
-	xml  android.ModuleOutPath
+	html android.Path
+	text android.Path
+	xml  android.Path
 
-	transitiveHTML *android.DepSet
-	transitiveText *android.DepSet
-	transitiveXML  *android.DepSet
-
-	transitiveHTMLZip android.OptionalPath
-	transitiveTextZip android.OptionalPath
-	transitiveXMLZip  android.OptionalPath
+	depSets LintDepSets
 }
 
-type lintOutputIntf interface {
+type lintOutputsIntf interface {
 	lintOutputs() *lintOutputs
 }
 
-var _ lintOutputIntf = (*linter)(nil)
+type lintDepSetsIntf interface {
+	LintDepSets() LintDepSets
+}
+
+type LintDepSets struct {
+	HTML, Text, XML *android.DepSet
+}
+
+type LintDepSetsBuilder struct {
+	HTML, Text, XML *android.DepSetBuilder
+}
+
+func NewLintDepSetBuilder() LintDepSetsBuilder {
+	return LintDepSetsBuilder{
+		HTML: android.NewDepSetBuilder(android.POSTORDER),
+		Text: android.NewDepSetBuilder(android.POSTORDER),
+		XML:  android.NewDepSetBuilder(android.POSTORDER),
+	}
+}
+
+func (l LintDepSetsBuilder) Direct(html, text, xml android.Path) LintDepSetsBuilder {
+	l.HTML.Direct(html)
+	l.Text.Direct(text)
+	l.XML.Direct(xml)
+	return l
+}
+
+func (l LintDepSetsBuilder) Transitive(depSets LintDepSets) LintDepSetsBuilder {
+	if depSets.HTML != nil {
+		l.HTML.Transitive(depSets.HTML)
+	}
+	if depSets.Text != nil {
+		l.Text.Transitive(depSets.Text)
+	}
+	if depSets.XML != nil {
+		l.XML.Transitive(depSets.XML)
+	}
+	return l
+}
+
+func (l LintDepSetsBuilder) Build() LintDepSets {
+	return LintDepSets{
+		HTML: l.HTML.Build(),
+		Text: l.Text.Build(),
+		XML:  l.XML.Build(),
+	}
+}
+
+func (l *linter) LintDepSets() LintDepSets {
+	return l.outputs.depSets
+}
+
+var _ lintDepSetsIntf = (*linter)(nil)
+
+var _ lintOutputsIntf = (*linter)(nil)
 
 func (l *linter) lintOutputs() *lintOutputs {
 	return &l.outputs
@@ -247,16 +297,11 @@
 	text := android.PathForModuleOut(ctx, "lint-report.txt")
 	xml := android.PathForModuleOut(ctx, "lint-report.xml")
 
-	htmlDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(html)
-	textDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(text)
-	xmlDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(xml)
+	depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml)
 
 	ctx.VisitDirectDepsWithTag(staticLibTag, func(dep android.Module) {
-		if depLint, ok := dep.(lintOutputIntf); ok {
-			depLintOutputs := depLint.lintOutputs()
-			htmlDeps.Transitive(depLintOutputs.transitiveHTML)
-			textDeps.Transitive(depLintOutputs.transitiveText)
-			xmlDeps.Transitive(depLintOutputs.transitiveXML)
+		if depLint, ok := dep.(lintDepSetsIntf); ok {
+			depSetsBuilder.Transitive(depLint.LintDepSets())
 		}
 	})
 
@@ -309,26 +354,35 @@
 		text: text,
 		xml:  xml,
 
-		transitiveHTML: htmlDeps.Build(),
-		transitiveText: textDeps.Build(),
-		transitiveXML:  xmlDeps.Build(),
+		depSets: depSetsBuilder.Build(),
 	}
 
 	if l.buildModuleReportZip {
-		htmlZip := android.PathForModuleOut(ctx, "lint-report-html.zip")
-		l.outputs.transitiveHTMLZip = android.OptionalPathForPath(htmlZip)
-		lintZip(ctx, l.outputs.transitiveHTML.ToSortedList(), htmlZip)
-
-		textZip := android.PathForModuleOut(ctx, "lint-report-text.zip")
-		l.outputs.transitiveTextZip = android.OptionalPathForPath(textZip)
-		lintZip(ctx, l.outputs.transitiveText.ToSortedList(), textZip)
-
-		xmlZip := android.PathForModuleOut(ctx, "lint-report-xml.zip")
-		l.outputs.transitiveXMLZip = android.OptionalPathForPath(xmlZip)
-		lintZip(ctx, l.outputs.transitiveXML.ToSortedList(), xmlZip)
+		l.reports = BuildModuleLintReportZips(ctx, l.LintDepSets())
 	}
 }
 
+func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets) android.Paths {
+	htmlList := depSets.HTML.ToSortedList()
+	textList := depSets.Text.ToSortedList()
+	xmlList := depSets.XML.ToSortedList()
+
+	if len(htmlList) == 0 && len(textList) == 0 && len(xmlList) == 0 {
+		return nil
+	}
+
+	htmlZip := android.PathForModuleOut(ctx, "lint-report-html.zip")
+	lintZip(ctx, htmlList, htmlZip)
+
+	textZip := android.PathForModuleOut(ctx, "lint-report-text.zip")
+	lintZip(ctx, textList, textZip)
+
+	xmlZip := android.PathForModuleOut(ctx, "lint-report-xml.zip")
+	lintZip(ctx, xmlList, xmlZip)
+
+	return android.Paths{htmlZip, textZip, xmlZip}
+}
+
 type lintSingleton struct {
 	htmlZip android.WritablePath
 	textZip android.WritablePath
@@ -403,7 +457,7 @@
 			return
 		}
 
-		if l, ok := m.(lintOutputIntf); ok {
+		if l, ok := m.(lintOutputsIntf); ok {
 			outputs = append(outputs, l.lintOutputs())
 		}
 	})
@@ -414,7 +468,9 @@
 		var paths android.Paths
 
 		for _, output := range outputs {
-			paths = append(paths, get(output))
+			if p := get(output); p != nil {
+				paths = append(paths, p)
+			}
 		}
 
 		lintZip(ctx, paths, outputPath)
diff --git a/java/sdk.go b/java/sdk.go
index 6564f6d..6e67a13 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -413,8 +413,8 @@
 	case sdkPrivate:
 		return sdkDep{
 			useModule:          true,
-			systemModules:      config.LegacyCorePlatformSystemModules,
-			bootclasspath:      config.LegacyCorePlatformBootclasspathLibraries,
+			systemModules:      corePlatformSystemModules(ctx),
+			bootclasspath:      corePlatformBootclasspathLibraries(ctx),
 			classpath:          config.FrameworkLibraries,
 			frameworkResModule: "framework-res",
 		}
@@ -438,8 +438,8 @@
 	case sdkCorePlatform:
 		return sdkDep{
 			useModule:        true,
-			systemModules:    config.LegacyCorePlatformSystemModules,
-			bootclasspath:    config.LegacyCorePlatformBootclasspathLibraries,
+			systemModules:    corePlatformSystemModules(ctx),
+			bootclasspath:    corePlatformBootclasspathLibraries(ctx),
 			noFrameworksLibs: true,
 		}
 	case sdkPublic:
diff --git a/java/sdk_library.go b/java/sdk_library.go
index e3ba2c7..8a8d0c9 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1996,6 +1996,15 @@
 }
 
 // to satisfy apex.javaDependency interface
+func (module *SdkLibraryImport) LintDepSets() LintDepSets {
+	if module.implLibraryModule == nil {
+		return LintDepSets{}
+	} else {
+		return module.implLibraryModule.LintDepSets()
+	}
+}
+
+// to satisfy apex.javaDependency interface
 func (module *SdkLibraryImport) Stem() string {
 	return module.BaseModuleName()
 }
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 1f23b14..395da79 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -49,8 +49,8 @@
 	}{
 		{
 			name:           "default",
-			bootclasspath:  config.LegacyCorePlatformBootclasspathLibraries,
-			system:         config.LegacyCorePlatformSystemModules,
+			bootclasspath:  config.StableCorePlatformBootclasspathLibraries,
+			system:         config.StableCorePlatformSystemModules,
 			java8classpath: config.FrameworkLibraries,
 			java9classpath: config.FrameworkLibraries,
 			aidl:           "-Iframework/aidl",
@@ -58,16 +58,16 @@
 		{
 			name:           `sdk_version:"core_platform"`,
 			properties:     `sdk_version:"core_platform"`,
-			bootclasspath:  config.LegacyCorePlatformBootclasspathLibraries,
-			system:         config.LegacyCorePlatformSystemModules,
+			bootclasspath:  config.StableCorePlatformBootclasspathLibraries,
+			system:         config.StableCorePlatformSystemModules,
 			java8classpath: []string{},
 			aidl:           "",
 		},
 		{
 			name:           "blank sdk version",
 			properties:     `sdk_version: "",`,
-			bootclasspath:  config.LegacyCorePlatformBootclasspathLibraries,
-			system:         config.LegacyCorePlatformSystemModules,
+			bootclasspath:  config.StableCorePlatformBootclasspathLibraries,
+			system:         config.StableCorePlatformSystemModules,
 			java8classpath: config.FrameworkLibraries,
 			java9classpath: config.FrameworkLibraries,
 			aidl:           "-Iframework/aidl",
@@ -155,9 +155,9 @@
 		{
 
 			name:           "nostdlib system_modules",
-			properties:     `sdk_version: "none", system_modules: "legacy-core-platform-api-stubs-system-modules"`,
-			system:         "legacy-core-platform-api-stubs-system-modules",
-			bootclasspath:  []string{"legacy-core-platform-api-stubs-system-modules-lib"},
+			properties:     `sdk_version: "none", system_modules: "stable-core-platform-api-stubs-system-modules"`,
+			system:         "stable-core-platform-api-stubs-system-modules",
+			bootclasspath:  []string{"stable-core-platform-api-stubs-system-modules-lib"},
 			java8classpath: []string{},
 		},
 		{
diff --git a/java/testing.go b/java/testing.go
index 94f054e..e761743 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -136,7 +136,7 @@
 				name: "%s",
 				srcs: ["a.java"],
 				sdk_version: "none",
-				system_modules: "legacy-core-platform-api-stubs-system-modules",
+				system_modules: "stable-core-platform-api-stubs-system-modules",
 			}
 		`, extra)
 	}
@@ -146,7 +146,7 @@
 			name: "framework",
 			srcs: ["a.java"],
 			sdk_version: "none",
-			system_modules: "legacy-core-platform-api-stubs-system-modules",
+			system_modules: "stable-core-platform-api-stubs-system-modules",
 			aidl: {
 				export_include_dirs: ["framework/aidl"],
 			},
@@ -161,7 +161,7 @@
 			name: "android.hidl.base-V1.0-java",
 			srcs: ["a.java"],
 			sdk_version: "none",
-			system_modules: "legacy-core-platform-api-stubs-system-modules",
+			system_modules: "stable-core-platform-api-stubs-system-modules",
 			installable: true,
 		}
 
@@ -169,7 +169,7 @@
 			name: "android.hidl.manager-V1.0-java",
 			srcs: ["a.java"],
 			sdk_version: "none",
-			system_modules: "legacy-core-platform-api-stubs-system-modules",
+			system_modules: "stable-core-platform-api-stubs-system-modules",
 			installable: true,
 		}
 
@@ -177,7 +177,7 @@
 			name: "org.apache.http.legacy",
 			srcs: ["a.java"],
 			sdk_version: "none",
-			system_modules: "legacy-core-platform-api-stubs-system-modules",
+			system_modules: "stable-core-platform-api-stubs-system-modules",
 			installable: true,
 		}
 
@@ -185,7 +185,7 @@
 			name: "android.test.base",
 			srcs: ["a.java"],
 			sdk_version: "none",
-			system_modules: "legacy-core-platform-api-stubs-system-modules",
+			system_modules: "stable-core-platform-api-stubs-system-modules",
 			installable: true,
 		}
   
@@ -193,7 +193,7 @@
 			name: "android.test.mock",
 			srcs: ["a.java"],
 			sdk_version: "none",
-			system_modules: "legacy-core-platform-api-stubs-system-modules",
+			system_modules: "stable-core-platform-api-stubs-system-modules",
 			installable: true,
 		}
 	`
diff --git a/rust/Android.bp b/rust/Android.bp
index 26a5a08..e03bf4f 100644
--- a/rust/Android.bp
+++ b/rust/Android.bp
@@ -27,6 +27,7 @@
     testSrcs: [
         "binary_test.go",
         "bindgen_test.go",
+        "builder_test.go",
         "clippy_test.go",
         "compiler_test.go",
         "coverage_test.go",
diff --git a/rust/bindgen.go b/rust/bindgen.go
index d377dad..83ad560 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -24,7 +24,7 @@
 )
 
 var (
-	defaultBindgenFlags = []string{"--no-rustfmt-bindings"}
+	defaultBindgenFlags = []string{""}
 
 	// bindgen should specify its own Clang revision so updating Clang isn't potentially blocked on bindgen failures.
 	bindgenClangVersion  = "clang-r383902c"
@@ -40,7 +40,8 @@
 	//TODO(ivanlozano) Switch this to RuleBuilder
 	bindgen = pctx.AndroidStaticRule("bindgen",
 		blueprint.RuleParams{
-			Command:     "CLANG_PATH=$bindgenClang LIBCLANG_PATH=$bindgenLibClang $bindgenCmd $flags $in -o $out -- $cflags",
+			Command: "CLANG_PATH=$bindgenClang LIBCLANG_PATH=$bindgenLibClang RUSTFMT=${config.RustBin}/rustfmt " +
+				"$bindgenCmd $flags $in -o $out -- $cflags",
 			CommandDeps: []string{"$bindgenCmd"},
 		},
 		"flags", "cflags")
@@ -148,6 +149,9 @@
 		&b.Properties)
 }
 
+// rust_bindgen generates Rust FFI bindings to C libraries using bindgen given a wrapper header as the primary input.
+// Bindgen has a number of flags to control the generated source, and additional flags can be passed to clang to ensure
+// the header and generated source is appropriately handled.
 func RustBindgenFactory() android.Module {
 	module, _ := NewRustBindgen(android.HostAndDeviceSupported)
 	return module.Init()
diff --git a/rust/builder.go b/rust/builder.go
index 8b5a2bb..45cd268 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -200,15 +200,16 @@
 	}
 
 	if len(deps.SrcDeps) > 0 {
-		moduleGenDir := android.PathForModuleOut(ctx, "out/")
+		genSubDir := "out/"
+		moduleGenDir := android.PathForModuleOut(ctx, genSubDir)
 		var outputs android.WritablePaths
 
 		for _, genSrc := range deps.SrcDeps {
-			if android.SuffixInList(outputs.Strings(), "out/"+genSrc.Base()) {
+			if android.SuffixInList(outputs.Strings(), genSubDir+genSrc.Base()) {
 				ctx.PropertyErrorf("srcs",
 					"multiple source providers generate the same filename output: "+genSrc.Base())
 			}
-			outputs = append(outputs, android.PathForModuleOut(ctx, "out/"+genSrc.Base()))
+			outputs = append(outputs, android.PathForModuleOut(ctx, genSubDir+genSrc.Base()))
 		}
 
 		ctx.Build(pctx, android.BuildParams{
diff --git a/rust/builder_test.go b/rust/builder_test.go
new file mode 100644
index 0000000..04b67d9
--- /dev/null
+++ b/rust/builder_test.go
@@ -0,0 +1,40 @@
+// Copyright 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package rust
+
+import "testing"
+
+func TestSourceProviderCollision(t *testing.T) {
+	testRustError(t, "multiple source providers generate the same filename output: bindings.rs", `
+		rust_binary {
+			name: "source_collider",
+			srcs: [
+				"foo.rs",
+				":libbindings1",
+				":libbindings2",
+			],
+		}
+		rust_bindgen {
+			name: "libbindings1",
+			stem: "bindings",
+			wrapper_src: "src/any.h",
+		}
+		rust_bindgen {
+			name: "libbindings2",
+			stem: "bindings",
+			wrapper_src: "src/any.h",
+		}
+	`)
+}
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 6fefc28..a2198e9 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -51,10 +51,10 @@
 	name: "core-current-stubs-system-modules",
 }
 java_system_modules_import {
-	name: "legacy-core-platform-api-stubs-system-modules",
+	name: "stable-core-platform-api-stubs-system-modules",
 }
 java_import {
-	name: "legacy.core.platform.api.stubs",
+	name: "stable.core.platform.api.stubs",
 }
 java_import {
 	name: "android_stubs_current",