Merge "Mixed bazel/soong build prototype for genrule"
diff --git a/OWNERS b/OWNERS
index 8355d10..3a5a8a7 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,13 +1,20 @@
-per-file * = asmundak@google.com
-per-file * = ccross@android.com
-per-file * = dwillemsen@google.com
-per-file * = eakammer@google.com
-per-file * = jungjw@google.com
-per-file * = patricearruda@google.com
-per-file * = paulduffin@google.com
+# This file is included by several other projects as the list of people
+# approving build related projects.
 
-per-file ndk_*.go = danalbert@google.com
-per-file clang.go,global.go = srhines@google.com, chh@google.com, pirama@google.com, yikong@google.com
-per-file tidy.go = srhines@google.com, chh@google.com
-per-file lto.go,pgo.go = srhines@google.com, pirama@google.com, yikong@google.com
-per-file docs/map_files.md = danalbert@google.com, enh@google.com, jiyong@google.com
+ahumesky@google.com
+asmundak@google.com
+ccross@android.com
+cparsons@google.com
+dwillemsen@google.com
+eakammer@google.com
+jingwen@google.com
+joeo@google.com
+jungjw@google.com
+lberki@google.com
+patricearruda@google.com
+ruperts@google.com
+
+# To expedite LON reviews
+hansson@google.com
+paulduffin@google.com
+
diff --git a/android/Android.bp b/android/Android.bp
index 7aa228e..a89169e 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -64,6 +64,7 @@
     testSrcs: [
         "android_test.go",
         "androidmk_test.go",
+        "apex_test.go",
         "arch_test.go",
         "config_test.go",
         "csuite_config_test.go",
diff --git a/android/androidmk.go b/android/androidmk.go
index e90e5f0..ddd51ff 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -639,3 +639,21 @@
 		// Make does not understand LinuxBionic
 		module.Os() == LinuxBionic
 }
+
+func AndroidMkDataPaths(data []DataPath) []string {
+	var testFiles []string
+	for _, d := range data {
+		rel := d.SrcPath.Rel()
+		path := d.SrcPath.String()
+		if !strings.HasSuffix(path, rel) {
+			panic(fmt.Errorf("path %q does not end with %q", path, rel))
+		}
+		path = strings.TrimSuffix(path, rel)
+		testFileString := path + ":" + rel
+		if len(d.RelativeInstallPath) > 0 {
+			testFileString += ":" + d.RelativeInstallPath
+		}
+		testFiles = append(testFiles, testFileString)
+	}
+	return testFiles
+}
diff --git a/android/androidmk_test.go b/android/androidmk_test.go
index a558f45..8574dc9 100644
--- a/android/androidmk_test.go
+++ b/android/androidmk_test.go
@@ -68,6 +68,7 @@
 }
 
 func TestAndroidMkSingleton_PassesUpdatedAndroidMkDataToCustomCallback(t *testing.T) {
+	t.Parallel()
 	bp := `
 	custom {
 		name: "foo",
@@ -103,6 +104,7 @@
 }
 
 func TestGetDistForGoals(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		bp                     string
 		expectedAndroidMkLines []string
diff --git a/android/apex.go b/android/apex.go
index 7ae46d4..c01b716 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -28,21 +28,30 @@
 	SdkVersion_Android10 = uncheckedFinalApiLevel(29)
 )
 
+// ApexInfo describes the metadata common to all modules in an apexBundle.
 type ApexInfo struct {
-	// Name of the apex variation that this module is mutated into
+	// Name of the apex variation that this module is mutated into, or "" for
+	// a platform variant.  Note that a module can be included in multiple APEXes,
+	// in which case, the module is mutated into one or more variants, each of
+	// which is for one or more APEXes.
 	ApexVariationName string
 
 	// Serialized ApiLevel. Use via MinSdkVersion() method. Cannot be stored in
 	// its struct form because this is cloned into properties structs, and
 	// ApiLevel has private members.
 	MinSdkVersionStr string
-	Updatable        bool
-	RequiredSdks     SdkRefs
 
-	InApexes []string
+	// True if the module comes from an updatable APEX.
+	Updatable    bool
+	RequiredSdks SdkRefs
+
+	InApexes     []string
+	ApexContents []*ApexContents
 }
 
-func (i ApexInfo) mergedName(ctx EarlyModuleContext) string {
+var ApexInfoProvider = blueprint.NewMutatorProvider(ApexInfo{}, "apex")
+
+func (i ApexInfo) mergedName(ctx PathContext) string {
 	name := "apex" + strconv.Itoa(i.MinSdkVersion(ctx).FinalOrFutureInt())
 	for _, sdk := range i.RequiredSdks {
 		name += "_" + sdk.Name + "_" + sdk.Version
@@ -50,10 +59,22 @@
 	return name
 }
 
-func (this *ApexInfo) MinSdkVersion(ctx EarlyModuleContext) ApiLevel {
+func (this *ApexInfo) MinSdkVersion(ctx PathContext) ApiLevel {
 	return ApiLevelOrPanic(ctx, this.MinSdkVersionStr)
 }
 
+func (i ApexInfo) IsForPlatform() bool {
+	return i.ApexVariationName == ""
+}
+
+// ApexTestForInfo stores the contents of APEXes for which this module is a test and thus has
+// access to APEX internals.
+type ApexTestForInfo struct {
+	ApexContents []*ApexContents
+}
+
+var ApexTestForInfoProvider = blueprint.NewMutatorProvider(ApexTestForInfo{}, "apex_test_for")
+
 // Extracted from ApexModule to make it easier to define custom subsets of the
 // ApexModule interface and improve code navigation within the IDE.
 type DepIsInSameApex interface {
@@ -87,23 +108,18 @@
 	// Call this before apex.apexMutator is run.
 	BuildForApex(apex ApexInfo)
 
-	// Returns the name of APEX variation that this module will be built for.
-	// Empty string is returned when 'IsForPlatform() == true'. Note that a
-	// module can beincluded in multiple APEXes, in which case, the module
-	// is mutated into one or more variants, each of which is for one or
-	// more APEXes.  This method returns the name of the APEX variation of
-	// the module.
+	// Returns true if this module is present in any APEXes
+	// directly or indirectly.
 	// Call this after apex.apexMutator is run.
-	ApexVariationName() string
+	InAnyApex() bool
 
-	// Returns the name of the APEX modules that this variant of this module
-	// is present in.
+	// Returns true if this module is directly in any APEXes.
 	// Call this after apex.apexMutator is run.
-	InApexes() []string
+	DirectlyInAnyApex() bool
 
-	// Tests whether this module will be built for the platform or not.
-	// This is a shortcut for ApexVariationName() == ""
-	IsForPlatform() bool
+	// Returns true if any variant of this module is directly in any APEXes.
+	// Call this after apex.apexMutator is run.
+	AnyVariantDirectlyInAnyApex() bool
 
 	// Tests if this module could have APEX variants. APEX variants are
 	// created only for the modules that returns true here. This is useful
@@ -116,10 +132,6 @@
 	// libs.
 	IsInstallableToApex() bool
 
-	// Mutate this module into one or more variants each of which is built
-	// for an APEX marked via BuildForApex().
-	CreateApexVariations(mctx BottomUpMutatorContext) []Module
-
 	// Tests if this module is available for the specified APEX or ":platform"
 	AvailableFor(what string) bool
 
@@ -138,9 +150,6 @@
 	// it returns 9 as string
 	ChooseSdkVersion(ctx BaseModuleContext, versionList []string, maxSdkVersion ApiLevel) (string, error)
 
-	// Tests if the module comes from an updatable APEX.
-	Updatable() bool
-
 	// List of APEXes that this module tests. The module has access to
 	// the private part of the listed APEXes even when it is not included in the
 	// APEXes.
@@ -153,11 +162,6 @@
 	// Returns true if this module needs a unique variation per apex, for example if
 	// use_apex_name_macro is set.
 	UniqueApexVariations() bool
-
-	// UpdateUniqueApexVariationsForDeps sets UniqueApexVariationsForDeps if any dependencies
-	// that are in the same APEX have unique APEX variations so that the module can link against
-	// the right variant.
-	UpdateUniqueApexVariationsForDeps(mctx BottomUpMutatorContext)
 }
 
 type ApexProperties struct {
@@ -171,7 +175,21 @@
 	// Default is ["//apex_available:platform"].
 	Apex_available []string
 
-	Info ApexInfo `blueprint:"mutated"`
+	// AnyVariantDirectlyInAnyApex is true in the primary variant of a module if _any_ variant
+	// of the module is directly in any apex.  This includes host, arch, asan, etc. variants.
+	// It is unused in any variant that is not the primary variant.
+	// Ideally this wouldn't be used, as it incorrectly mixes arch variants if only one arch
+	// is in an apex, but a few places depend on it, for example when an ASAN variant is
+	// created before the apexMutator.
+	AnyVariantDirectlyInAnyApex bool `blueprint:"mutated"`
+
+	// DirectlyInAnyApex is true if any APEX variant (including the "" variant used for the
+	// platform) of this module is directly in any APEX.
+	DirectlyInAnyApex bool `blueprint:"mutated"`
+
+	// DirectlyInAnyApex is true if any APEX variant (including the "" variant used for the
+	// platform) of this module is directly or indirectly in any APEX.
+	InAnyApex bool `blueprint:"mutated"`
 
 	NotAvailableForPlatform bool `blueprint:"mutated"`
 
@@ -187,6 +205,15 @@
 	ExcludeFromApexContents()
 }
 
+// Marker interface that identifies dependencies that should inherit the DirectlyInAnyApex
+// state from the parent to the child.  For example, stubs libraries are marked as
+// DirectlyInAnyApex if their implementation is in an apex.
+type CopyDirectlyInAnyApexTag interface {
+	blueprint.DependencyTag
+
+	CopyDirectlyInAnyApex()
+}
+
 // Provides default implementation for the ApexModule interface. APEX-aware
 // modules are expected to include this struct and call InitApexModule().
 type ApexModuleBase struct {
@@ -215,43 +242,6 @@
 	return false
 }
 
-func (m *ApexModuleBase) UpdateUniqueApexVariationsForDeps(mctx BottomUpMutatorContext) {
-	// anyInSameApex returns true if the two ApexInfo lists contain any values in an InApexes list
-	// in common.  It is used instead of DepIsInSameApex because it needs to determine if the dep
-	// is in the same APEX due to being directly included, not only if it is included _because_ it
-	// is a dependency.
-	anyInSameApex := func(a, b []ApexInfo) bool {
-		collectApexes := func(infos []ApexInfo) []string {
-			var ret []string
-			for _, info := range infos {
-				ret = append(ret, info.InApexes...)
-			}
-			return ret
-		}
-
-		aApexes := collectApexes(a)
-		bApexes := collectApexes(b)
-		sort.Strings(bApexes)
-		for _, aApex := range aApexes {
-			index := sort.SearchStrings(bApexes, aApex)
-			if index < len(bApexes) && bApexes[index] == aApex {
-				return true
-			}
-		}
-		return false
-	}
-
-	mctx.VisitDirectDeps(func(dep Module) {
-		if depApexModule, ok := dep.(ApexModule); ok {
-			if anyInSameApex(depApexModule.apexModuleBase().apexVariations, m.apexVariations) &&
-				(depApexModule.UniqueApexVariations() ||
-					depApexModule.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps) {
-				m.ApexProperties.UniqueApexVariationsForDeps = true
-			}
-		}
-	})
-}
-
 func (m *ApexModuleBase) BuildForApex(apex ApexInfo) {
 	m.apexVariationsLock.Lock()
 	defer m.apexVariationsLock.Unlock()
@@ -263,16 +253,16 @@
 	m.apexVariations = append(m.apexVariations, apex)
 }
 
-func (m *ApexModuleBase) ApexVariationName() string {
-	return m.ApexProperties.Info.ApexVariationName
+func (m *ApexModuleBase) DirectlyInAnyApex() bool {
+	return m.ApexProperties.DirectlyInAnyApex
 }
 
-func (m *ApexModuleBase) InApexes() []string {
-	return m.ApexProperties.Info.InApexes
+func (m *ApexModuleBase) AnyVariantDirectlyInAnyApex() bool {
+	return m.ApexProperties.AnyVariantDirectlyInAnyApex
 }
 
-func (m *ApexModuleBase) IsForPlatform() bool {
-	return m.ApexProperties.Info.ApexVariationName == ""
+func (m *ApexModuleBase) InAnyApex() bool {
+	return m.ApexProperties.InAnyApex
 }
 
 func (m *ApexModuleBase) CanHaveApexVariants() bool {
@@ -345,10 +335,6 @@
 	}
 }
 
-func (m *ApexModuleBase) Updatable() bool {
-	return m.ApexProperties.Info.Updatable
-}
-
 type byApexName []ApexInfo
 
 func (a byApexName) Len() int           { return len(a) }
@@ -358,7 +344,7 @@
 // mergeApexVariations deduplicates APEX variations that would build identically into a common
 // variation.  It returns the reduced list of variations and a list of aliases from the original
 // variation names to the new variation names.
-func mergeApexVariations(ctx EarlyModuleContext, apexVariations []ApexInfo) (merged []ApexInfo, aliases [][2]string) {
+func mergeApexVariations(ctx PathContext, apexVariations []ApexInfo) (merged []ApexInfo, aliases [][2]string) {
 	sort.Sort(byApexName(apexVariations))
 	seen := make(map[string]int)
 	for _, apexInfo := range apexVariations {
@@ -366,11 +352,13 @@
 		mergedName := apexInfo.mergedName(ctx)
 		if index, exists := seen[mergedName]; exists {
 			merged[index].InApexes = append(merged[index].InApexes, apexName)
+			merged[index].ApexContents = append(merged[index].ApexContents, apexInfo.ApexContents...)
 			merged[index].Updatable = merged[index].Updatable || apexInfo.Updatable
 		} else {
 			seen[mergedName] = len(merged)
 			apexInfo.ApexVariationName = apexInfo.mergedName(ctx)
 			apexInfo.InApexes = CopyOf(apexInfo.InApexes)
+			apexInfo.ApexContents = append([]*ApexContents(nil), apexInfo.ApexContents...)
 			merged = append(merged, apexInfo)
 		}
 		aliases = append(aliases, [2]string{apexName, mergedName})
@@ -378,17 +366,23 @@
 	return merged, aliases
 }
 
-func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []Module {
-	if len(m.apexVariations) > 0 {
-		m.checkApexAvailableProperty(mctx)
+func CreateApexVariations(mctx BottomUpMutatorContext, module ApexModule) []Module {
+	base := module.apexModuleBase()
+	if len(base.apexVariations) > 0 {
+		base.checkApexAvailableProperty(mctx)
 
 		var apexVariations []ApexInfo
 		var aliases [][2]string
-		if !mctx.Module().(ApexModule).UniqueApexVariations() && !m.ApexProperties.UniqueApexVariationsForDeps {
-			apexVariations, aliases = mergeApexVariations(mctx, m.apexVariations)
+		if !mctx.Module().(ApexModule).UniqueApexVariations() && !base.ApexProperties.UniqueApexVariationsForDeps {
+			apexVariations, aliases = mergeApexVariations(mctx, base.apexVariations)
 		} else {
-			apexVariations = m.apexVariations
+			apexVariations = base.apexVariations
 		}
+		// base.apexVariations is only needed to propagate the list of apexes from
+		// apexDepsMutator to apexMutator.  It is no longer accurate after
+		// mergeApexVariations, and won't be copied to all but the first created
+		// variant.  Clear it so it doesn't accidentally get used later.
+		base.apexVariations = nil
 
 		sort.Sort(byApexName(apexVariations))
 		variations := []string{}
@@ -400,6 +394,16 @@
 		defaultVariation := ""
 		mctx.SetDefaultDependencyVariation(&defaultVariation)
 
+		var inApex ApexMembership
+		for _, a := range apexVariations {
+			for _, apexContents := range a.ApexContents {
+				inApex = inApex.merge(apexContents.contents[mctx.ModuleName()])
+			}
+		}
+
+		base.ApexProperties.InAnyApex = true
+		base.ApexProperties.DirectlyInAnyApex = inApex == directlyInApex
+
 		modules := mctx.CreateVariations(variations...)
 		for i, mod := range modules {
 			platformVariation := i == 0
@@ -410,7 +414,7 @@
 				mod.MakeUninstallable()
 			}
 			if !platformVariation {
-				mod.(ApexModule).apexModuleBase().ApexProperties.Info = apexVariations[i-1]
+				mctx.SetVariationProvider(mod, ApexInfoProvider, apexVariations[i-1])
 			}
 		}
 
@@ -423,116 +427,139 @@
 	return nil
 }
 
-var apexData OncePer
-var apexNamesMapMutex sync.Mutex
-var apexNamesKey = NewOnceKey("apexNames")
+// UpdateUniqueApexVariationsForDeps sets UniqueApexVariationsForDeps if any dependencies
+// that are in the same APEX have unique APEX variations so that the module can link against
+// the right variant.
+func UpdateUniqueApexVariationsForDeps(mctx BottomUpMutatorContext, am ApexModule) {
+	// anyInSameApex returns true if the two ApexInfo lists contain any values in an InApexes list
+	// in common.  It is used instead of DepIsInSameApex because it needs to determine if the dep
+	// is in the same APEX due to being directly included, not only if it is included _because_ it
+	// is a dependency.
+	anyInSameApex := func(a, b []ApexInfo) bool {
+		collectApexes := func(infos []ApexInfo) []string {
+			var ret []string
+			for _, info := range infos {
+				ret = append(ret, info.InApexes...)
+			}
+			return ret
+		}
 
-// This structure maintains the global mapping in between modules and APEXes.
-// Examples:
-//
-// apexNamesMap()["foo"]["bar"] == true: module foo is directly depended on by APEX bar
-// apexNamesMap()["foo"]["bar"] == false: module foo is indirectly depended on by APEX bar
-// apexNamesMap()["foo"]["bar"] doesn't exist: foo is not built for APEX bar
-func apexNamesMap() map[string]map[string]bool {
-	return apexData.Once(apexNamesKey, func() interface{} {
-		return make(map[string]map[string]bool)
-	}).(map[string]map[string]bool)
+		aApexes := collectApexes(a)
+		bApexes := collectApexes(b)
+		sort.Strings(bApexes)
+		for _, aApex := range aApexes {
+			index := sort.SearchStrings(bApexes, aApex)
+			if index < len(bApexes) && bApexes[index] == aApex {
+				return true
+			}
+		}
+		return false
+	}
+
+	mctx.VisitDirectDeps(func(dep Module) {
+		if depApexModule, ok := dep.(ApexModule); ok {
+			if anyInSameApex(depApexModule.apexModuleBase().apexVariations, am.apexModuleBase().apexVariations) &&
+				(depApexModule.UniqueApexVariations() ||
+					depApexModule.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps) {
+				am.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps = true
+			}
+		}
+	})
 }
 
-// Update the map to mark that a module named moduleName is directly or indirectly
-// 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(apex ApexInfo, moduleName string, directDep bool) {
-	apexNamesMapMutex.Lock()
-	defer apexNamesMapMutex.Unlock()
-	apexesForModule, ok := apexNamesMap()[moduleName]
-	if !ok {
-		apexesForModule = make(map[string]bool)
-		apexNamesMap()[moduleName] = apexesForModule
+// UpdateDirectlyInAnyApex uses the final module to store if any variant of this
+// module is directly in any APEX, and then copies the final value to all the modules.
+// It also copies the DirectlyInAnyApex value to any direct dependencies with a
+// CopyDirectlyInAnyApexTag dependency tag.
+func UpdateDirectlyInAnyApex(mctx BottomUpMutatorContext, am ApexModule) {
+	base := am.apexModuleBase()
+	// Copy DirectlyInAnyApex and InAnyApex from any direct dependencies with a
+	// CopyDirectlyInAnyApexTag dependency tag.
+	mctx.VisitDirectDeps(func(dep Module) {
+		if _, ok := mctx.OtherModuleDependencyTag(dep).(CopyDirectlyInAnyApexTag); ok {
+			depBase := dep.(ApexModule).apexModuleBase()
+			base.ApexProperties.DirectlyInAnyApex = depBase.ApexProperties.DirectlyInAnyApex
+			base.ApexProperties.InAnyApex = depBase.ApexProperties.InAnyApex
+		}
+	})
+
+	if base.ApexProperties.DirectlyInAnyApex {
+		// Variants of a module are always visited sequentially in order, so it is safe to
+		// write to another variant of this module.
+		// For a BottomUpMutator the PrimaryModule() is visited first and FinalModule() is
+		// visited last.
+		mctx.FinalModule().(ApexModule).apexModuleBase().ApexProperties.AnyVariantDirectlyInAnyApex = true
 	}
-	apexesForModule[apex.ApexVariationName] = apexesForModule[apex.ApexVariationName] || directDep
-	for _, apexName := range apex.InApexes {
-		apexesForModule[apexName] = apexesForModule[apex.ApexVariationName] || directDep
+
+	// If this is the FinalModule (last visited module) copy AnyVariantDirectlyInAnyApex to
+	// all the other variants
+	if am == mctx.FinalModule().(ApexModule) {
+		mctx.VisitAllModuleVariants(func(variant Module) {
+			variant.(ApexModule).apexModuleBase().ApexProperties.AnyVariantDirectlyInAnyApex =
+				base.ApexProperties.AnyVariantDirectlyInAnyApex
+		})
 	}
 }
 
-// TODO(b/146393795): remove this when b/146393795 is fixed
-func ClearApexDependency() {
-	m := apexNamesMap()
-	for k := range m {
-		delete(m, k)
+type ApexMembership int
+
+const (
+	notInApex        ApexMembership = 0
+	indirectlyInApex                = iota
+	directlyInApex
+)
+
+// Each apexBundle has an apexContents, and modules in that apex have a provider containing the
+// apexContents of each apexBundle they are part of.
+type ApexContents struct {
+	ApexName string
+	contents map[string]ApexMembership
+}
+
+func NewApexContents(name string, contents map[string]ApexMembership) *ApexContents {
+	return &ApexContents{
+		ApexName: name,
+		contents: contents,
 	}
 }
 
-// Tests whether a module named moduleName is directly depended on by an APEX
-// named apexName.
-func DirectlyInApex(apexName string, moduleName string) bool {
-	apexNamesMapMutex.Lock()
-	defer apexNamesMapMutex.Unlock()
-	if apexNamesForModule, ok := apexNamesMap()[moduleName]; ok {
-		return apexNamesForModule[apexName]
+func (i ApexMembership) Add(direct bool) ApexMembership {
+	if direct || i == directlyInApex {
+		return directlyInApex
 	}
-	return false
+	return indirectlyInApex
+}
+
+func (i ApexMembership) merge(other ApexMembership) ApexMembership {
+	if other == directlyInApex || i == directlyInApex {
+		return directlyInApex
+	}
+
+	if other == indirectlyInApex || i == indirectlyInApex {
+		return indirectlyInApex
+	}
+	return notInApex
+}
+
+func (ac *ApexContents) DirectlyInApex(name string) bool {
+	return ac.contents[name] == directlyInApex
+}
+
+func (ac *ApexContents) InApex(name string) bool {
+	return ac.contents[name] != notInApex
 }
 
 // Tests whether a module named moduleName is directly depended on by all APEXes
-// in a list of apexNames.
-func DirectlyInAllApexes(apexNames []string, moduleName string) bool {
-	apexNamesMapMutex.Lock()
-	defer apexNamesMapMutex.Unlock()
-	for _, apexName := range apexNames {
-		apexNamesForModule := apexNamesMap()[moduleName]
-		if !apexNamesForModule[apexName] {
+// in an ApexInfo.
+func DirectlyInAllApexes(apexInfo ApexInfo, moduleName string) bool {
+	for _, contents := range apexInfo.ApexContents {
+		if !contents.DirectlyInApex(moduleName) {
 			return false
 		}
 	}
 	return true
 }
 
-type hostContext interface {
-	Host() bool
-}
-
-// Tests whether a module named moduleName is directly depended on by any APEX.
-func DirectlyInAnyApex(ctx hostContext, moduleName string) bool {
-	if ctx.Host() {
-		// Host has no APEX.
-		return false
-	}
-	apexNamesMapMutex.Lock()
-	defer apexNamesMapMutex.Unlock()
-	if apexNames, ok := apexNamesMap()[moduleName]; ok {
-		for an := range apexNames {
-			if apexNames[an] {
-				return true
-			}
-		}
-	}
-	return false
-}
-
-// Tests whether a module named module is depended on (including both
-// direct and indirect dependencies) by any APEX.
-func InAnyApex(moduleName string) bool {
-	apexNamesMapMutex.Lock()
-	defer apexNamesMapMutex.Unlock()
-	apexNames, ok := apexNamesMap()[moduleName]
-	return ok && len(apexNames) > 0
-}
-
-func GetApexesForModule(moduleName string) []string {
-	ret := []string{}
-	apexNamesMapMutex.Lock()
-	defer apexNamesMapMutex.Unlock()
-	if apexNames, ok := apexNamesMap()[moduleName]; ok {
-		for an := range apexNames {
-			ret = append(ret, an)
-		}
-	}
-	return ret
-}
-
 func InitApexModule(m ApexModule) {
 	base := m.apexModuleBase()
 	base.canHaveApexVariants = true
@@ -581,15 +608,15 @@
 	var fullContent strings.Builder
 	var flatContent strings.Builder
 
-	fmt.Fprintf(&flatContent, "%s(minSdkVersion:%s):\\n", ctx.ModuleName(), minSdkVersion)
+	fmt.Fprintf(&fullContent, "%s(minSdkVersion:%s):\\n", ctx.ModuleName(), minSdkVersion)
 	for _, key := range FirstUniqueStrings(SortedStringKeys(depInfos)) {
 		info := depInfos[key]
 		toName := fmt.Sprintf("%s(minSdkVersion:%s)", info.To, info.MinSdkVersion)
 		if info.IsExternal {
 			toName = toName + " (external)"
 		}
-		fmt.Fprintf(&fullContent, "%s <- %s\\n", toName, strings.Join(SortedUniqueStrings(info.From), ", "))
-		fmt.Fprintf(&flatContent, "  %s\\n", toName)
+		fmt.Fprintf(&fullContent, "  %s <- %s\\n", toName, strings.Join(SortedUniqueStrings(info.From), ", "))
+		fmt.Fprintf(&flatContent, "%s\\n", toName)
 	}
 
 	d.fullListPath = PathForModuleOut(ctx, "depsinfo", "fulllist.txt").OutputPath
diff --git a/android/apex_test.go b/android/apex_test.go
index db02833..7507628 100644
--- a/android/apex_test.go
+++ b/android/apex_test.go
@@ -20,6 +20,7 @@
 )
 
 func Test_mergeApexVariations(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name        string
 		in          []ApexInfo
@@ -29,10 +30,10 @@
 		{
 			name: "single",
 			in: []ApexInfo{
-				{"foo", 10000, false, nil, []string{"foo"}},
+				{"foo", "current", false, nil, []string{"foo"}, nil},
 			},
 			wantMerged: []ApexInfo{
-				{"apex10000", 10000, false, nil, []string{"foo"}},
+				{"apex10000", "current", false, nil, []string{"foo"}, nil},
 			},
 			wantAliases: [][2]string{
 				{"foo", "apex10000"},
@@ -41,12 +42,11 @@
 		{
 			name: "merge",
 			in: []ApexInfo{
-				{"foo", 10000, false, SdkRefs{{"baz", "1"}}, []string{"foo"}},
-				{"bar", 10000, false, SdkRefs{{"baz", "1"}}, []string{"bar"}},
+				{"foo", "current", false, SdkRefs{{"baz", "1"}}, []string{"foo"}, nil},
+				{"bar", "current", false, SdkRefs{{"baz", "1"}}, []string{"bar"}, nil},
 			},
 			wantMerged: []ApexInfo{
-				{"apex10000_baz_1", 10000, false, SdkRefs{{"baz", "1"}}, []string{"bar", "foo"}},
-			},
+				{"apex10000_baz_1", "current", false, SdkRefs{{"baz", "1"}}, []string{"bar", "foo"}, nil}},
 			wantAliases: [][2]string{
 				{"bar", "apex10000_baz_1"},
 				{"foo", "apex10000_baz_1"},
@@ -55,12 +55,12 @@
 		{
 			name: "don't merge version",
 			in: []ApexInfo{
-				{"foo", 10000, false, nil, []string{"foo"}},
-				{"bar", 30, false, nil, []string{"bar"}},
+				{"foo", "current", false, nil, []string{"foo"}, nil},
+				{"bar", "30", false, nil, []string{"bar"}, nil},
 			},
 			wantMerged: []ApexInfo{
-				{"apex30", 30, false, nil, []string{"bar"}},
-				{"apex10000", 10000, false, nil, []string{"foo"}},
+				{"apex30", "30", false, nil, []string{"bar"}, nil},
+				{"apex10000", "current", false, nil, []string{"foo"}, nil},
 			},
 			wantAliases: [][2]string{
 				{"bar", "apex30"},
@@ -70,11 +70,11 @@
 		{
 			name: "merge updatable",
 			in: []ApexInfo{
-				{"foo", 10000, false, nil, []string{"foo"}},
-				{"bar", 10000, true, nil, []string{"bar"}},
+				{"foo", "current", false, nil, []string{"foo"}, nil},
+				{"bar", "current", true, nil, []string{"bar"}, nil},
 			},
 			wantMerged: []ApexInfo{
-				{"apex10000", 10000, true, nil, []string{"bar", "foo"}},
+				{"apex10000", "current", true, nil, []string{"bar", "foo"}, nil},
 			},
 			wantAliases: [][2]string{
 				{"bar", "apex10000"},
@@ -84,12 +84,12 @@
 		{
 			name: "don't merge sdks",
 			in: []ApexInfo{
-				{"foo", 10000, false, SdkRefs{{"baz", "1"}}, []string{"foo"}},
-				{"bar", 10000, false, SdkRefs{{"baz", "2"}}, []string{"bar"}},
+				{"foo", "current", false, SdkRefs{{"baz", "1"}}, []string{"foo"}, nil},
+				{"bar", "current", false, SdkRefs{{"baz", "2"}}, []string{"bar"}, nil},
 			},
 			wantMerged: []ApexInfo{
-				{"apex10000_baz_2", 10000, false, SdkRefs{{"baz", "2"}}, []string{"bar"}},
-				{"apex10000_baz_1", 10000, false, SdkRefs{{"baz", "1"}}, []string{"foo"}},
+				{"apex10000_baz_2", "current", false, SdkRefs{{"baz", "2"}}, []string{"bar"}, nil},
+				{"apex10000_baz_1", "current", false, SdkRefs{{"baz", "1"}}, []string{"foo"}, nil},
 			},
 			wantAliases: [][2]string{
 				{"bar", "apex10000_baz_2"},
@@ -99,7 +99,9 @@
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			gotMerged, gotAliases := mergeApexVariations(tt.in)
+			config := TestConfig(buildDir, nil, "", nil)
+			ctx := &configErrorWrapper{config: config}
+			gotMerged, gotAliases := mergeApexVariations(ctx, tt.in)
 			if !reflect.DeepEqual(gotMerged, tt.wantMerged) {
 				t.Errorf("mergeApexVariations() gotMerged = %v, want %v", gotMerged, tt.wantMerged)
 			}
diff --git a/android/api_levels.go b/android/api_levels.go
index 9768340..bace3d4 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -152,7 +152,7 @@
 // * "30" -> "30"
 // * "R" -> "30"
 // * "S" -> "S"
-func ReplaceFinalizedCodenames(ctx EarlyModuleContext, raw string) string {
+func ReplaceFinalizedCodenames(ctx PathContext, raw string) string {
 	num, ok := getFinalCodenamesMap(ctx.Config())[raw]
 	if !ok {
 		return raw
@@ -175,7 +175,7 @@
 //
 // Inputs that are not "current", known previews, or convertible to an integer
 // will return an error.
-func ApiLevelFromUser(ctx EarlyModuleContext, raw string) (ApiLevel, error) {
+func ApiLevelFromUser(ctx PathContext, raw string) (ApiLevel, error) {
 	if raw == "" {
 		panic("API level string must be non-empty")
 	}
@@ -203,7 +203,7 @@
 // Converts an API level string `raw` into an ApiLevel in the same method as
 // `ApiLevelFromUser`, but the input is assumed to have no errors and any errors
 // will panic instead of returning an error.
-func ApiLevelOrPanic(ctx EarlyModuleContext, raw string) ApiLevel {
+func ApiLevelOrPanic(ctx PathContext, raw string) ApiLevel {
 	value, err := ApiLevelFromUser(ctx, raw)
 	if err != nil {
 		panic(err.Error())
diff --git a/android/arch_test.go b/android/arch_test.go
index 8525b03..7ec050f 100644
--- a/android/arch_test.go
+++ b/android/arch_test.go
@@ -36,6 +36,7 @@
 }
 
 func TestFilterArchStruct(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name     string
 		in       interface{}
@@ -274,6 +275,7 @@
 }
 
 func TestArchMutator(t *testing.T) {
+	t.Parallel()
 	var buildOSVariants []string
 	var buildOS32Variants []string
 	switch runtime.GOOS {
@@ -385,6 +387,7 @@
 }
 
 func TestArchMutatorNativeBridge(t *testing.T) {
+	t.Parallel()
 	bp := `
 		// This module is only enabled for x86.
 		module {
diff --git a/android/config_test.go b/android/config_test.go
index 274d59f..0c907b7 100644
--- a/android/config_test.go
+++ b/android/config_test.go
@@ -58,6 +58,7 @@
 
 // tests that ValidateConfigAnnotation works
 func TestValidateConfigAnnotations(t *testing.T) {
+	t.Parallel()
 	config := configType{}
 	err := validateConfigAnnotations(&config)
 	expectedError := `Field configType.PopulateMe has tag json:"omitempty" which specifies to change its json field name to "omitempty".
@@ -74,6 +75,7 @@
 
 // run validateConfigAnnotations against each type that might have json annotations
 func TestProductConfigAnnotations(t *testing.T) {
+	t.Parallel()
 	err := validateConfigAnnotations(&productVariables{})
 	if err != nil {
 		t.Errorf(err.Error())
@@ -86,6 +88,7 @@
 }
 
 func TestMissingVendorConfig(t *testing.T) {
+	t.Parallel()
 	c := &config{}
 	if c.VendorConfig("test").Bool("not_set") {
 		t.Errorf("Expected false")
diff --git a/android/csuite_config_test.go b/android/csuite_config_test.go
index bf1a19a..ec93ed6 100644
--- a/android/csuite_config_test.go
+++ b/android/csuite_config_test.go
@@ -32,6 +32,7 @@
 }
 
 func TestCSuiteConfig(t *testing.T) {
+	t.Parallel()
 	ctx := testCSuiteConfig(t, `
 csuite_config { name: "plain"}
 csuite_config { name: "with_manifest", test_config: "manifest.xml" }
diff --git a/android/defaults_test.go b/android/defaults_test.go
index d096b2f..a6abe8f 100644
--- a/android/defaults_test.go
+++ b/android/defaults_test.go
@@ -59,6 +59,7 @@
 }
 
 func TestDefaults(t *testing.T) {
+	t.Parallel()
 	bp := `
 		defaults {
 			name: "transitive",
@@ -102,6 +103,7 @@
 }
 
 func TestDefaultsAllowMissingDependencies(t *testing.T) {
+	t.Parallel()
 	bp := `
 		defaults {
 			name: "defaults",
diff --git a/android/depset_test.go b/android/depset_test.go
index c328127..1ad27eb 100644
--- a/android/depset_test.go
+++ b/android/depset_test.go
@@ -64,6 +64,7 @@
 // Tests based on Bazel's ExpanderTestBase.java to ensure compatibility
 // https://github.com/bazelbuild/bazel/blob/master/src/test/java/com/google/devtools/build/lib/collect/nestedset/ExpanderTestBase.java
 func TestDepSet(t *testing.T) {
+	t.Parallel()
 	a := PathForTesting("a")
 	b := PathForTesting("b")
 	c := PathForTesting("c")
@@ -274,6 +275,7 @@
 }
 
 func TestDepSetInvalidOrder(t *testing.T) {
+	t.Parallel()
 	orders := []DepSetOrder{POSTORDER, PREORDER, TOPOLOGICAL}
 
 	run := func(t *testing.T, order1, order2 DepSetOrder) {
diff --git a/android/expand_test.go b/android/expand_test.go
index 12179ed..7992288 100644
--- a/android/expand_test.go
+++ b/android/expand_test.go
@@ -163,6 +163,7 @@
 }
 
 func TestExpand(t *testing.T) {
+	t.Parallel()
 	for _, test := range expandTestCases {
 		got, err := Expand(test.in, func(s string) (string, error) {
 			s, _, err := expander(s)
@@ -179,6 +180,7 @@
 }
 
 func TestExpandNinjaEscaped(t *testing.T) {
+	t.Parallel()
 	for _, test := range expandTestCases {
 		got, err := ExpandNinjaEscaped(test.in, expander)
 		if err != nil && !test.err {
diff --git a/android/module.go b/android/module.go
index c4e43c2..056b0a5 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1499,8 +1499,8 @@
 	if !ctx.PrimaryArch() {
 		suffix = append(suffix, ctx.Arch().ArchType.String())
 	}
-	if apex, ok := m.module.(ApexModule); ok && !apex.IsForPlatform() {
-		suffix = append(suffix, apex.ApexVariationName())
+	if apexInfo := ctx.Provider(ApexInfoProvider).(ApexInfo); !apexInfo.IsForPlatform() {
+		suffix = append(suffix, apexInfo.ApexVariationName)
 	}
 
 	ctx.Variable(pctx, "moduleDesc", desc)
diff --git a/android/module_test.go b/android/module_test.go
index 6e648d7..b2a41e4 100644
--- a/android/module_test.go
+++ b/android/module_test.go
@@ -19,6 +19,7 @@
 )
 
 func TestSrcIsModule(t *testing.T) {
+	t.Parallel()
 	type args struct {
 		s string
 	}
@@ -66,6 +67,7 @@
 }
 
 func TestSrcIsModuleWithTag(t *testing.T) {
+	t.Parallel()
 	type args struct {
 		s string
 	}
@@ -164,6 +166,7 @@
 }
 
 func TestErrorDependsOnDisabledModule(t *testing.T) {
+	t.Parallel()
 	ctx := NewTestContext()
 	ctx.RegisterModuleType("deps", depsModuleFactory)
 
diff --git a/android/mutator_test.go b/android/mutator_test.go
index 191b535..ce073bf 100644
--- a/android/mutator_test.go
+++ b/android/mutator_test.go
@@ -59,6 +59,7 @@
 }
 
 func TestMutatorAddMissingDependencies(t *testing.T) {
+	t.Parallel()
 	bp := `
 		test {
 			name: "foo",
@@ -92,6 +93,7 @@
 }
 
 func TestModuleString(t *testing.T) {
+	t.Parallel()
 	ctx := NewTestContext()
 
 	var moduleStrings []string
@@ -190,6 +192,7 @@
 }
 
 func TestFinalDepsPhase(t *testing.T) {
+	t.Parallel()
 	ctx := NewTestContext()
 
 	finalGot := map[string]int{}
@@ -267,6 +270,7 @@
 }
 
 func TestNoCreateVariationsInFinalDeps(t *testing.T) {
+	t.Parallel()
 	ctx := NewTestContext()
 
 	checkErr := func() {
diff --git a/android/namespace_test.go b/android/namespace_test.go
index 66c0d89..5cce3e4 100644
--- a/android/namespace_test.go
+++ b/android/namespace_test.go
@@ -24,6 +24,7 @@
 )
 
 func TestDependingOnModuleInSameNamespace(t *testing.T) {
+	t.Parallel()
 	ctx := setupTest(t,
 		map[string]string{
 			"dir1": `
@@ -48,6 +49,7 @@
 }
 
 func TestDependingOnModuleInRootNamespace(t *testing.T) {
+	t.Parallel()
 	ctx := setupTest(t,
 		map[string]string{
 			".": `
@@ -70,6 +72,7 @@
 }
 
 func TestImplicitlyImportRootNamespace(t *testing.T) {
+	t.Parallel()
 	_ = setupTest(t,
 		map[string]string{
 			".": `
@@ -92,6 +95,7 @@
 }
 
 func TestDependingOnBlueprintModuleInRootNamespace(t *testing.T) {
+	t.Parallel()
 	_ = setupTest(t,
 		map[string]string{
 			".": `
@@ -114,6 +118,7 @@
 }
 
 func TestDependingOnModuleInImportedNamespace(t *testing.T) {
+	t.Parallel()
 	ctx := setupTest(t,
 		map[string]string{
 			"dir1": `
@@ -143,6 +148,7 @@
 }
 
 func TestDependingOnModuleInNonImportedNamespace(t *testing.T) {
+	t.Parallel()
 	_, errs := setupTestExpectErrs(
 		map[string]string{
 			"dir1": `
@@ -183,6 +189,7 @@
 }
 
 func TestDependingOnModuleByFullyQualifiedReference(t *testing.T) {
+	t.Parallel()
 	ctx := setupTest(t,
 		map[string]string{
 			"dir1": `
@@ -210,6 +217,7 @@
 }
 
 func TestSameNameInTwoNamespaces(t *testing.T) {
+	t.Parallel()
 	ctx := setupTest(t,
 		map[string]string{
 			"dir1": `
@@ -260,6 +268,7 @@
 }
 
 func TestSearchOrder(t *testing.T) {
+	t.Parallel()
 	ctx := setupTest(t,
 		map[string]string{
 			"dir1": `
@@ -348,6 +357,7 @@
 }
 
 func TestTwoNamespacesCanImportEachOther(t *testing.T) {
+	t.Parallel()
 	_ = setupTest(t,
 		map[string]string{
 			"dir1": `
@@ -378,6 +388,7 @@
 }
 
 func TestImportingNonexistentNamespace(t *testing.T) {
+	t.Parallel()
 	_, errs := setupTestExpectErrs(
 		map[string]string{
 			"dir1": `
@@ -402,6 +413,7 @@
 }
 
 func TestNamespacesDontInheritParentNamespaces(t *testing.T) {
+	t.Parallel()
 	_, errs := setupTestExpectErrs(
 		map[string]string{
 			"dir1": `
@@ -433,6 +445,7 @@
 }
 
 func TestModulesDoReceiveParentNamespace(t *testing.T) {
+	t.Parallel()
 	_ = setupTest(t,
 		map[string]string{
 			"dir1": `
@@ -455,6 +468,7 @@
 }
 
 func TestNamespaceImportsNotTransitive(t *testing.T) {
+	t.Parallel()
 	_, errs := setupTestExpectErrs(
 		map[string]string{
 			"dir1": `
@@ -496,6 +510,7 @@
 }
 
 func TestTwoNamepacesInSameDir(t *testing.T) {
+	t.Parallel()
 	_, errs := setupTestExpectErrs(
 		map[string]string{
 			"dir1": `
@@ -516,6 +531,7 @@
 }
 
 func TestNamespaceNotAtTopOfFile(t *testing.T) {
+	t.Parallel()
 	_, errs := setupTestExpectErrs(
 		map[string]string{
 			"dir1": `
@@ -537,6 +553,7 @@
 }
 
 func TestTwoModulesWithSameNameInSameNamespace(t *testing.T) {
+	t.Parallel()
 	_, errs := setupTestExpectErrs(
 		map[string]string{
 			"dir1": `
@@ -562,6 +579,7 @@
 }
 
 func TestDeclaringNamespaceInNonAndroidBpFile(t *testing.T) {
+	t.Parallel()
 	_, errs := setupTestFromFiles(
 		map[string][]byte{
 			"Android.bp": []byte(`
@@ -585,6 +603,7 @@
 
 // so that the generated .ninja file will have consistent names
 func TestConsistentNamespaceNames(t *testing.T) {
+	t.Parallel()
 	ctx := setupTest(t,
 		map[string]string{
 			"dir1": "soong_namespace{}",
@@ -604,6 +623,7 @@
 
 // so that the generated .ninja file will have consistent names
 func TestRename(t *testing.T) {
+	t.Parallel()
 	_ = setupTest(t,
 		map[string]string{
 			"dir1": `
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index 56a07dc..306c509 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -343,6 +343,7 @@
 }
 
 func TestNeverallow(t *testing.T) {
+	t.Parallel()
 	for _, test := range neverallowTests {
 		// Create a test per config to allow for test specific config, e.g. test rules.
 		config := TestConfig(buildDir, nil, "", test.fs)
diff --git a/android/onceper_test.go b/android/onceper_test.go
index 1a55ff4..da0b10d 100644
--- a/android/onceper_test.go
+++ b/android/onceper_test.go
@@ -20,6 +20,7 @@
 )
 
 func TestOncePer_Once(t *testing.T) {
+	t.Parallel()
 	once := OncePer{}
 	key := NewOnceKey("key")
 
@@ -36,6 +37,7 @@
 }
 
 func TestOncePer_Once_wait(t *testing.T) {
+	t.Parallel()
 	once := OncePer{}
 	key := NewOnceKey("key")
 
@@ -51,6 +53,7 @@
 }
 
 func TestOncePer_Get(t *testing.T) {
+	t.Parallel()
 	once := OncePer{}
 	key := NewOnceKey("key")
 
@@ -67,6 +70,7 @@
 }
 
 func TestOncePer_Get_panic(t *testing.T) {
+	t.Parallel()
 	once := OncePer{}
 	key := NewOnceKey("key")
 
@@ -82,6 +86,7 @@
 }
 
 func TestOncePer_Get_wait(t *testing.T) {
+	t.Parallel()
 	once := OncePer{}
 	key := NewOnceKey("key")
 
@@ -97,6 +102,7 @@
 }
 
 func TestOncePer_OnceStringSlice(t *testing.T) {
+	t.Parallel()
 	once := OncePer{}
 	key := NewOnceKey("key")
 
@@ -113,6 +119,7 @@
 }
 
 func TestOncePer_Once2StringSlice(t *testing.T) {
+	t.Parallel()
 	once := OncePer{}
 	key := NewOnceKey("key")
 
@@ -129,6 +136,7 @@
 }
 
 func TestNewOnceKey(t *testing.T) {
+	t.Parallel()
 	once := OncePer{}
 	key1 := NewOnceKey("key")
 	key2 := NewOnceKey("key")
@@ -146,6 +154,7 @@
 }
 
 func TestNewCustomOnceKey(t *testing.T) {
+	t.Parallel()
 	type key struct {
 		key string
 	}
@@ -166,6 +175,7 @@
 }
 
 func TestOncePerReentrant(t *testing.T) {
+	t.Parallel()
 	once := OncePer{}
 	key1 := NewOnceKey("key")
 	key2 := NewOnceKey("key")
@@ -178,6 +188,7 @@
 
 // Test that a recovered panic in a Once function doesn't deadlock
 func TestOncePerPanic(t *testing.T) {
+	t.Parallel()
 	once := OncePer{}
 	key := NewOnceKey("key")
 
diff --git a/android/package_test.go b/android/package_test.go
index 04dfc08..a4b4c60 100644
--- a/android/package_test.go
+++ b/android/package_test.go
@@ -56,6 +56,7 @@
 }
 
 func TestPackage(t *testing.T) {
+	t.Parallel()
 	for _, test := range packageTests {
 		t.Run(test.name, func(t *testing.T) {
 			_, errs := testPackage(test.fs)
diff --git a/android/path_properties_test.go b/android/path_properties_test.go
index f367b82..9bbb571 100644
--- a/android/path_properties_test.go
+++ b/android/path_properties_test.go
@@ -59,6 +59,7 @@
 }
 
 func TestPathDepsMutator(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name string
 		bp   string
diff --git a/android/paths_test.go b/android/paths_test.go
index d099f65..03e1410 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -110,6 +110,7 @@
 }...)
 
 func TestValidateSafePath(t *testing.T) {
+	t.Parallel()
 	for _, testCase := range validateSafePathTestCases {
 		t.Run(strings.Join(testCase.in, ","), func(t *testing.T) {
 			ctx := &configErrorWrapper{}
@@ -123,6 +124,7 @@
 }
 
 func TestValidatePath(t *testing.T) {
+	t.Parallel()
 	for _, testCase := range validatePathTestCases {
 		t.Run(strings.Join(testCase.in, ","), func(t *testing.T) {
 			ctx := &configErrorWrapper{}
@@ -136,6 +138,7 @@
 }
 
 func TestOptionalPath(t *testing.T) {
+	t.Parallel()
 	var path OptionalPath
 	checkInvalidOptionalPath(t, path)
 
@@ -253,6 +256,7 @@
 }
 
 func TestPathForModuleInstall(t *testing.T) {
+	t.Parallel()
 	testConfig := pathTestConfig("")
 
 	hostTarget := Target{Os: Linux, Arch: Arch{ArchType: X86}}
@@ -657,6 +661,7 @@
 }
 
 func TestDirectorySortedPaths(t *testing.T) {
+	t.Parallel()
 	config := TestConfig("out", nil, "", map[string][]byte{
 		"Android.bp": nil,
 		"a.txt":      nil,
@@ -739,6 +744,7 @@
 }
 
 func TestMaybeRel(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name   string
 		base   string
@@ -796,6 +802,7 @@
 }
 
 func TestPathForSource(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name     string
 		buildDir string
@@ -1028,6 +1035,7 @@
 }
 
 func TestPathsForModuleSrc(t *testing.T) {
+	t.Parallel()
 	tests := []pathForModuleSrcTestCase{
 		{
 			name: "path",
@@ -1123,6 +1131,7 @@
 }
 
 func TestPathForModuleSrc(t *testing.T) {
+	t.Parallel()
 	tests := []pathForModuleSrcTestCase{
 		{
 			name: "path",
@@ -1190,6 +1199,7 @@
 }
 
 func TestPathsForModuleSrc_AllowMissingDependencies(t *testing.T) {
+	t.Parallel()
 	bp := `
 		test {
 			name: "foo",
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 854395e..40fced8 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -262,6 +262,7 @@
 }
 
 func TestPrebuilts(t *testing.T) {
+	t.Parallel()
 	fs := map[string][]byte{
 		"prebuilt_file": nil,
 		"source_file":   nil,
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
index c41b067..d205a5b 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -264,6 +264,7 @@
 }
 
 func TestRuleBuilder(t *testing.T) {
+	t.Parallel()
 	fs := map[string][]byte{
 		"dep_fixer":  nil,
 		"input":      nil,
@@ -455,6 +456,7 @@
 }
 
 func TestRuleBuilder_Build(t *testing.T) {
+	t.Parallel()
 	fs := map[string][]byte{
 		"bar": nil,
 		"cp":  nil,
@@ -546,6 +548,7 @@
 }
 
 func Test_ninjaEscapeExceptForSpans(t *testing.T) {
+	t.Parallel()
 	type args struct {
 		s     string
 		spans [][2]int
diff --git a/android/soong_config_modules_test.go b/android/soong_config_modules_test.go
index f905b1a..f0f1462 100644
--- a/android/soong_config_modules_test.go
+++ b/android/soong_config_modules_test.go
@@ -38,6 +38,7 @@
 func (t soongConfigTestModule) GenerateAndroidBuildActions(ModuleContext) {}
 
 func TestSoongConfigModule(t *testing.T) {
+	t.Parallel()
 	configBp := `
 		soong_config_module_type {
 			name: "acme_test_defaults",
diff --git a/android/soongconfig/modules_test.go b/android/soongconfig/modules_test.go
index 4190016..ff4883e 100644
--- a/android/soongconfig/modules_test.go
+++ b/android/soongconfig/modules_test.go
@@ -20,6 +20,7 @@
 )
 
 func Test_CanonicalizeToProperty(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name string
 		arg  string
@@ -66,6 +67,7 @@
 }
 
 func Test_typeForPropertyFromPropertyStruct(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name     string
 		ps       interface{}
@@ -186,6 +188,7 @@
 }
 
 func Test_createAffectablePropertiesType(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name                 string
 		affectableProperties []string
diff --git a/android/util_test.go b/android/util_test.go
index 25b52ca..8c42157 100644
--- a/android/util_test.go
+++ b/android/util_test.go
@@ -60,6 +60,7 @@
 }
 
 func TestFirstUniqueStrings(t *testing.T) {
+	t.Parallel()
 	f := func(t *testing.T, imp func([]string) []string, in, want []string) {
 		t.Helper()
 		out := imp(in)
@@ -120,6 +121,7 @@
 }
 
 func TestLastUniqueStrings(t *testing.T) {
+	t.Parallel()
 	for _, testCase := range lastUniqueStringsTestCases {
 		out := LastUniqueStrings(testCase.in)
 		if !reflect.DeepEqual(out, testCase.out) {
@@ -132,6 +134,7 @@
 }
 
 func TestJoinWithPrefix(t *testing.T) {
+	t.Parallel()
 	testcases := []struct {
 		name     string
 		input    []string
@@ -171,6 +174,7 @@
 }
 
 func TestIndexList(t *testing.T) {
+	t.Parallel()
 	input := []string{"a", "b", "c"}
 
 	testcases := []struct {
@@ -210,6 +214,7 @@
 }
 
 func TestInList(t *testing.T) {
+	t.Parallel()
 	input := []string{"a"}
 
 	testcases := []struct {
@@ -241,6 +246,7 @@
 }
 
 func TestPrefixInList(t *testing.T) {
+	t.Parallel()
 	prefixes := []string{"a", "b"}
 
 	testcases := []struct {
@@ -276,6 +282,7 @@
 }
 
 func TestFilterList(t *testing.T) {
+	t.Parallel()
 	input := []string{"a", "b", "c", "c", "b", "d", "a"}
 	filter := []string{"a", "c"}
 	remainder, filtered := FilterList(input, filter)
@@ -300,6 +307,7 @@
 }
 
 func TestRemoveListFromList(t *testing.T) {
+	t.Parallel()
 	input := []string{"a", "b", "c", "d", "a", "c", "d"}
 	filter := []string{"a", "c"}
 	expected := []string{"b", "d", "d"}
@@ -314,6 +322,7 @@
 }
 
 func TestRemoveFromList(t *testing.T) {
+	t.Parallel()
 	testcases := []struct {
 		name          string
 		key           string
@@ -417,6 +426,7 @@
 }
 
 func TestSplitFileExt(t *testing.T) {
+	t.Parallel()
 	t.Run("soname with version", func(t *testing.T) {
 		root, suffix, ext := SplitFileExt("libtest.so.1.0.30")
 		expected := "libtest"
@@ -482,6 +492,7 @@
 }
 
 func Test_Shard(t *testing.T) {
+	t.Parallel()
 	type args struct {
 		strings   []string
 		shardSize int
diff --git a/android/variable_test.go b/android/variable_test.go
index 9cafedd..9348b0d 100644
--- a/android/variable_test.go
+++ b/android/variable_test.go
@@ -112,6 +112,7 @@
 }
 
 func TestPrintfIntoProperty(t *testing.T) {
+	t.Parallel()
 	for _, testCase := range printfIntoPropertyTestCases {
 		s := testCase.in
 		v := reflect.ValueOf(&s).Elem()
@@ -157,6 +158,7 @@
 }
 
 func TestProductVariables(t *testing.T) {
+	t.Parallel()
 	ctx := NewTestContext()
 	// A module type that has a srcs property but not a cflags property.
 	ctx.RegisterModuleType("module1", testProductVariableModuleFactoryFactory(&struct {
@@ -265,6 +267,7 @@
 
 // Test a defaults module that supports more product variable properties than the target module.
 func TestProductVariablesDefaults(t *testing.T) {
+	t.Parallel()
 	bp := `
 		defaults {
 			name: "defaults",
diff --git a/android/visibility.go b/android/visibility.go
index 68da1c4..51d5611 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -17,6 +17,7 @@
 import (
 	"fmt"
 	"regexp"
+	"sort"
 	"strings"
 	"sync"
 
@@ -441,12 +442,19 @@
 		}
 
 		rule := effectiveVisibilityRules(ctx.Config(), depQualified)
-		if rule != nil && !rule.matches(qualified) {
+		if !rule.matches(qualified) {
 			ctx.ModuleErrorf("depends on %s which is not visible to this module", depQualified)
 		}
 	})
 }
 
+// Default visibility is public.
+var defaultVisibility = compositeRule{publicRule{}}
+
+// Return the effective visibility rules.
+//
+// If no rules have been specified this will return the default visibility rule
+// which is currently //visibility:public.
 func effectiveVisibilityRules(config Config, qualified qualifiedModuleName) compositeRule {
 	moduleToVisibilityRule := moduleToVisibilityRuleMap(config)
 	value, ok := moduleToVisibilityRule.Load(qualified)
@@ -456,6 +464,12 @@
 	} else {
 		rule = packageDefaultVisibility(config, qualified)
 	}
+
+	// If no rule is specified then return the default visibility rule to avoid
+	// every caller having to treat nil as public.
+	if rule == nil {
+		rule = defaultVisibility
+	}
 	return rule
 }
 
@@ -483,13 +497,63 @@
 	}
 }
 
+type VisibilityRuleSet interface {
+	// Widen the visibility with some extra rules.
+	Widen(extra []string) error
+
+	Strings() []string
+}
+
+type visibilityRuleSet struct {
+	rules []string
+}
+
+var _ VisibilityRuleSet = (*visibilityRuleSet)(nil)
+
+func (v *visibilityRuleSet) Widen(extra []string) error {
+	// Check the extra rules first just in case they are invalid. Otherwise, if
+	// the current visibility is public then the extra rules will just be ignored.
+	if len(extra) == 1 {
+		singularRule := extra[0]
+		switch singularRule {
+		case "//visibility:public":
+			// Public overrides everything so just discard any existing rules.
+			v.rules = extra
+			return nil
+		case "//visibility:private":
+			// Extending rule with private is an error.
+			return fmt.Errorf("%q does not widen the visibility", singularRule)
+		}
+	}
+
+	if len(v.rules) == 1 {
+		switch v.rules[0] {
+		case "//visibility:public":
+			// No point in adding rules to something which is already public.
+			return nil
+		case "//visibility:private":
+			// Adding any rules to private means it is no longer private so the
+			// private can be discarded.
+			v.rules = nil
+		}
+	}
+
+	v.rules = FirstUniqueStrings(append(v.rules, extra...))
+	sort.Strings(v.rules)
+	return nil
+}
+
+func (v *visibilityRuleSet) Strings() []string {
+	return v.rules
+}
+
 // Get the effective visibility rules, i.e. the actual rules that affect the visibility of the
 // property irrespective of where they are defined.
 //
 // Includes visibility rules specified by package default_visibility and/or on defaults.
 // Short hand forms, e.g. //:__subpackages__ are replaced with their full form, e.g.
 // //package/containing/rule:__subpackages__.
-func EffectiveVisibilityRules(ctx BaseModuleContext, module Module) []string {
+func EffectiveVisibilityRules(ctx BaseModuleContext, module Module) VisibilityRuleSet {
 	moduleName := ctx.OtherModuleName(module)
 	dir := ctx.OtherModuleDir(module)
 	qualified := qualifiedModuleName{dir, moduleName}
@@ -499,7 +563,7 @@
 	// Modules are implicitly visible to other modules in the same package,
 	// without checking the visibility rules. Here we need to add that visibility
 	// explicitly.
-	if rule != nil && !rule.matches(qualified) {
+	if !rule.matches(qualified) {
 		if len(rule) == 1 {
 			if _, ok := rule[0].(privateRule); ok {
 				// If the rule is //visibility:private we can't append another
@@ -508,13 +572,13 @@
 				// modules are implicitly visible within the package we get the same
 				// result without any rule at all, so just make it an empty list to be
 				// appended below.
-				rule = compositeRule{}
+				rule = nil
 			}
 		}
 		rule = append(rule, packageRule{dir})
 	}
 
-	return rule.Strings()
+	return &visibilityRuleSet{rule.Strings()}
 }
 
 // Clear the default visibility properties so they can be replaced.
diff --git a/android/visibility_test.go b/android/visibility_test.go
index ca09345..8de5fa9 100644
--- a/android/visibility_test.go
+++ b/android/visibility_test.go
@@ -1140,6 +1140,7 @@
 }
 
 func TestVisibility(t *testing.T) {
+	t.Parallel()
 	for _, test := range visibilityTests {
 		t.Run(test.name, func(t *testing.T) {
 			ctx, errs := testVisibility(buildDir, test.fs)
@@ -1270,3 +1271,49 @@
 	})
 	return m
 }
+
+func testVisibilityRuleSet(t *testing.T, rules, extra, expected []string) {
+	t.Helper()
+	set := &visibilityRuleSet{rules}
+	err := set.Widen(extra)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	actual := set.Strings()
+	if !reflect.DeepEqual(actual, expected) {
+		t.Errorf("mismatching rules after extend: expected %#v, actual %#v", expected, actual)
+	}
+}
+
+func TestVisibilityRuleSet(t *testing.T) {
+	t.Run("extend empty", func(t *testing.T) {
+		testVisibilityRuleSet(t, nil, []string{"//foo"}, []string{"//foo"})
+	})
+	t.Run("extend", func(t *testing.T) {
+		testVisibilityRuleSet(t, []string{"//foo"}, []string{"//bar"}, []string{"//bar", "//foo"})
+	})
+	t.Run("extend duplicate", func(t *testing.T) {
+		testVisibilityRuleSet(t, []string{"//foo"}, []string{"//bar", "//foo"}, []string{"//bar", "//foo"})
+	})
+	t.Run("extend public", func(t *testing.T) {
+		testVisibilityRuleSet(t, []string{"//visibility:public"}, []string{"//foo"}, []string{"//visibility:public"})
+	})
+	t.Run("extend private", func(t *testing.T) {
+		testVisibilityRuleSet(t, []string{"//visibility:private"}, []string{"//foo"}, []string{"//foo"})
+	})
+	t.Run("extend with public", func(t *testing.T) {
+		testVisibilityRuleSet(t, []string{"//foo"}, []string{"//visibility:public"}, []string{"//visibility:public"})
+	})
+	t.Run("extend with private", func(t *testing.T) {
+		t.Helper()
+		set := &visibilityRuleSet{[]string{"//foo"}}
+		err := set.Widen([]string{"//visibility:private"})
+		expectedError := `"//visibility:private" does not widen the visibility`
+		if err == nil {
+			t.Errorf("missing error")
+		} else if err.Error() != expectedError {
+			t.Errorf("expected error %q found error %q", expectedError, err)
+		}
+	})
+}
diff --git a/android/vts_config_test.go b/android/vts_config_test.go
index 254fa92..a95e589 100644
--- a/android/vts_config_test.go
+++ b/android/vts_config_test.go
@@ -32,6 +32,7 @@
 }
 
 func TestVtsConfig(t *testing.T) {
+	t.Parallel()
 	ctx := testVtsConfig(t, `
 vts_config { name: "plain"}
 vts_config { name: "with_manifest", test_config: "manifest.xml" }
diff --git a/androidmk/androidmk/androidmk_test.go b/androidmk/androidmk/androidmk_test.go
index 2448acc..560ea13 100644
--- a/androidmk/androidmk/androidmk_test.go
+++ b/androidmk/androidmk/androidmk_test.go
@@ -1462,6 +1462,7 @@
 }
 
 func TestEndToEnd(t *testing.T) {
+	t.Parallel()
 	for i, test := range testCases {
 		expected, err := bpfix.Reformat(test.expected)
 		if err != nil {
diff --git a/androidmk/parser/make_strings_test.go b/androidmk/parser/make_strings_test.go
index 6995e89..9622068 100644
--- a/androidmk/parser/make_strings_test.go
+++ b/androidmk/parser/make_strings_test.go
@@ -89,6 +89,7 @@
 }
 
 func TestMakeStringSplitN(t *testing.T) {
+	t.Parallel()
 	for _, test := range splitNTestCases {
 		got := test.in.SplitN(test.sep, test.n)
 		gotString := dumpArray(got)
@@ -118,6 +119,7 @@
 }
 
 func TestMakeStringValue(t *testing.T) {
+	t.Parallel()
 	for _, test := range valueTestCases {
 		got := test.in.Value(nil)
 		if got != test.expected {
@@ -161,6 +163,7 @@
 }
 
 func TestMakeStringWords(t *testing.T) {
+	t.Parallel()
 	for _, test := range splitWordsTestCases {
 		got := test.in.Words()
 		gotString := dumpArray(got)
diff --git a/androidmk/parser/parser_test.go b/androidmk/parser/parser_test.go
index f562c29..7c05a0c 100644
--- a/androidmk/parser/parser_test.go
+++ b/androidmk/parser/parser_test.go
@@ -37,6 +37,7 @@
 }
 
 func TestParse(t *testing.T) {
+	t.Parallel()
 	for _, test := range parserTestCases {
 		t.Run(test.name, func(t *testing.T) {
 			p := NewParser(test.name, bytes.NewBufferString(test.in))
diff --git a/apex/OWNERS b/apex/OWNERS
index a382ae8..793f3ed 100644
--- a/apex/OWNERS
+++ b/apex/OWNERS
@@ -1 +1,4 @@
-per-file * = jiyong@google.com
\ No newline at end of file
+per-file * = jiyong@google.com
+
+per-file allowed_deps.txt = set noparent
+per-file allowed_deps.txt = dariofreni@google.com,hansson@google.com,harpin@google.com,jiyong@google.com,narayan@google.com,omakoto@google.com,jham@google.com
diff --git a/apex/allowed_deps.txt b/apex/allowed_deps.txt
new file mode 100644
index 0000000..87e96ea
--- /dev/null
+++ b/apex/allowed_deps.txt
@@ -0,0 +1,521 @@
+# A list of allowed dependencies for all updatable modules.
+#
+# The list tracks all direct and transitive dependencies that end up within any
+# of the updatable binaries; specifically excluding external dependencies
+# required to compile those binaries. This prevents potential regressions in
+# case a new dependency is not aware of the different functional and
+# non-functional requirements being part of an updatable module, for example
+# setting correct min_sdk_version.
+#
+# To update the list, run:
+# repo-root$ build/soong/scripts/update-apex-allowed-deps.sh
+#
+# See go/apex-allowed-deps-error for more details.
+# TODO(b/157465465): introduce automated quality signals and remove this list.
+
+adbd(minSdkVersion:(no version))
+android.hardware.cas.native@1.0(minSdkVersion:29)
+android.hardware.cas@1.0(minSdkVersion:29)
+android.hardware.common-ndk_platform(minSdkVersion:29)
+android.hardware.graphics.allocator@2.0(minSdkVersion:29)
+android.hardware.graphics.allocator@3.0(minSdkVersion:29)
+android.hardware.graphics.allocator@4.0(minSdkVersion:29)
+android.hardware.graphics.bufferqueue@1.0(minSdkVersion:29)
+android.hardware.graphics.bufferqueue@2.0(minSdkVersion:29)
+android.hardware.graphics.common-ndk_platform(minSdkVersion:29)
+android.hardware.graphics.common@1.0(minSdkVersion:29)
+android.hardware.graphics.common@1.1(minSdkVersion:29)
+android.hardware.graphics.common@1.2(minSdkVersion:29)
+android.hardware.graphics.mapper@2.0(minSdkVersion:29)
+android.hardware.graphics.mapper@2.1(minSdkVersion:29)
+android.hardware.graphics.mapper@3.0(minSdkVersion:29)
+android.hardware.graphics.mapper@4.0(minSdkVersion:29)
+android.hardware.media.bufferpool@2.0(minSdkVersion:29)
+android.hardware.media.c2@1.0(minSdkVersion:29)
+android.hardware.media.c2@1.1(minSdkVersion:29)
+android.hardware.media.omx@1.0(minSdkVersion:29)
+android.hardware.media@1.0(minSdkVersion:29)
+android.hardware.neuralnetworks@1.0(minSdkVersion:30)
+android.hardware.neuralnetworks@1.1(minSdkVersion:30)
+android.hardware.neuralnetworks@1.2(minSdkVersion:30)
+android.hardware.neuralnetworks@1.3(minSdkVersion:30)
+android.hardware.tetheroffload.config-V1.0-java(minSdkVersion:current)
+android.hardware.tetheroffload.control-V1.0-java(minSdkVersion:current)
+android.hidl.allocator@1.0(minSdkVersion:29)
+android.hidl.base-V1.0-java(minSdkVersion:current)
+android.hidl.memory.token@1.0(minSdkVersion:29)
+android.hidl.memory@1.0(minSdkVersion:29)
+android.hidl.safe_union@1.0(minSdkVersion:29)
+android.hidl.token@1.0(minSdkVersion:29)
+android.hidl.token@1.0-utils(minSdkVersion:29)
+android.net.ipsec.ike(minSdkVersion:current)
+android.net.ipsec.ike.xml(minSdkVersion:(no version))
+androidx-constraintlayout_constraintlayout(minSdkVersion:14)
+androidx-constraintlayout_constraintlayout-solver(minSdkVersion:24)
+androidx.activity_activity(minSdkVersion:14)
+androidx.activity_activity-ktx(minSdkVersion:14)
+androidx.annotation_annotation(minSdkVersion:24)
+androidx.annotation_annotation(minSdkVersion:current)
+androidx.appcompat_appcompat(minSdkVersion:14)
+androidx.appcompat_appcompat-resources(minSdkVersion:14)
+androidx.arch.core_core-common(minSdkVersion:24)
+androidx.arch.core_core-common(minSdkVersion:current)
+androidx.arch.core_core-runtime(minSdkVersion:14)
+androidx.asynclayoutinflater_asynclayoutinflater(minSdkVersion:14)
+androidx.autofill_autofill(minSdkVersion:14)
+androidx.cardview_cardview(minSdkVersion:14)
+androidx.collection_collection(minSdkVersion:24)
+androidx.collection_collection(minSdkVersion:current)
+androidx.collection_collection-ktx(minSdkVersion:24)
+androidx.coordinatorlayout_coordinatorlayout(minSdkVersion:14)
+androidx.core_core(minSdkVersion:14)
+androidx.core_core-ktx(minSdkVersion:14)
+androidx.cursoradapter_cursoradapter(minSdkVersion:14)
+androidx.customview_customview(minSdkVersion:14)
+androidx.documentfile_documentfile(minSdkVersion:14)
+androidx.drawerlayout_drawerlayout(minSdkVersion:14)
+androidx.fragment_fragment(minSdkVersion:14)
+androidx.fragment_fragment-ktx(minSdkVersion:14)
+androidx.interpolator_interpolator(minSdkVersion:14)
+androidx.leanback_leanback(minSdkVersion:17)
+androidx.leanback_leanback-preference(minSdkVersion:21)
+androidx.legacy_legacy-preference-v14(minSdkVersion:14)
+androidx.legacy_legacy-support-core-ui(minSdkVersion:14)
+androidx.legacy_legacy-support-core-utils(minSdkVersion:14)
+androidx.legacy_legacy-support-v13(minSdkVersion:14)
+androidx.legacy_legacy-support-v4(minSdkVersion:14)
+androidx.lifecycle_lifecycle-common(minSdkVersion:24)
+androidx.lifecycle_lifecycle-common(minSdkVersion:current)
+androidx.lifecycle_lifecycle-common-java8(minSdkVersion:24)
+androidx.lifecycle_lifecycle-extensions(minSdkVersion:14)
+androidx.lifecycle_lifecycle-livedata(minSdkVersion:14)
+androidx.lifecycle_lifecycle-livedata-core(minSdkVersion:14)
+androidx.lifecycle_lifecycle-livedata-core-ktx(minSdkVersion:14)
+androidx.lifecycle_lifecycle-process(minSdkVersion:14)
+androidx.lifecycle_lifecycle-runtime(minSdkVersion:14)
+androidx.lifecycle_lifecycle-runtime-ktx(minSdkVersion:14)
+androidx.lifecycle_lifecycle-service(minSdkVersion:14)
+androidx.lifecycle_lifecycle-viewmodel(minSdkVersion:14)
+androidx.lifecycle_lifecycle-viewmodel-ktx(minSdkVersion:14)
+androidx.lifecycle_lifecycle-viewmodel-savedstate(minSdkVersion:14)
+androidx.loader_loader(minSdkVersion:14)
+androidx.localbroadcastmanager_localbroadcastmanager(minSdkVersion:14)
+androidx.media_media(minSdkVersion:14)
+androidx.navigation_navigation-common(minSdkVersion:14)
+androidx.navigation_navigation-common-ktx(minSdkVersion:14)
+androidx.navigation_navigation-fragment(minSdkVersion:14)
+androidx.navigation_navigation-fragment-ktx(minSdkVersion:14)
+androidx.navigation_navigation-runtime(minSdkVersion:14)
+androidx.navigation_navigation-runtime-ktx(minSdkVersion:14)
+androidx.navigation_navigation-ui(minSdkVersion:14)
+androidx.navigation_navigation-ui-ktx(minSdkVersion:14)
+androidx.preference_preference(minSdkVersion:14)
+androidx.print_print(minSdkVersion:14)
+androidx.recyclerview_recyclerview(minSdkVersion:14)
+androidx.recyclerview_recyclerview-selection(minSdkVersion:14)
+androidx.savedstate_savedstate(minSdkVersion:14)
+androidx.slidingpanelayout_slidingpanelayout(minSdkVersion:14)
+androidx.swiperefreshlayout_swiperefreshlayout(minSdkVersion:14)
+androidx.transition_transition(minSdkVersion:14)
+androidx.vectordrawable_vectordrawable(minSdkVersion:14)
+androidx.vectordrawable_vectordrawable-animated(minSdkVersion:14)
+androidx.versionedparcelable_versionedparcelable(minSdkVersion:14)
+androidx.viewpager_viewpager(minSdkVersion:14)
+apache-commons-compress(minSdkVersion:current)
+art.module.public.api.stubs(minSdkVersion:(no version))
+bcm_object(minSdkVersion:29)
+boringssl_self_test(minSdkVersion:29)
+bouncycastle_ike_digests(minSdkVersion:current)
+brotli-java(minSdkVersion:current)
+captiveportal-lib(minSdkVersion:29)
+car-ui-lib(minSdkVersion:28)
+CellBroadcastApp(minSdkVersion:29)
+CellBroadcastServiceModule(minSdkVersion:29)
+codecs_g711dec(minSdkVersion:29)
+com.google.android.material_material(minSdkVersion:14)
+conscrypt(minSdkVersion:29)
+conscrypt.module.platform.api.stubs(minSdkVersion:(no version))
+conscrypt.module.public.api.stubs(minSdkVersion:(no version))
+core-lambda-stubs(minSdkVersion:(no version))
+core.current.stubs(minSdkVersion:(no version))
+crtbegin_dynamic(minSdkVersion:apex_inherit)
+crtbegin_dynamic1(minSdkVersion:apex_inherit)
+crtbegin_so(minSdkVersion:apex_inherit)
+crtbegin_so1(minSdkVersion:apex_inherit)
+crtbrand(minSdkVersion:apex_inherit)
+crtend_android(minSdkVersion:apex_inherit)
+crtend_so(minSdkVersion:apex_inherit)
+datastallprotosnano(minSdkVersion:29)
+derive_sdk(minSdkVersion:current)
+derive_sdk_prefer32(minSdkVersion:current)
+dnsresolver_aidl_interface-unstable-ndk_platform(minSdkVersion:29)
+DocumentsUI-res-lib(minSdkVersion:29)
+exoplayer2-extractor(minSdkVersion:16)
+exoplayer2-extractor-annotation-stubs(minSdkVersion:16)
+ExtServices(minSdkVersion:current)
+ExtServices-core(minSdkVersion:current)
+flatbuffer_headers(minSdkVersion:(no version))
+fmtlib(minSdkVersion:29)
+framework-permission(minSdkVersion:current)
+framework-sdkextensions(minSdkVersion:current)
+framework-statsd(minSdkVersion:current)
+framework-tethering(minSdkVersion:current)
+gemmlowp_headers(minSdkVersion:(no version))
+GoogleCellBroadcastApp(minSdkVersion:29)
+GoogleCellBroadcastServiceModule(minSdkVersion:29)
+GoogleExtServices(minSdkVersion:current)
+GooglePermissionController(minSdkVersion:28)
+guava(minSdkVersion:current)
+gwp_asan_headers(minSdkVersion:(no version))
+i18n.module.public.api.stubs(minSdkVersion:(no version))
+iconloader(minSdkVersion:21)
+ike-internals(minSdkVersion:current)
+InProcessTethering(minSdkVersion:current)
+ipmemorystore-aidl-interfaces-java(minSdkVersion:29)
+ipmemorystore-aidl-interfaces-unstable-java(minSdkVersion:29)
+jni_headers(minSdkVersion:29)
+jsr305(minSdkVersion:14)
+kotlinx-coroutines-android(minSdkVersion:current)
+kotlinx-coroutines-core(minSdkVersion:current)
+legacy.art.module.platform.api.stubs(minSdkVersion:(no version))
+legacy.core.platform.api.stubs(minSdkVersion:(no version))
+legacy.i18n.module.platform.api.stubs(minSdkVersion:(no version))
+libaacextractor(minSdkVersion:29)
+libadb_crypto(minSdkVersion:(no version))
+libadb_pairing_auth(minSdkVersion:(no version))
+libadb_pairing_connection(minSdkVersion:(no version))
+libadb_pairing_server(minSdkVersion:(no version))
+libadb_protos(minSdkVersion:(no version))
+libadb_tls_connection(minSdkVersion:(no version))
+libadbconnection_client(minSdkVersion:(no version))
+libadbconnection_server(minSdkVersion:(no version))
+libadbd(minSdkVersion:(no version))
+libadbd_core(minSdkVersion:(no version))
+libadbd_services(minSdkVersion:(no version))
+libamrextractor(minSdkVersion:29)
+libapp_processes_protos_lite(minSdkVersion:(no version))
+libarect(minSdkVersion:29)
+libasyncio(minSdkVersion:(no version))
+libatomic(minSdkVersion:(no version))
+libaudio_system_headers(minSdkVersion:29)
+libaudioclient_headers(minSdkVersion:29)
+libaudiofoundation_headers(minSdkVersion:29)
+libaudioutils(minSdkVersion:29)
+libaudioutils_fixedfft(minSdkVersion:29)
+libavcdec(minSdkVersion:29)
+libavcenc(minSdkVersion:29)
+libavservices_minijail(minSdkVersion:29)
+libbacktrace_headers(minSdkVersion:apex_inherit)
+libbase(minSdkVersion:29)
+libbase_headers(minSdkVersion:29)
+libbinder_headers(minSdkVersion:29)
+libbinderthreadstateutils(minSdkVersion:29)
+libbluetooth-types-header(minSdkVersion:29)
+libbrotli(minSdkVersion:(no version))
+libbuildversion(minSdkVersion:(no version))
+libc(minSdkVersion:(no version))
+libc++(minSdkVersion:apex_inherit)
+libc++_static(minSdkVersion:apex_inherit)
+libc++abi(minSdkVersion:apex_inherit)
+libc++demangle(minSdkVersion:apex_inherit)
+libc_headers(minSdkVersion:apex_inherit)
+libc_headers_arch(minSdkVersion:apex_inherit)
+libcap(minSdkVersion:29)
+libcodec2(minSdkVersion:29)
+libcodec2_headers(minSdkVersion:29)
+libcodec2_hidl@1.0(minSdkVersion:29)
+libcodec2_hidl@1.1(minSdkVersion:29)
+libcodec2_internal(minSdkVersion:29)
+libcodec2_soft_aacdec(minSdkVersion:29)
+libcodec2_soft_aacenc(minSdkVersion:29)
+libcodec2_soft_amrnbdec(minSdkVersion:29)
+libcodec2_soft_amrnbenc(minSdkVersion:29)
+libcodec2_soft_amrwbdec(minSdkVersion:29)
+libcodec2_soft_amrwbenc(minSdkVersion:29)
+libcodec2_soft_av1dec_gav1(minSdkVersion:29)
+libcodec2_soft_avcdec(minSdkVersion:29)
+libcodec2_soft_avcenc(minSdkVersion:29)
+libcodec2_soft_common(minSdkVersion:29)
+libcodec2_soft_flacdec(minSdkVersion:29)
+libcodec2_soft_flacenc(minSdkVersion:29)
+libcodec2_soft_g711alawdec(minSdkVersion:29)
+libcodec2_soft_g711mlawdec(minSdkVersion:29)
+libcodec2_soft_gsmdec(minSdkVersion:29)
+libcodec2_soft_h263dec(minSdkVersion:29)
+libcodec2_soft_h263enc(minSdkVersion:29)
+libcodec2_soft_hevcdec(minSdkVersion:29)
+libcodec2_soft_hevcenc(minSdkVersion:29)
+libcodec2_soft_mp3dec(minSdkVersion:29)
+libcodec2_soft_mpeg2dec(minSdkVersion:29)
+libcodec2_soft_mpeg4dec(minSdkVersion:29)
+libcodec2_soft_mpeg4enc(minSdkVersion:29)
+libcodec2_soft_opusdec(minSdkVersion:29)
+libcodec2_soft_opusenc(minSdkVersion:29)
+libcodec2_soft_rawdec(minSdkVersion:29)
+libcodec2_soft_vorbisdec(minSdkVersion:29)
+libcodec2_soft_vp8dec(minSdkVersion:29)
+libcodec2_soft_vp8enc(minSdkVersion:29)
+libcodec2_soft_vp9dec(minSdkVersion:29)
+libcodec2_soft_vp9enc(minSdkVersion:29)
+libcodec2_vndk(minSdkVersion:29)
+libcrypto(minSdkVersion:29)
+libcrypto_static(minSdkVersion:(no version))
+libcrypto_utils(minSdkVersion:(no version))
+libcutils(minSdkVersion:29)
+libcutils_headers(minSdkVersion:29)
+libcutils_sockets(minSdkVersion:29)
+libdiagnose_usb(minSdkVersion:(no version))
+libdl(minSdkVersion:(no version))
+libeigen(minSdkVersion:(no version))
+libfifo(minSdkVersion:29)
+libFLAC(minSdkVersion:29)
+libFLAC-config(minSdkVersion:29)
+libFLAC-headers(minSdkVersion:29)
+libflacextractor(minSdkVersion:29)
+libfmq(minSdkVersion:29)
+libFraunhoferAAC(minSdkVersion:29)
+libgav1(minSdkVersion:29)
+libgcc_stripped(minSdkVersion:(no version))
+libgralloctypes(minSdkVersion:29)
+libgrallocusage(minSdkVersion:29)
+libgsm(minSdkVersion:apex_inherit)
+libgtest_prod(minSdkVersion:apex_inherit)
+libgui_bufferqueue_static(minSdkVersion:29)
+libgui_headers(minSdkVersion:29)
+libhardware(minSdkVersion:29)
+libhardware_headers(minSdkVersion:29)
+libhevcdec(minSdkVersion:29)
+libhevcenc(minSdkVersion:29)
+libhidlbase(minSdkVersion:29)
+libhidlmemory(minSdkVersion:29)
+libhwbinder-impl-internal(minSdkVersion:29)
+libion(minSdkVersion:29)
+libjavacrypto(minSdkVersion:29)
+libjsoncpp(minSdkVersion:29)
+libLibGuiProperties(minSdkVersion:29)
+liblog(minSdkVersion:(no version))
+liblog_headers(minSdkVersion:29)
+liblua(minSdkVersion:(no version))
+liblz4(minSdkVersion:(no version))
+libm(minSdkVersion:(no version))
+libmath(minSdkVersion:29)
+libmdnssd(minSdkVersion:(no version))
+libmedia_codecserviceregistrant(minSdkVersion:29)
+libmedia_datasource_headers(minSdkVersion:29)
+libmedia_headers(minSdkVersion:29)
+libmedia_helper_headers(minSdkVersion:29)
+libmedia_midiiowrapper(minSdkVersion:29)
+libmidiextractor(minSdkVersion:29)
+libminijail(minSdkVersion:29)
+libminijail_gen_constants(minSdkVersion:(no version))
+libminijail_gen_constants_obj(minSdkVersion:29)
+libminijail_gen_syscall(minSdkVersion:(no version))
+libminijail_gen_syscall_obj(minSdkVersion:29)
+libminijail_generated(minSdkVersion:29)
+libmkvextractor(minSdkVersion:29)
+libmp3extractor(minSdkVersion:29)
+libmp4extractor(minSdkVersion:29)
+libmpeg2dec(minSdkVersion:29)
+libmpeg2extractor(minSdkVersion:29)
+libnativebase_headers(minSdkVersion:29)
+libnativehelper_compat_libc++(minSdkVersion:(no version))
+libnativehelper_header_only(minSdkVersion:29)
+libnativewindow_headers(minSdkVersion:29)
+libnetd_resolv(minSdkVersion:29)
+libnetdbinder_utils_headers(minSdkVersion:29)
+libnetdutils(minSdkVersion:29)
+libnetworkstackutilsjni(minSdkVersion:29)
+libneuralnetworks(minSdkVersion:(no version))
+libneuralnetworks_common(minSdkVersion:(no version))
+libneuralnetworks_headers(minSdkVersion:(no version))
+liboggextractor(minSdkVersion:29)
+libopus(minSdkVersion:29)
+libprocessgroup(minSdkVersion:29)
+libprocessgroup_headers(minSdkVersion:29)
+libprocpartition(minSdkVersion:(no version))
+libprotobuf-cpp-lite(minSdkVersion:29)
+libprotobuf-java-lite(minSdkVersion:current)
+libprotobuf-java-nano(minSdkVersion:9)
+libprotoutil(minSdkVersion:(no version))
+libqemu_pipe(minSdkVersion:(no version))
+libsfplugin_ccodec_utils(minSdkVersion:29)
+libsonivoxwithoutjet(minSdkVersion:29)
+libspeexresampler(minSdkVersion:29)
+libssl(minSdkVersion:29)
+libstagefright_amrnb_common(minSdkVersion:29)
+libstagefright_amrnbdec(minSdkVersion:29)
+libstagefright_amrnbenc(minSdkVersion:29)
+libstagefright_amrwbdec(minSdkVersion:29)
+libstagefright_amrwbenc(minSdkVersion:29)
+libstagefright_bufferpool@2.0.1(minSdkVersion:29)
+libstagefright_bufferqueue_helper(minSdkVersion:29)
+libstagefright_enc_common(minSdkVersion:29)
+libstagefright_esds(minSdkVersion:29)
+libstagefright_flacdec(minSdkVersion:29)
+libstagefright_foundation(minSdkVersion:29)
+libstagefright_foundation_headers(minSdkVersion:29)
+libstagefright_foundation_without_imemory(minSdkVersion:29)
+libstagefright_headers(minSdkVersion:29)
+libstagefright_id3(minSdkVersion:29)
+libstagefright_m4vh263dec(minSdkVersion:29)
+libstagefright_m4vh263enc(minSdkVersion:29)
+libstagefright_metadatautils(minSdkVersion:29)
+libstagefright_mp3dec(minSdkVersion:29)
+libstagefright_mpeg2extractor(minSdkVersion:29)
+libstagefright_mpeg2support_nocrypto(minSdkVersion:29)
+libstats_jni(minSdkVersion:(no version))
+libstatslog_resolv(minSdkVersion:29)
+libstatslog_statsd(minSdkVersion:(no version))
+libstatspull(minSdkVersion:(no version))
+libstatspush_compat(minSdkVersion:29)
+libstatssocket(minSdkVersion:(no version))
+libstatssocket_headers(minSdkVersion:29)
+libsystem_headers(minSdkVersion:apex_inherit)
+libsysutils(minSdkVersion:apex_inherit)
+libtetherutilsjni(minSdkVersion:current)
+libtextclassifier(minSdkVersion:(no version))
+libtextclassifier-java(minSdkVersion:current)
+libtextclassifier_hash_headers(minSdkVersion:(no version))
+libtextclassifier_hash_static(minSdkVersion:(no version))
+libtflite_kernel_utils(minSdkVersion:(no version))
+libtflite_static(minSdkVersion:(no version))
+libui(minSdkVersion:29)
+libui_headers(minSdkVersion:29)
+libunwind_llvm(minSdkVersion:apex_inherit)
+libutf(minSdkVersion:(no version))
+libutils(minSdkVersion:apex_inherit)
+libutils_headers(minSdkVersion:apex_inherit)
+libvorbisidec(minSdkVersion:29)
+libvpx(minSdkVersion:29)
+libwatchdog(minSdkVersion:29)
+libwavextractor(minSdkVersion:29)
+libwebm(minSdkVersion:29)
+libyuv(minSdkVersion:29)
+libyuv_static(minSdkVersion:29)
+libzstd(minSdkVersion:(no version))
+media_ndk_headers(minSdkVersion:29)
+media_plugin_headers(minSdkVersion:29)
+mediaswcodec(minSdkVersion:29)
+metrics-constants-protos(minSdkVersion:29)
+ndk_crtbegin_so.19(minSdkVersion:(no version))
+ndk_crtbegin_so.21(minSdkVersion:(no version))
+ndk_crtbegin_so.27(minSdkVersion:(no version))
+ndk_crtend_so.19(minSdkVersion:(no version))
+ndk_crtend_so.21(minSdkVersion:(no version))
+ndk_crtend_so.27(minSdkVersion:(no version))
+ndk_libc++_static(minSdkVersion:(no version))
+ndk_libc++abi(minSdkVersion:(no version))
+net-utils-framework-common(minSdkVersion:current)
+netd_aidl_interface-unstable-java(minSdkVersion:29)
+netd_event_listener_interface-ndk_platform(minSdkVersion:29)
+netlink-client(minSdkVersion:29)
+networkstack-aidl-interfaces-unstable-java(minSdkVersion:29)
+networkstack-client(minSdkVersion:29)
+NetworkStackApiStableDependencies(minSdkVersion:29)
+NetworkStackApiStableLib(minSdkVersion:29)
+networkstackprotos(minSdkVersion:29)
+PermissionController(minSdkVersion:28)
+permissioncontroller-statsd(minSdkVersion:current)
+philox_random(minSdkVersion:(no version))
+philox_random_headers(minSdkVersion:(no version))
+prebuilt_androidx-constraintlayout_constraintlayout-nodeps(minSdkVersion:(no version))
+prebuilt_androidx-constraintlayout_constraintlayout-solver-nodeps(minSdkVersion:current)
+prebuilt_androidx.activity_activity-ktx-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.activity_activity-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.annotation_annotation-nodeps(minSdkVersion:current)
+prebuilt_androidx.appcompat_appcompat-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.appcompat_appcompat-resources-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.arch.core_core-common-nodeps(minSdkVersion:current)
+prebuilt_androidx.arch.core_core-runtime-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.asynclayoutinflater_asynclayoutinflater-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.autofill_autofill-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.cardview_cardview-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.collection_collection-ktx-nodeps(minSdkVersion:current)
+prebuilt_androidx.collection_collection-nodeps(minSdkVersion:current)
+prebuilt_androidx.coordinatorlayout_coordinatorlayout-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.core_core-ktx-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.core_core-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.cursoradapter_cursoradapter-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.customview_customview-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.documentfile_documentfile-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.drawerlayout_drawerlayout-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.fragment_fragment-ktx-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.fragment_fragment-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.interpolator_interpolator-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.leanback_leanback-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.leanback_leanback-preference-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.legacy_legacy-support-core-ui-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.legacy_legacy-support-core-utils-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.legacy_legacy-support-v13-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.lifecycle_lifecycle-common-java8-nodeps(minSdkVersion:current)
+prebuilt_androidx.lifecycle_lifecycle-common-nodeps(minSdkVersion:current)
+prebuilt_androidx.lifecycle_lifecycle-extensions-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.lifecycle_lifecycle-livedata-core-ktx-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.lifecycle_lifecycle-livedata-core-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.lifecycle_lifecycle-livedata-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.lifecycle_lifecycle-process-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.lifecycle_lifecycle-runtime-ktx-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.lifecycle_lifecycle-runtime-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.lifecycle_lifecycle-service-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.lifecycle_lifecycle-viewmodel-ktx-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.lifecycle_lifecycle-viewmodel-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.lifecycle_lifecycle-viewmodel-savedstate-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.loader_loader-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.localbroadcastmanager_localbroadcastmanager-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.media_media-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.navigation_navigation-common-ktx-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.navigation_navigation-common-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.navigation_navigation-fragment-ktx-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.navigation_navigation-fragment-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.navigation_navigation-runtime-ktx-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.navigation_navigation-runtime-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.navigation_navigation-ui-ktx-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.navigation_navigation-ui-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.preference_preference-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.print_print-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.recyclerview_recyclerview-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.recyclerview_recyclerview-selection-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.savedstate_savedstate-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.slidingpanelayout_slidingpanelayout-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.swiperefreshlayout_swiperefreshlayout-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.transition_transition-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.vectordrawable_vectordrawable-animated-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.vectordrawable_vectordrawable-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.versionedparcelable_versionedparcelable-nodeps(minSdkVersion:(no version))
+prebuilt_androidx.viewpager_viewpager-nodeps(minSdkVersion:(no version))
+prebuilt_com.google.android.material_material-nodeps(minSdkVersion:(no version))
+prebuilt_error_prone_annotations(minSdkVersion:(no version))
+prebuilt_kotlin-stdlib(minSdkVersion:current)
+prebuilt_kotlinx-coroutines-android-nodeps(minSdkVersion:(no version))
+prebuilt_kotlinx-coroutines-core-nodeps(minSdkVersion:(no version))
+prebuilt_libclang_rt.builtins-aarch64-android(minSdkVersion:(no version))
+prebuilt_libclang_rt.builtins-arm-android(minSdkVersion:(no version))
+prebuilt_libclang_rt.builtins-i686-android(minSdkVersion:(no version))
+prebuilt_libclang_rt.builtins-x86_64-android(minSdkVersion:(no version))
+prebuilt_test_framework-sdkextensions(minSdkVersion:(no version))
+server_configurable_flags(minSdkVersion:29)
+service-permission(minSdkVersion:current)
+service-statsd(minSdkVersion:current)
+SettingsLibActionBarShadow(minSdkVersion:21)
+SettingsLibAppPreference(minSdkVersion:21)
+SettingsLibBarChartPreference(minSdkVersion:21)
+SettingsLibHelpUtils(minSdkVersion:21)
+SettingsLibLayoutPreference(minSdkVersion:21)
+SettingsLibProgressBar(minSdkVersion:21)
+SettingsLibRestrictedLockUtils(minSdkVersion:21)
+SettingsLibSearchWidget(minSdkVersion:21)
+SettingsLibSettingsTheme(minSdkVersion:21)
+SettingsLibUtils(minSdkVersion:21)
+stats_proto(minSdkVersion:29)
+statsd(minSdkVersion:(no version))
+statsd-aidl-ndk_platform(minSdkVersion:(no version))
+statsprotos(minSdkVersion:29)
+tensorflow_headers(minSdkVersion:(no version))
+Tethering(minSdkVersion:current)
+TetheringApiCurrentLib(minSdkVersion:current)
+TetheringGoogle(minSdkVersion:current)
+textclassifier-statsd(minSdkVersion:current)
+TextClassifierNotificationLibNoManifest(minSdkVersion:29)
+TextClassifierServiceLibNoManifest(minSdkVersion:28)
+updatable-media(minSdkVersion:29)
+xz-java(minSdkVersion:current)
diff --git a/apex/androidmk.go b/apex/androidmk.go
index c4fe3a3..ee8b2b3 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -135,7 +135,7 @@
 				}
 			}
 			if len(newDataPaths) > 0 {
-				fmt.Fprintln(w, "LOCAL_TEST_DATA :=", strings.Join(cc.AndroidMkDataPaths(newDataPaths), " "))
+				fmt.Fprintln(w, "LOCAL_TEST_DATA :=", strings.Join(android.AndroidMkDataPaths(newDataPaths), " "))
 			}
 
 			if fi.module != nil && len(fi.module.NoticeFiles()) > 0 {
@@ -264,6 +264,10 @@
 						postInstallCommands = append(postInstallCommands, a.compatSymlinks...)
 					}
 				}
+
+				// File_contexts of flattened APEXes should be merged into file_contexts.bin
+				fmt.Fprintln(w, "LOCAL_FILE_CONTEXTS :=", a.fileContexts)
+
 				if len(postInstallCommands) > 0 {
 					fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", strings.Join(postInstallCommands, " && "))
 				}
diff --git a/apex/apex.go b/apex/apex.go
index e8294a8..a9a58a6 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -19,7 +19,6 @@
 	"path/filepath"
 	"sort"
 	"strings"
-	"sync"
 
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/bootstrap"
@@ -68,6 +67,7 @@
 	androidAppTag  = dependencyTag{name: "androidApp", payload: true}
 	rroTag         = dependencyTag{name: "rro", payload: true}
 	bpfTag         = dependencyTag{name: "bpf", payload: true}
+	testForTag     = dependencyTag{name: "test for"}
 
 	apexAvailBaseline = makeApexAvailableBaseline()
 
@@ -565,7 +565,6 @@
 		"libdebuggerd_handler_fallback",
 		"libdexfile_external_headers",
 		"libdexfile_support",
-		"libdexfile_support_static",
 		"libdl_static",
 		"libjemalloc5",
 		"liblinker_main",
@@ -744,12 +743,6 @@
 	android.PreDepsMutators(RegisterPreDepsMutators)
 	android.PostDepsMutators(RegisterPostDepsMutators)
 
-	android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
-		apexFileContextsInfos := apexFileContextsInfos(ctx.Config())
-		sort.Strings(*apexFileContextsInfos)
-		ctx.Strict("APEX_FILE_CONTEXTS_INFOS", strings.Join(*apexFileContextsInfos, " "))
-	})
-
 	android.AddNeverAllowRules(createApexPermittedPackagesRules(qModulesPackages())...)
 	android.AddNeverAllowRules(createApexPermittedPackagesRules(rModulesPackages())...)
 }
@@ -777,7 +770,10 @@
 func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
 	ctx.TopDown("apex_deps", apexDepsMutator).Parallel()
 	ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
+	ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator).Parallel()
+	ctx.BottomUp("apex_test_for", apexTestForMutator).Parallel()
 	ctx.BottomUp("apex", apexMutator).Parallel()
+	ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
 	ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
 	ctx.BottomUp("apex_uses", apexUsesMutator).Parallel()
 	ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
@@ -793,13 +789,6 @@
 	if !ok || a.vndkApex {
 		return
 	}
-	apexInfo := android.ApexInfo{
-		ApexVariationName: mctx.ModuleName(),
-		MinSdkVersionStr:  a.minSdkVersion(mctx).String(),
-		RequiredSdks:      a.RequiredSdks(),
-		Updatable:         a.Updatable(),
-		InApexes:          []string{mctx.ModuleName()},
-	}
 
 	useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
 	excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
@@ -808,7 +797,9 @@
 		return
 	}
 
-	mctx.WalkDeps(func(child, parent android.Module) bool {
+	contents := make(map[string]android.ApexMembership)
+
+	continueApexDepsWalk := func(child, parent android.Module) bool {
 		am, ok := child.(android.ApexModule)
 		if !ok || !am.CanHaveApexVariants() {
 			return false
@@ -821,12 +812,41 @@
 				return false
 			}
 		}
+		return true
+	}
+
+	mctx.WalkDeps(func(child, parent android.Module) bool {
+		if !continueApexDepsWalk(child, parent) {
+			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)
+		contents[depName] = contents[depName].Add(directDep)
+		return true
+	})
+
+	apexContents := android.NewApexContents(mctx.ModuleName(), contents)
+	mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
+		Contents: apexContents,
+	})
+
+	apexInfo := android.ApexInfo{
+		ApexVariationName: mctx.ModuleName(),
+		MinSdkVersionStr:  a.minSdkVersion(mctx).String(),
+		RequiredSdks:      a.RequiredSdks(),
+		Updatable:         a.Updatable(),
+		InApexes:          []string{mctx.ModuleName()},
+		ApexContents:      []*android.ApexContents{apexContents},
+	}
+
+	mctx.WalkDeps(func(child, parent android.Module) bool {
+		if !continueApexDepsWalk(child, parent) {
+			return false
+		}
+
+		child.(android.ApexModule).BuildForApex(apexInfo)
 		return true
 	})
 }
@@ -838,7 +858,40 @@
 	if am, ok := mctx.Module().(android.ApexModule); ok {
 		// Check if any dependencies use unique apex variations.  If so, use unique apex variations
 		// for this module.
-		am.UpdateUniqueApexVariationsForDeps(mctx)
+		android.UpdateUniqueApexVariationsForDeps(mctx, am)
+	}
+}
+
+func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
+	if !mctx.Module().Enabled() {
+		return
+	}
+	// Check if this module is a test for an apex.  If so, add a dependency on the apex
+	// in order to retrieve its contents later.
+	if am, ok := mctx.Module().(android.ApexModule); ok {
+		if testFor := am.TestFor(); len(testFor) > 0 {
+			mctx.AddFarVariationDependencies([]blueprint.Variation{
+				{Mutator: "os", Variation: am.Target().OsVariation()},
+				{"arch", "common"},
+			}, testForTag, testFor...)
+		}
+	}
+}
+
+func apexTestForMutator(mctx android.BottomUpMutatorContext) {
+	if !mctx.Module().Enabled() {
+		return
+	}
+
+	if _, ok := mctx.Module().(android.ApexModule); ok {
+		var contents []*android.ApexContents
+		for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
+			abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
+			contents = append(contents, abInfo.Contents)
+		}
+		mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
+			ApexContents: contents,
+		})
 	}
 }
 
@@ -899,8 +952,9 @@
 	if !mctx.Module().Enabled() {
 		return
 	}
+
 	if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
-		am.CreateApexVariations(mctx)
+		android.CreateApexVariations(mctx, am)
 	} else if a, ok := mctx.Module().(*apexBundle); ok && !a.vndkApex {
 		// apex bundle itself is mutated so that it and its modules have same
 		// apex variant.
@@ -917,22 +971,13 @@
 
 }
 
-var (
-	apexFileContextsInfosKey   = android.NewOnceKey("apexFileContextsInfosKey")
-	apexFileContextsInfosMutex sync.Mutex
-)
-
-func apexFileContextsInfos(config android.Config) *[]string {
-	return config.Once(apexFileContextsInfosKey, func() interface{} {
-		return &[]string{}
-	}).(*[]string)
-}
-
-func addFlattenedFileContextsInfos(ctx android.BaseModuleContext, fileContextsInfo string) {
-	apexFileContextsInfosMutex.Lock()
-	defer apexFileContextsInfosMutex.Unlock()
-	apexFileContextsInfos := apexFileContextsInfos(ctx.Config())
-	*apexFileContextsInfos = append(*apexFileContextsInfos, fileContextsInfo)
+func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
+	if !mctx.Module().Enabled() {
+		return
+	}
+	if am, ok := mctx.Module().(android.ApexModule); ok {
+		android.UpdateDirectlyInAnyApex(mctx, am)
+	}
 }
 
 func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
@@ -1144,6 +1189,12 @@
 	Payload_fs_type *string
 }
 
+type ApexBundleInfo struct {
+	Contents *android.ApexContents
+}
+
+var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_deps")
+
 type apexTargetBundleProperties struct {
 	Target struct {
 		// Multilib properties only for android.
@@ -1499,6 +1550,12 @@
 		}
 	}
 	for i, target := range targets {
+		if target.HostCross {
+			// Don't include artifats for the host cross targets because there is no way
+			// for us to run those artifacts natively on host
+			continue
+		}
+
 		// When multilib.* is omitted for native_shared_libs/jni_libs/tests, it implies
 		// multilib.both
 		addDependenciesForNativeModules(ctx,
@@ -1928,6 +1985,8 @@
 			return false
 		}
 
+		childApexInfo := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
+
 		dt := ctx.OtherModuleDependencyTag(child)
 
 		if _, ok := dt.(android.ExcludeFromApexContentsTag); ok {
@@ -1944,7 +2003,7 @@
 		}
 
 		// Check for the indirect dependencies if it is considered as part of the APEX
-		if android.InList(ctx.ModuleName(), am.InApexes()) {
+		if android.InList(ctx.ModuleName(), childApexInfo.InApexes) {
 			return do(ctx, parent, am, false /* externalDep */)
 		}
 
@@ -2052,6 +2111,8 @@
 		return
 	}
 
+	abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
+
 	a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
 		if ccm, ok := to.(*cc.Module); ok {
 			apexName := ctx.ModuleName()
@@ -2072,7 +2133,7 @@
 				return false
 			}
 
-			isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !android.DirectlyInApex(apexName, toName)
+			isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
 			if isStubLibraryFromOtherApex && !externalDep {
 				ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
 					"It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
@@ -2311,7 +2372,8 @@
 						}
 						af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
 						af.transitiveDep = true
-						if !a.Host() && !android.DirectlyInApex(ctx.ModuleName(), depName) && (cc.IsStubs() || cc.HasStubsVariants()) {
+						abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
+						if !a.Host() && !abInfo.Contents.DirectlyInApex(depName) && (cc.IsStubs() || cc.HasStubsVariants()) {
 							// If the dependency is a stubs lib, don't include it in this APEX,
 							// but make sure that the lib is installed on the device.
 							// In case no APEX is having the lib, the lib is installed to the system
@@ -2319,7 +2381,7 @@
 							//
 							// Always include if we are a host-apex however since those won't have any
 							// system libraries.
-							if !android.DirectlyInAnyApex(ctx, depName) {
+							if !am.DirectlyInAnyApex() {
 								// we need a module name for Make
 								name := cc.BaseModuleName() + cc.Properties.SubName
 								if proptools.Bool(a.properties.Use_vendor) {
@@ -2358,6 +2420,8 @@
 					if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
 						filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
 					}
+				} else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
+					// nothing
 				} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
 					ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
 				}
diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go
index 83a56a2..803e0c5 100644
--- a/apex/apex_singleton.go
+++ b/apex/apex_singleton.go
@@ -17,9 +17,9 @@
 package apex
 
 import (
-	"github.com/google/blueprint"
-
 	"android/soong/android"
+
+	"github.com/google/blueprint"
 )
 
 func init() {
@@ -27,39 +27,82 @@
 }
 
 type apexDepsInfoSingleton struct {
-	// Output file with all flatlists from updatable modules' deps-info combined
-	updatableFlatListsPath android.OutputPath
+	allowedApexDepsInfoCheckResult android.OutputPath
 }
 
 func apexDepsInfoSingletonFactory() android.Singleton {
 	return &apexDepsInfoSingleton{}
 }
 
-var combineFilesRule = pctx.AndroidStaticRule("combineFilesRule",
-	blueprint.RuleParams{
-		Command:        "cat $out.rsp | xargs cat > $out",
+var (
+	// Generate new apex allowed_deps.txt by merging all internal dependencies.
+	generateApexDepsInfoFilesRule = pctx.AndroidStaticRule("generateApexDepsInfoFilesRule", blueprint.RuleParams{
+		Command: "cat $out.rsp | xargs cat" +
+			// Only track non-external dependencies, i.e. those that end up in the binary
+			" | grep -v '(external)'" +
+			// Ignore comments in any of the files
+			" | grep -v '^#'" +
+			" | sort -u -f >$out",
 		Rspfile:        "$out.rsp",
 		RspfileContent: "$in",
-	},
+	})
+
+	// Diff two given lists while ignoring comments in the allowed deps file.
+	diffAllowedApexDepsInfoRule = pctx.AndroidStaticRule("diffAllowedApexDepsInfoRule", blueprint.RuleParams{
+		Description: "Diff ${allowed_deps} and ${new_allowed_deps}",
+		Command: `
+			if grep -v '^#' ${allowed_deps} | diff -B - ${new_allowed_deps}; then
+			   touch ${out};
+			else
+				echo -e "\n******************************";
+				echo "ERROR: go/apex-allowed-deps-error";
+				echo "******************************";
+				echo "Detected changes to allowed dependencies in updatable modules.";
+				echo "To fix and update build/soong/apex/allowed_deps.txt, please run:";
+				echo "$$ (croot && build/soong/scripts/update-apex-allowed-deps.sh)";
+				echo "Members of mainline-modularization@google.com will review the changes.";
+				echo -e "******************************\n";
+				exit 1;
+			fi;
+		`,
+	}, "allowed_deps", "new_allowed_deps")
 )
 
 func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContext) {
 	updatableFlatLists := android.Paths{}
 	ctx.VisitAllModules(func(module android.Module) {
 		if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok {
+			apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
 			if path := binaryInfo.FlatListPath(); path != nil {
-				if binaryInfo.Updatable() {
+				if binaryInfo.Updatable() || apexInfo.Updatable {
 					updatableFlatLists = append(updatableFlatLists, path)
 				}
 			}
 		}
 	})
 
-	s.updatableFlatListsPath = android.PathForOutput(ctx, "apex", "depsinfo", "updatable-flatlists.txt")
+	allowedDeps := android.ExistentPathForSource(ctx, "build/soong/apex/allowed_deps.txt").Path()
+
+	newAllowedDeps := android.PathForOutput(ctx, "apex", "depsinfo", "new-allowed-deps.txt")
 	ctx.Build(pctx, android.BuildParams{
-		Rule:        combineFilesRule,
-		Description: "Generate " + s.updatableFlatListsPath.String(),
-		Inputs:      updatableFlatLists,
-		Output:      s.updatableFlatListsPath,
+		Rule:   generateApexDepsInfoFilesRule,
+		Inputs: append(updatableFlatLists, allowedDeps),
+		Output: newAllowedDeps,
 	})
+
+	s.allowedApexDepsInfoCheckResult = android.PathForOutput(ctx, newAllowedDeps.Rel()+".check")
+	ctx.Build(pctx, android.BuildParams{
+		Rule:   diffAllowedApexDepsInfoRule,
+		Input:  newAllowedDeps,
+		Output: s.allowedApexDepsInfoCheckResult,
+		Args: map[string]string{
+			"allowed_deps":     allowedDeps.String(),
+			"new_allowed_deps": newAllowedDeps.String(),
+		},
+	})
+}
+
+func (s *apexDepsInfoSingleton) MakeVars(ctx android.MakeVarsContext) {
+	// Export check result to Make. The path is added to droidcore.
+	ctx.Strict("APEX_ALLOWED_DEPS_CHECK", s.allowedApexDepsInfoCheckResult.String())
 }
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 2099109..5a9a3b1 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -125,8 +125,6 @@
 }
 
 func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
-	android.ClearApexDependency()
-
 	bp = bp + `
 		filegroup {
 			name: "myapex-file_contexts",
@@ -347,6 +345,7 @@
 
 // Minimal test
 func TestBasicApex(t *testing.T) {
+	t.Parallel()
 	ctx, config := testApex(t, `
 		apex_defaults {
 			name: "myapex-defaults",
@@ -584,21 +583,22 @@
 	ensureListContains(t, noticeInputs, "custom_notice_for_static_lib")
 
 	fullDepsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("depsinfo/fulllist.txt").Args["content"], "\\n")
-	ensureListContains(t, fullDepsInfo, "myjar(minSdkVersion:(no version)) <- myapex")
-	ensureListContains(t, fullDepsInfo, "mylib(minSdkVersion:(no version)) <- myapex")
-	ensureListContains(t, fullDepsInfo, "mylib2(minSdkVersion:(no version)) <- mylib")
-	ensureListContains(t, fullDepsInfo, "myotherjar(minSdkVersion:(no version)) <- myjar")
-	ensureListContains(t, fullDepsInfo, "mysharedjar(minSdkVersion:(no version)) (external) <- myjar")
+	ensureListContains(t, fullDepsInfo, "  myjar(minSdkVersion:(no version)) <- myapex")
+	ensureListContains(t, fullDepsInfo, "  mylib(minSdkVersion:(no version)) <- myapex")
+	ensureListContains(t, fullDepsInfo, "  mylib2(minSdkVersion:(no version)) <- mylib")
+	ensureListContains(t, fullDepsInfo, "  myotherjar(minSdkVersion:(no version)) <- myjar")
+	ensureListContains(t, fullDepsInfo, "  mysharedjar(minSdkVersion:(no version)) (external) <- myjar")
 
 	flatDepsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("depsinfo/flatlist.txt").Args["content"], "\\n")
-	ensureListContains(t, flatDepsInfo, "  myjar(minSdkVersion:(no version))")
-	ensureListContains(t, flatDepsInfo, "  mylib(minSdkVersion:(no version))")
-	ensureListContains(t, flatDepsInfo, "  mylib2(minSdkVersion:(no version))")
-	ensureListContains(t, flatDepsInfo, "  myotherjar(minSdkVersion:(no version))")
-	ensureListContains(t, flatDepsInfo, "  mysharedjar(minSdkVersion:(no version)) (external)")
+	ensureListContains(t, flatDepsInfo, "myjar(minSdkVersion:(no version))")
+	ensureListContains(t, flatDepsInfo, "mylib(minSdkVersion:(no version))")
+	ensureListContains(t, flatDepsInfo, "mylib2(minSdkVersion:(no version))")
+	ensureListContains(t, flatDepsInfo, "myotherjar(minSdkVersion:(no version))")
+	ensureListContains(t, flatDepsInfo, "mysharedjar(minSdkVersion:(no version)) (external)")
 }
 
 func TestDefaults(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex_defaults {
 			name: "myapex-defaults",
@@ -673,6 +673,7 @@
 }
 
 func TestApexManifest(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -694,6 +695,7 @@
 }
 
 func TestBasicZipApex(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -744,6 +746,7 @@
 }
 
 func TestApexWithStubs(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -936,6 +939,7 @@
 }
 
 func TestApexWithExplicitStubsDependency(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex2",
@@ -1012,17 +1016,18 @@
 	ensureNotContains(t, libFooStubsLdFlags, "libbar.so")
 
 	fullDepsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("depsinfo/fulllist.txt").Args["content"], "\\n")
-	ensureListContains(t, fullDepsInfo, "mylib(minSdkVersion:(no version)) <- myapex2")
-	ensureListContains(t, fullDepsInfo, "libbaz(minSdkVersion:(no version)) <- mylib")
-	ensureListContains(t, fullDepsInfo, "libfoo(minSdkVersion:(no version)) (external) <- mylib")
+	ensureListContains(t, fullDepsInfo, "  mylib(minSdkVersion:(no version)) <- myapex2")
+	ensureListContains(t, fullDepsInfo, "  libbaz(minSdkVersion:(no version)) <- mylib")
+	ensureListContains(t, fullDepsInfo, "  libfoo(minSdkVersion:(no version)) (external) <- mylib")
 
 	flatDepsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("depsinfo/flatlist.txt").Args["content"], "\\n")
-	ensureListContains(t, flatDepsInfo, "  mylib(minSdkVersion:(no version))")
-	ensureListContains(t, flatDepsInfo, "  libbaz(minSdkVersion:(no version))")
-	ensureListContains(t, flatDepsInfo, "  libfoo(minSdkVersion:(no version)) (external)")
+	ensureListContains(t, flatDepsInfo, "mylib(minSdkVersion:(no version))")
+	ensureListContains(t, flatDepsInfo, "libbaz(minSdkVersion:(no version))")
+	ensureListContains(t, flatDepsInfo, "libfoo(minSdkVersion:(no version)) (external)")
 }
 
 func TestApexWithRuntimeLibsDependency(t *testing.T) {
+	t.Parallel()
 	/*
 		myapex
 		  |
@@ -1092,6 +1097,7 @@
 }
 
 func TestRuntimeApexShouldInstallHwasanIfLibcDependsOnIt(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, "", func(fs map[string][]byte, config android.Config) {
 		bp := `
 		apex {
@@ -1155,6 +1161,7 @@
 }
 
 func TestRuntimeApexShouldInstallHwasanIfHwaddressSanitized(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, "", func(fs map[string][]byte, config android.Config) {
 		bp := `
 		apex {
@@ -1216,6 +1223,7 @@
 }
 
 func TestApexDependsOnLLNDKTransitively(t *testing.T) {
+	t.Parallel()
 	testcases := []struct {
 		name          string
 		minSdkVersion string
@@ -1305,6 +1313,7 @@
 }
 
 func TestApexWithSystemLibsStubs(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -1395,6 +1404,7 @@
 }
 
 func TestApexMinSdkVersion_NativeModulesShouldBeBuiltAgainstStubs(t *testing.T) {
+	t.Parallel()
 	// there are three links between liba --> libz
 	// 1) myapex -> libx -> liba -> libz    : this should be #29 link, but fallback to #28
 	// 2) otherapex -> liby -> liba -> libz : this should be #30 link
@@ -1481,6 +1491,7 @@
 }
 
 func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -1530,6 +1541,7 @@
 }
 
 func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -1575,6 +1587,7 @@
 }
 
 func TestPlatformUsesLatestStubsFromApexes(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -1607,10 +1620,12 @@
 	`)
 
 	expectLink := func(from, from_variant, to, to_variant string) {
+		t.Helper()
 		ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
 		ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
 	}
 	expectNoLink := func(from, from_variant, to, to_variant string) {
+		t.Helper()
 		ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
 		ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
 	}
@@ -1620,6 +1635,7 @@
 }
 
 func TestQApexesUseLatestStubsInBundledBuildsAndHWASAN(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -1659,6 +1675,7 @@
 }
 
 func TestQTargetApexUsesStaticUnwinder(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -1689,6 +1706,7 @@
 }
 
 func TestApexMinSdkVersion_ErrorIfIncompatibleStubs(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `"libz" .*: not found a version\(<=29\)`, `
 		apex {
 			name: "myapex",
@@ -1724,6 +1742,7 @@
 }
 
 func TestApexMinSdkVersion_ErrorIfIncompatibleVersion(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `module "mylib".*: should support min_sdk_version\(29\)`, `
 		apex {
 			name: "myapex",
@@ -1752,6 +1771,7 @@
 }
 
 func TestApexMinSdkVersion_Okay(t *testing.T) {
+	t.Parallel()
 	testApex(t, `
 		apex {
 			name: "myapex",
@@ -1802,6 +1822,7 @@
 }
 
 func TestJavaStableSdkVersion(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name          string
 		expectedError string
@@ -1919,6 +1940,7 @@
 }
 
 func TestApexMinSdkVersion_ErrorIfDepIsNewer(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `module "mylib2".*: should support min_sdk_version\(29\) for "myapex"`, `
 		apex {
 			name: "myapex",
@@ -1960,6 +1982,7 @@
 }
 
 func TestApexMinSdkVersion_ErrorIfDepIsNewer_Java(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `module "bar".*: should support min_sdk_version\(29\) for "myapex"`, `
 		apex {
 			name: "myapex",
@@ -1995,6 +2018,7 @@
 }
 
 func TestApexMinSdkVersion_OkayEvenWhenDepIsNewer_IfItSatisfiesApexMinSdkVersion(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2048,6 +2072,7 @@
 }
 
 func TestFilesInSubDir(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2110,6 +2135,7 @@
 }
 
 func TestFilesInSubDirWhenNativeBridgeEnabled(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2168,6 +2194,7 @@
 }
 
 func TestUseVendor(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2222,6 +2249,7 @@
 }
 
 func TestUseVendorNotAllowedForSystemApexes(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `module "myapex" .*: use_vendor: not allowed`, `
 		apex {
 			name: "myapex",
@@ -2254,6 +2282,7 @@
 }
 
 func TestUseVendorFailsIfNotVendorAvailable(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `dependency "mylib" of "myapex" missing variant:\n.*image:vendor`, `
 		apex {
 			name: "myapex",
@@ -2278,6 +2307,7 @@
 }
 
 func TestVendorApex(t *testing.T) {
+	t.Parallel()
 	ctx, config := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2323,6 +2353,7 @@
 }
 
 func TestVendorApex_use_vndk_as_stable(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2376,6 +2407,7 @@
 }
 
 func TestApex_withPrebuiltFirmware(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name           string
 		additionalProp string
@@ -2412,6 +2444,7 @@
 }
 
 func TestAndroidMk_UseVendorRequired(t *testing.T) {
+	t.Parallel()
 	ctx, config := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2446,6 +2479,7 @@
 }
 
 func TestAndroidMk_VendorApexRequired(t *testing.T) {
+	t.Parallel()
 	ctx, config := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2477,6 +2511,7 @@
 }
 
 func TestAndroidMkWritesCommonProperties(t *testing.T) {
+	t.Parallel()
 	ctx, config := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2506,6 +2541,7 @@
 }
 
 func TestStaticLinking(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2550,6 +2586,7 @@
 }
 
 func TestKeys(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex_keytest",
@@ -2606,6 +2643,7 @@
 }
 
 func TestCertificate(t *testing.T) {
+	t.Parallel()
 	t.Run("if unspecified, it defaults to DefaultAppCertificate", func(t *testing.T) {
 		ctx, _ := testApex(t, `
 			apex {
@@ -2734,6 +2772,7 @@
 }
 
 func TestMacro(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2861,6 +2900,7 @@
 }
 
 func TestHeaderLibsDependency(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -3004,6 +3044,7 @@
 }
 
 func TestVndkApexCurrent(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex_vndk {
 			name: "myapex",
@@ -3057,6 +3098,7 @@
 }
 
 func TestVndkApexWithPrebuilt(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex_vndk {
 			name: "myapex",
@@ -3139,6 +3181,7 @@
 }
 
 func TestVndkApexVersion(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex_vndk {
 			name: "myapex_v27",
@@ -3205,6 +3248,7 @@
 }
 
 func TestVndkApexErrorWithDuplicateVersion(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `module "myapex_v27.*" .*: vndk_version: 27 is already defined in "myapex_v27.*"`, `
 		apex_vndk {
 			name: "myapex_v27",
@@ -3251,6 +3295,7 @@
 }
 
 func TestVndkApexNameRule(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex_vndk {
 			name: "myapex",
@@ -3282,6 +3327,7 @@
 }
 
 func TestVndkApexSkipsNativeBridgeSupportedModules(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex_vndk {
 			name: "myapex",
@@ -3320,6 +3366,7 @@
 }
 
 func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `module "myapex" .*: native_bridge_supported: .* doesn't support native bridge binary`, `
 		apex_vndk {
 			name: "myapex",
@@ -3350,6 +3397,7 @@
 }
 
 func TestVndkApexWithBinder32(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex_vndk {
 			name: "myapex_v27",
@@ -3416,6 +3464,7 @@
 }
 
 func TestVndkApexShouldNotProvideNativeLibs(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex_vndk {
 			name: "myapex",
@@ -3450,6 +3499,7 @@
 }
 
 func TestDependenciesInApexManifest(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex_nodep",
@@ -3554,6 +3604,7 @@
 }
 
 func TestApexName(t *testing.T) {
+	t.Parallel()
 	ctx, config := testApex(t, `
 		apex {
 			name: "myapex",
@@ -3598,6 +3649,7 @@
 }
 
 func TestNonTestApex(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -3643,16 +3695,14 @@
 	// Ensure that the platform variant ends with _shared
 	ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared")
 
-	if !android.InAnyApex("mylib_common") {
+	if !ctx.ModuleForTests("mylib_common", "android_arm64_armv8-a_shared_apex10000").Module().(*cc.Module).InAnyApex() {
 		t.Log("Found mylib_common not in any apex!")
 		t.Fail()
 	}
 }
 
 func TestTestApex(t *testing.T) {
-	if android.InAnyApex("mylib_common_test") {
-		t.Fatal("mylib_common_test must not be used in any other tests since this checks that global state is not updated in an illegal way!")
-	}
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex_test {
 			name: "myapex",
@@ -3701,6 +3751,7 @@
 }
 
 func TestApexWithTarget(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -3791,6 +3842,7 @@
 }
 
 func TestApexWithShBinary(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -3819,6 +3871,7 @@
 }
 
 func TestApexInVariousPartition(t *testing.T) {
+	t.Parallel()
 	testcases := []struct {
 		propName, parition, flattenedPartition string
 	}{
@@ -3863,6 +3916,7 @@
 }
 
 func TestFileContexts_FindInDefaultLocationIfNotSet(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -3881,6 +3935,7 @@
 }
 
 func TestFileContexts_ShouldBeUnderSystemSepolicyForSystemApexes(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `"myapex" .*: file_contexts: should be under system/sepolicy`, `
 		apex {
 			name: "myapex",
@@ -3899,6 +3954,7 @@
 }
 
 func TestFileContexts_ProductSpecificApexes(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `"myapex" .*: file_contexts: cannot find`, `
 		apex {
 			name: "myapex",
@@ -3936,6 +3992,7 @@
 }
 
 func TestFileContexts_SetViaFileGroup(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -3963,6 +4020,7 @@
 }
 
 func TestApexKeyFromOtherModule(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex_key {
 			name: "myapex.key",
@@ -3996,6 +4054,7 @@
 }
 
 func TestPrebuilt(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		prebuilt_apex {
 			name: "myapex",
@@ -4019,6 +4078,7 @@
 }
 
 func TestPrebuiltFilenameOverride(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		prebuilt_apex {
 			name: "myapex",
@@ -4036,6 +4096,7 @@
 }
 
 func TestPrebuiltOverrides(t *testing.T) {
+	t.Parallel()
 	ctx, config := testApex(t, `
 		prebuilt_apex {
 			name: "myapex.prebuilt",
@@ -4056,6 +4117,7 @@
 }
 
 func TestApexWithTests(t *testing.T) {
+	t.Parallel()
 	ctx, config := testApex(t, `
 		apex_test {
 			name: "myapex",
@@ -4167,6 +4229,7 @@
 }
 
 func TestInstallExtraFlattenedApexes(t *testing.T) {
+	t.Parallel()
 	ctx, config := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4190,6 +4253,7 @@
 }
 
 func TestApexUsesOtherApex(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4250,6 +4314,7 @@
 }
 
 func TestApexUsesFailsIfNotProvided(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `uses: "commonapex" does not provide native_shared_libs`, `
 		apex {
 			name: "myapex",
@@ -4290,6 +4355,7 @@
 }
 
 func TestApexUsesFailsIfUseVenderMismatch(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `use_vendor: "commonapex" has different value of use_vendor`, `
 		apex {
 			name: "myapex",
@@ -4315,6 +4381,7 @@
 }
 
 func TestErrorsIfDepsAreNotEnabled(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `module "myapex" .* depends on disabled module "libfoo"`, `
 		apex {
 			name: "myapex",
@@ -4361,6 +4428,7 @@
 }
 
 func TestApexWithApps(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4439,6 +4507,7 @@
 }
 
 func TestApexWithAppImports(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4487,6 +4556,7 @@
 }
 
 func TestApexWithAppImportsPrefer(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4528,6 +4598,7 @@
 }
 
 func TestApexWithTestHelperApp(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4559,6 +4630,7 @@
 }
 
 func TestApexPropertiesShouldBeDefaultable(t *testing.T) {
+	t.Parallel()
 	// libfoo's apex_available comes from cc_defaults
 	testApexError(t, `requires "libfoo" that is not available for the APEX`, `
 	apex {
@@ -4593,6 +4665,7 @@
 }
 
 func TestApexAvailable_DirectDep(t *testing.T) {
+	t.Parallel()
 	// libfoo is not available to myapex, but only to otherapex
 	testApexError(t, "requires \"libfoo\" that is not available for the APEX", `
 	apex {
@@ -4628,6 +4701,7 @@
 }
 
 func TestApexAvailable_IndirectDep(t *testing.T) {
+	t.Parallel()
 	// libbbaz is an indirect dep
 	testApexError(t, `requires "libbaz" that is not available for the APEX. Dependency path:
 .*via tag apex\.dependencyTag.*name:sharedLib.*
@@ -4672,6 +4746,7 @@
 }
 
 func TestApexAvailable_InvalidApexName(t *testing.T) {
+	t.Parallel()
 	testApexError(t, "\"otherapex\" is not a valid module name", `
 	apex {
 		name: "myapex",
@@ -4731,6 +4806,7 @@
 }
 
 func TestApexAvailable_CheckForPlatform(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 	apex {
 		name: "myapex",
@@ -4793,6 +4869,7 @@
 }
 
 func TestApexAvailable_CreatedForApex(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 	apex {
 		name: "myapex",
@@ -4827,6 +4904,7 @@
 }
 
 func TestOverrideApex(t *testing.T) {
+	t.Parallel()
 	ctx, config := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4910,6 +4988,7 @@
 }
 
 func TestLegacyAndroid10Support(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4965,6 +5044,7 @@
 }
 
 func TestJavaSDKLibrary(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4997,6 +5077,7 @@
 }
 
 func TestJavaSDKLibrary_WithinApex(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -5044,6 +5125,7 @@
 }
 
 func TestJavaSDKLibrary_CrossBoundary(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -5089,6 +5171,7 @@
 }
 
 func TestJavaSDKLibrary_ImportPreferred(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, ``,
 		withFiles(map[string][]byte{
 			"apex/a.java":             nil,
@@ -5174,6 +5257,7 @@
 }
 
 func TestJavaSDKLibrary_ImportOnly(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `java_libs: "foo" is not configured to be compiled into dex`, `
 		apex {
 			name: "myapex",
@@ -5200,6 +5284,7 @@
 }
 
 func TestCompatConfig(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -5234,6 +5319,7 @@
 }
 
 func TestRejectNonInstallableJavaLibrary(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `"myjar" is not configured to be compiled into dex`, `
 		apex {
 			name: "myapex",
@@ -5259,6 +5345,7 @@
 }
 
 func TestCarryRequiredModuleNames(t *testing.T) {
+	t.Parallel()
 	ctx, config := testApex(t, `
 		apex {
 			name: "myapex",
@@ -5297,6 +5384,7 @@
 }
 
 func TestSymlinksFromApexToSystem(t *testing.T) {
+	t.Parallel()
 	bp := `
 		apex {
 			name: "myapex",
@@ -5426,6 +5514,7 @@
 }
 
 func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) {
+	t.Parallel()
 	ctx, config := testApex(t, `
 		apex {
 			name: "myapex",
@@ -5477,6 +5566,7 @@
 }
 
 func TestApexWithJniLibs(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -5518,6 +5608,7 @@
 }
 
 func TestApexMutatorsDontRunIfDisabled(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -5539,6 +5630,7 @@
 }
 
 func TestAppBundle(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -5569,6 +5661,7 @@
 }
 
 func TestAppSetBundle(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -5743,6 +5836,7 @@
 }
 
 func TestUpdatable_should_set_min_sdk_version(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
 		apex {
 			name: "myapex",
@@ -5759,6 +5853,7 @@
 }
 
 func TestNoUpdatableJarsInBootImage(t *testing.T) {
+	t.Parallel()
 	var err string
 	var transform func(*dexpreopt.GlobalConfig)
 
@@ -5845,7 +5940,6 @@
 
 func testApexPermittedPackagesRules(t *testing.T, errmsg, bp string, apexBootJars []string, rules []android.Rule) {
 	t.Helper()
-	android.ClearApexDependency()
 	bp += `
 	apex_key {
 		name: "myapex.key",
@@ -5896,6 +5990,7 @@
 }
 
 func TestApexPermittedPackagesRules(t *testing.T) {
+	t.Parallel()
 	testcases := []struct {
 		name            string
 		expectedError   string
@@ -5979,6 +6074,7 @@
 }
 
 func TestTestFor(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -6036,6 +6132,7 @@
 }
 
 func TestApexSet(t *testing.T) {
+	t.Parallel()
 	ctx, config := testApex(t, `
 		apex_set {
 			name: "myapex",
@@ -6075,6 +6172,7 @@
 }
 
 func TestNoStaticLinkingToStubsLib(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `.*required by "mylib" is a native library providing stub.*`, `
 		apex {
 			name: "myapex",
@@ -6111,6 +6209,7 @@
 }
 
 func TestApexKeysTxt(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -6151,6 +6250,7 @@
 }
 
 func TestAllowedFiles(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex {
 			name: "myapex",
@@ -6206,6 +6306,7 @@
 }
 
 func TestNonPreferredPrebuiltDependency(t *testing.T) {
+	t.Parallel()
 	_, _ = testApex(t, `
 		apex {
 			name: "myapex",
diff --git a/apex/builder.go b/apex/builder.go
index b0f0c82..7c125ef 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -257,15 +257,34 @@
 
 	output := android.PathForModuleOut(ctx, "file_contexts")
 	rule := android.NewRuleBuilder()
-	// remove old file
-	rule.Command().Text("rm").FlagWithOutput("-f ", output)
-	// copy file_contexts
-	rule.Command().Text("cat").Input(fileContexts).Text(">>").Output(output)
-	// new line
-	rule.Command().Text("echo").Text(">>").Output(output)
-	// force-label /apex_manifest.pb and / as system_file so that apexd can read them
-	rule.Command().Text("echo").Flag("/apex_manifest\\\\.pb u:object_r:system_file:s0").Text(">>").Output(output)
-	rule.Command().Text("echo").Flag("/ u:object_r:system_file:s0").Text(">>").Output(output)
+
+	if a.properties.ApexType == imageApex {
+		// remove old file
+		rule.Command().Text("rm").FlagWithOutput("-f ", output)
+		// copy file_contexts
+		rule.Command().Text("cat").Input(fileContexts).Text(">>").Output(output)
+		// new line
+		rule.Command().Text("echo").Text(">>").Output(output)
+		// force-label /apex_manifest.pb and / as system_file so that apexd can read them
+		rule.Command().Text("echo").Flag("/apex_manifest\\\\.pb u:object_r:system_file:s0").Text(">>").Output(output)
+		rule.Command().Text("echo").Flag("/ u:object_r:system_file:s0").Text(">>").Output(output)
+	} else {
+		// For flattened apexes, install path should be prepended.
+		// File_contexts file should be emiited to make via LOCAL_FILE_CONTEXTS
+		// so that it can be merged into file_contexts.bin
+		apexPath := android.InstallPathToOnDevicePath(ctx, a.installDir.Join(ctx, a.Name()))
+		apexPath = strings.ReplaceAll(apexPath, ".", `\\.`)
+		// remove old file
+		rule.Command().Text("rm").FlagWithOutput("-f ", output)
+		// copy file_contexts
+		rule.Command().Text("awk").Text(`'/object_r/{printf("` + apexPath + `%s\n", $0)}'`).Input(fileContexts).Text(">").Output(output)
+		// new line
+		rule.Command().Text("echo").Text(">>").Output(output)
+		// force-label /apex_manifest.pb and / as system_file so that apexd can read them
+		rule.Command().Text("echo").Flag(apexPath + `/apex_manifest\\.pb u:object_r:system_file:s0`).Text(">>").Output(output)
+		rule.Command().Text("echo").Flag(apexPath + "/ u:object_r:system_file:s0").Text(">>").Output(output)
+	}
+
 	rule.Build(pctx, ctx, "file_contexts."+a.Name(), "Generate file_contexts")
 
 	a.fileContexts = output.OutputPath
@@ -689,14 +708,7 @@
 	// instead of `android.PathForOutput`) to return the correct path to the flattened
 	// APEX (as its contents is installed by Make, not Soong).
 	factx := flattenedApexContext{ctx}
-	apexBundleName := a.Name()
-	a.outputFile = android.PathForModuleInstall(&factx, "apex", apexBundleName)
-
-	if a.installable() {
-		installPath := android.PathForModuleInstall(ctx, "apex", apexBundleName)
-		devicePath := android.InstallPathToOnDevicePath(ctx, installPath)
-		addFlattenedFileContextsInfos(ctx, apexBundleName+":"+devicePath+":"+a.fileContexts.String())
-	}
+	a.outputFile = android.PathForModuleInstall(&factx, "apex", a.Name())
 	a.buildFilesInfo(ctx)
 }
 
diff --git a/apex/vndk_test.go b/apex/vndk_test.go
index 60b6ed5..e623990 100644
--- a/apex/vndk_test.go
+++ b/apex/vndk_test.go
@@ -9,6 +9,7 @@
 )
 
 func TestVndkApexForVndkLite(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testApex(t, `
 		apex_vndk {
 			name: "myapex",
@@ -62,6 +63,7 @@
 }
 
 func TestVndkApexUsesVendorVariant(t *testing.T) {
+	t.Parallel()
 	bp := `
 		apex_vndk {
 			name: "myapex",
diff --git a/bpf/bpf_test.go b/bpf/bpf_test.go
index d06d7d1..44d4cc3 100644
--- a/bpf/bpf_test.go
+++ b/bpf/bpf_test.go
@@ -66,6 +66,7 @@
 }
 
 func TestBpfDataDependency(t *testing.T) {
+	t.Parallel()
 	bp := `
 		bpf {
 			name: "bpf.o",
diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go
index ef9814f..2bbbd7f 100644
--- a/bpfix/bpfix/bpfix_test.go
+++ b/bpfix/bpfix/bpfix_test.go
@@ -116,6 +116,7 @@
 }
 
 func TestSimplifyKnownVariablesDuplicatingEachOther(t *testing.T) {
+	t.Parallel()
 	// TODO use []Expression{} once buildTree above can support it (which is after b/38325146 is done)
 	implFilterListTest(t, []string{"include"}, []string{"include"}, nil)
 	implFilterListTest(t, []string{"include1"}, []string{"include2"}, []string{"include1"})
@@ -169,6 +170,7 @@
 }
 
 func TestMergeMatchingProperties(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name string
 		in   string
@@ -258,6 +260,7 @@
 }
 
 func TestReorderCommonProperties(t *testing.T) {
+	t.Parallel()
 	var tests = []struct {
 		name string
 		in   string
@@ -344,6 +347,7 @@
 }
 
 func TestRemoveMatchingModuleListProperties(t *testing.T) {
+	t.Parallel()
 	var tests = []struct {
 		name string
 		in   string
@@ -499,6 +503,7 @@
 }
 
 func TestReplaceJavaStaticLibs(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name string
 		in   string
@@ -557,6 +562,7 @@
 }
 
 func TestRewritePrebuilts(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name string
 		in   string
@@ -623,6 +629,7 @@
 }
 
 func TestRewriteCtsModuleTypes(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name string
 		in   string
@@ -694,6 +701,7 @@
 }
 
 func TestRewritePrebuiltEtc(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name string
 		in   string
@@ -769,6 +777,7 @@
 }
 
 func TestRewriteAndroidTest(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name string
 		in   string
@@ -802,6 +811,7 @@
 }
 
 func TestRewriteAndroidAppImport(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name string
 		in   string
@@ -851,6 +861,7 @@
 }
 
 func TestRemoveEmptyLibDependencies(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name string
 		in   string
@@ -905,6 +916,7 @@
 }
 
 func TestRemoveHidlInterfaceTypes(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name string
 		in   string
@@ -936,6 +948,7 @@
 }
 
 func TestRemoveSoongConfigBoolVariable(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name string
 		in   string
@@ -1000,6 +1013,7 @@
 }
 
 func TestRemovePdkProperty(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name string
 		in   string
diff --git a/cc/OWNERS b/cc/OWNERS
new file mode 100644
index 0000000..6d7c30a
--- /dev/null
+++ b/cc/OWNERS
@@ -0,0 +1,4 @@
+per-file ndk_*.go = danalbert@google.com
+per-file tidy.go = srhines@google.com, chh@google.com
+per-file lto.go,pgo.go = srhines@google.com, pirama@google.com, yikong@google.com
+
diff --git a/cc/androidmk.go b/cc/androidmk.go
index f0e6152..a2549b8 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -33,7 +33,6 @@
 )
 
 type AndroidMkContext interface {
-	Name() string
 	Target() android.Target
 	subAndroidMk(*android.AndroidMkEntries, interface{})
 	Arch() android.Arch
@@ -44,6 +43,7 @@
 	static() bool
 	InRamdisk() bool
 	InRecovery() bool
+	AnyVariantDirectlyInAnyApex() bool
 }
 
 type subAndroidMkProvider interface {
@@ -63,7 +63,7 @@
 }
 
 func (c *Module) AndroidMkEntries() []android.AndroidMkEntries {
-	if c.Properties.HideFromMake || !c.IsForPlatform() {
+	if c.hideApexVariantFromMake || c.Properties.HideFromMake {
 		return []android.AndroidMkEntries{{
 			Disabled: true,
 		}}
@@ -156,24 +156,6 @@
 	return []android.AndroidMkEntries{entries}
 }
 
-func AndroidMkDataPaths(data []android.DataPath) []string {
-	var testFiles []string
-	for _, d := range data {
-		rel := d.SrcPath.Rel()
-		path := d.SrcPath.String()
-		if !strings.HasSuffix(path, rel) {
-			panic(fmt.Errorf("path %q does not end with %q", path, rel))
-		}
-		path = strings.TrimSuffix(path, rel)
-		testFileString := path + ":" + rel
-		if len(d.RelativeInstallPath) > 0 {
-			testFileString += ":" + d.RelativeInstallPath
-		}
-		testFiles = append(testFiles, testFileString)
-	}
-	return testFiles
-}
-
 func androidMkWriteExtraTestConfigs(extraTestConfigs android.Paths, entries *android.AndroidMkEntries) {
 	if len(extraTestConfigs) > 0 {
 		entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
@@ -183,7 +165,7 @@
 }
 
 func androidMkWriteTestData(data []android.DataPath, ctx AndroidMkContext, entries *android.AndroidMkEntries) {
-	testFiles := AndroidMkDataPaths(data)
+	testFiles := android.AndroidMkDataPaths(data)
 	if len(testFiles) > 0 {
 		entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
 			entries.AddStrings("LOCAL_TEST_DATA", testFiles...)
@@ -295,9 +277,8 @@
 			}
 		})
 	}
-	if len(library.Properties.Stubs.Versions) > 0 &&
-		android.DirectlyInAnyApex(ctx, ctx.Name()) && !ctx.InRamdisk() && !ctx.InRecovery() && !ctx.UseVndk() &&
-		!ctx.static() {
+	if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.AnyVariantDirectlyInAnyApex() &&
+		!ctx.InRamdisk() && !ctx.InRecovery() && !ctx.UseVndk() && !ctx.static() {
 		if library.buildStubs() && library.isLatestStubVersion() {
 			// reference the latest version via its name without suffix when it is provided by apex
 			entries.SubName = ""
diff --git a/cc/binary.go b/cc/binary.go
index b3ce5ff..7f7b619 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -445,7 +445,9 @@
 	// The original path becomes a symlink to the corresponding file in the
 	// runtime APEX.
 	translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled
-	if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !translatedArch && ctx.apexVariationName() == "" && !ctx.inRamdisk() && !ctx.inRecovery() {
+	if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !ctx.Host() && ctx.directlyInAnyApex() &&
+		!translatedArch && ctx.apexVariationName() == "" && !ctx.inRamdisk() && !ctx.inRecovery() {
+
 		if ctx.Device() && isBionic(ctx.baseModuleName()) {
 			binary.installSymlinkToRuntimeApex(ctx, file)
 		}
diff --git a/cc/binary_sdk_member.go b/cc/binary_sdk_member.go
index 55e400e..ebf89ea 100644
--- a/cc/binary_sdk_member.go
+++ b/cc/binary_sdk_member.go
@@ -40,19 +40,14 @@
 
 func (mt *binarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
 	targets := mctx.MultiTargets()
-	for _, lib := range names {
+	for _, bin := range names {
 		for _, target := range targets {
-			name, version := StubsLibNameAndVersion(lib)
-			if version == "" {
-				version = "latest"
-			}
 			variations := target.Variations()
 			if mctx.Device() {
 				variations = append(variations,
-					blueprint.Variation{Mutator: "image", Variation: android.CoreVariation},
-					blueprint.Variation{Mutator: "version", Variation: version})
+					blueprint.Variation{Mutator: "image", Variation: android.CoreVariation})
 			}
-			mctx.AddFarVariationDependencies(variations, dependencyTag, name)
+			mctx.AddFarVariationDependencies(variations, dependencyTag, bin)
 		}
 	}
 }
diff --git a/cc/cc.go b/cc/cc.go
index a813428..8188550 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -366,6 +366,7 @@
 	bootstrap() bool
 	mustUseVendorVariant() bool
 	nativeCoverage() bool
+	directlyInAnyApex() bool
 }
 
 type ModuleContext interface {
@@ -545,8 +546,17 @@
 	dataLibDepTag         = dependencyTag{name: "data lib"}
 	runtimeDepTag         = dependencyTag{name: "runtime lib"}
 	testPerSrcDepTag      = dependencyTag{name: "test_per_src"}
+	testForDepTag         = dependencyTag{name: "test for apex"}
+
+	stubImplDepTag = copyDirectlyInAnyApexDependencyTag{name: "stub_impl"}
 )
 
+type copyDirectlyInAnyApexDependencyTag dependencyTag
+
+func (copyDirectlyInAnyApexDependencyTag) CopyDirectlyInAnyApex() {}
+
+var _ android.CopyDirectlyInAnyApexTag = copyDirectlyInAnyApexDependencyTag{}
+
 func IsSharedDepTag(depTag blueprint.DependencyTag) bool {
 	ccLibDepTag, ok := depTag.(libraryDependencyTag)
 	return ok && ccLibDepTag.shared()
@@ -622,6 +632,8 @@
 
 	// For apex variants, this is set as apex.min_sdk_version
 	apexSdkVersion android.ApiLevel
+
+	hideApexVariantFromMake bool
 }
 
 func (c *Module) Toc() android.OptionalPath {
@@ -697,6 +709,9 @@
 }
 
 func (c *Module) SplitPerApiLevel() bool {
+	if !c.canUseSdk() {
+		return false
+	}
 	if linker, ok := c.linker.(*objectLinker); ok {
 		return linker.isCrt()
 	}
@@ -740,6 +755,9 @@
 		if library, ok := c.linker.(*libraryDecorator); ok {
 			return library.Properties.Stubs.Versions
 		}
+		if library, ok := c.linker.(*prebuiltLibraryLinker); ok {
+			return library.Properties.Stubs.Versions
+		}
 	}
 	panic(fmt.Errorf("StubsVersions called on non-library module: %q", c.BaseModuleName()))
 }
@@ -749,6 +767,9 @@
 		if _, ok := c.linker.(*libraryDecorator); ok {
 			return true
 		}
+		if _, ok := c.linker.(*prebuiltLibraryLinker); ok {
+			return true
+		}
 	}
 	return false
 }
@@ -774,6 +795,14 @@
 			c.Properties.PreventInstall = true
 			return
 		}
+		if library, ok := c.linker.(*prebuiltLibraryLinker); ok {
+			library.MutatedProperties.BuildStubs = true
+			c.Properties.HideFromMake = true
+			c.sanitize = nil
+			c.stl = nil
+			c.Properties.PreventInstall = true
+			return
+		}
 		if _, ok := c.linker.(*llndkStubDecorator); ok {
 			c.Properties.HideFromMake = true
 			return
@@ -787,6 +816,9 @@
 		if library, ok := c.linker.(*libraryDecorator); ok {
 			return library.buildStubs()
 		}
+		if library, ok := c.linker.(*prebuiltLibraryLinker); ok {
+			return library.buildStubs()
+		}
 	}
 	panic(fmt.Errorf("BuildStubs called on non-library module: %q", c.BaseModuleName()))
 }
@@ -796,6 +828,10 @@
 		library.MutatedProperties.AllStubsVersions = versions
 		return
 	}
+	if library, ok := c.linker.(*prebuiltLibraryLinker); ok {
+		library.MutatedProperties.AllStubsVersions = versions
+		return
+	}
 	if llndk, ok := c.linker.(*llndkStubDecorator); ok {
 		llndk.libraryDecorator.MutatedProperties.AllStubsVersions = versions
 		return
@@ -806,6 +842,9 @@
 	if library, ok := c.linker.(*libraryDecorator); ok {
 		return library.MutatedProperties.AllStubsVersions
 	}
+	if library, ok := c.linker.(*prebuiltLibraryLinker); ok {
+		return library.MutatedProperties.AllStubsVersions
+	}
 	if llndk, ok := c.linker.(*llndkStubDecorator); ok {
 		return llndk.libraryDecorator.MutatedProperties.AllStubsVersions
 	}
@@ -818,6 +857,10 @@
 			library.MutatedProperties.StubsVersion = version
 			return
 		}
+		if library, ok := c.linker.(*prebuiltLibraryLinker); ok {
+			library.MutatedProperties.StubsVersion = version
+			return
+		}
 		if llndk, ok := c.linker.(*llndkStubDecorator); ok {
 			llndk.libraryDecorator.MutatedProperties.StubsVersion = version
 			return
@@ -831,6 +874,9 @@
 		if library, ok := c.linker.(*libraryDecorator); ok {
 			return library.MutatedProperties.StubsVersion
 		}
+		if library, ok := c.linker.(*prebuiltLibraryLinker); ok {
+			return library.MutatedProperties.StubsVersion
+		}
 		if llndk, ok := c.linker.(*llndkStubDecorator); ok {
 			return llndk.libraryDecorator.MutatedProperties.StubsVersion
 		}
@@ -995,7 +1041,7 @@
 
 func (c *Module) UseSdk() bool {
 	if c.canUseSdk() {
-		return String(c.Properties.Sdk_version) != "" || c.SplitPerApiLevel()
+		return String(c.Properties.Sdk_version) != ""
 	}
 	return false
 }
@@ -1073,6 +1119,8 @@
 func (c *Module) IsStubs() bool {
 	if library, ok := c.linker.(*libraryDecorator); ok {
 		return library.buildStubs()
+	} else if library, ok := c.linker.(*prebuiltLibraryLinker); ok {
+		return library.buildStubs()
 	} else if _, ok := c.linker.(*llndkStubDecorator); ok {
 		return true
 	}
@@ -1327,11 +1375,11 @@
 }
 
 func (ctx *moduleContextImpl) isForPlatform() bool {
-	return ctx.mod.IsForPlatform()
+	return ctx.ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
 }
 
 func (ctx *moduleContextImpl) apexVariationName() string {
-	return ctx.mod.ApexVariationName()
+	return ctx.ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).ApexVariationName
 }
 
 func (ctx *moduleContextImpl) apexSdkVersion() android.ApiLevel {
@@ -1354,6 +1402,10 @@
 	return ctx.mod.nativeCoverage()
 }
 
+func (ctx *moduleContextImpl) directlyInAnyApex() bool {
+	return ctx.mod.DirectlyInAnyApex()
+}
+
 func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
 	return &Module{
 		hod:      hod,
@@ -1509,6 +1561,11 @@
 		return
 	}
 
+	apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+	if !apexInfo.IsForPlatform() {
+		c.hideApexVariantFromMake = true
+	}
+
 	c.makeLinkType = c.getMakeLinkType(actx)
 
 	c.Properties.SubName = ""
@@ -1640,8 +1697,7 @@
 		// force anything in the make world to link against the stubs library.
 		// (unless it is explicitly referenced via .bootstrap suffix or the
 		// module is marked with 'bootstrap: true').
-		if c.HasStubsVariants() &&
-			android.DirectlyInAnyApex(ctx, ctx.baseModuleName()) && !c.InRamdisk() &&
+		if c.HasStubsVariants() && c.AnyVariantDirectlyInAnyApex() && !c.InRamdisk() &&
 			!c.InRecovery() && !c.UseVndk() && !c.static() && !c.isCoverageVariant() &&
 			c.IsStubs() {
 			c.Properties.HideFromMake = false // unhide
@@ -1650,13 +1706,13 @@
 
 		// glob exported headers for snapshot, if BOARD_VNDK_VERSION is current.
 		if i, ok := c.linker.(snapshotLibraryInterface); ok && ctx.DeviceConfig().VndkVersion() == "current" {
-			if isSnapshotAware(ctx, c) {
+			if isSnapshotAware(ctx, c, apexInfo) {
 				i.collectHeadersForSnapshot(ctx)
 			}
 		}
 	}
 
-	if c.installable() {
+	if c.installable(apexInfo) {
 		c.installer.install(ctx, c.outputFile.Path())
 		if ctx.Failed() {
 			return
@@ -1830,6 +1886,42 @@
 	}
 }
 
+func (c *Module) addSharedLibDependenciesWithVersions(ctx android.BottomUpMutatorContext,
+	variations []blueprint.Variation, depTag libraryDependencyTag, name, version string, far bool) {
+
+	variations = append([]blueprint.Variation(nil), variations...)
+
+	if version != "" && CanBeOrLinkAgainstVersionVariants(c) {
+		// Version is explicitly specified. i.e. libFoo#30
+		variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version})
+		depTag.explicitlyVersioned = true
+	}
+	var deps []blueprint.Module
+	if far {
+		deps = ctx.AddFarVariationDependencies(variations, depTag, name)
+	} else {
+		deps = ctx.AddVariationDependencies(variations, depTag, name)
+	}
+
+	// If the version is not specified, add dependency to all stubs libraries.
+	// The stubs library will be used when the depending module is built for APEX and
+	// the dependent module is not in the same APEX.
+	if version == "" && CanBeOrLinkAgainstVersionVariants(c) {
+		if dep, ok := deps[0].(*Module); ok {
+			for _, ver := range dep.AllStubsVersions() {
+				// Note that depTag.ExplicitlyVersioned is false in this case.
+				versionVariations := append(variations,
+					blueprint.Variation{Mutator: "version", Variation: ver})
+				if far {
+					ctx.AddFarVariationDependencies(versionVariations, depTag, name)
+				} else {
+					ctx.AddVariationDependencies(versionVariations, depTag, name)
+				}
+			}
+		}
+	}
+}
+
 func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
 	if !c.Enabled() {
 		return
@@ -1930,6 +2022,11 @@
 				buildStubs = true
 			}
 		}
+		if library, ok := c.linker.(*prebuiltLibraryLinker); ok {
+			if library.buildStubs() {
+				buildStubs = true
+			}
+		}
 	}
 
 	rewriteSnapshotLibs := func(lib string, snapshotMap *snapshotMap) string {
@@ -2018,32 +2115,6 @@
 		}, depTag, rewriteSnapshotLibs(lib, vendorSnapshotStaticLibs))
 	}
 
-	addSharedLibDependencies := func(depTag libraryDependencyTag, name string, version string) {
-		var variations []blueprint.Variation
-		variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"})
-		if version != "" && VersionVariantAvailable(c) {
-			// Version is explicitly specified. i.e. libFoo#30
-			variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version})
-			depTag.explicitlyVersioned = true
-		}
-		deps := actx.AddVariationDependencies(variations, depTag, name)
-
-		// If the version is not specified, add dependency to all stubs libraries.
-		// The stubs library will be used when the depending module is built for APEX and
-		// the dependent module is not in the same APEX.
-		if version == "" && VersionVariantAvailable(c) {
-			if dep, ok := deps[0].(*Module); ok {
-				for _, ver := range dep.AllStubsVersions() {
-					// Note that depTag.ExplicitlyVersioned is false in this case.
-					ctx.AddVariationDependencies([]blueprint.Variation{
-						{Mutator: "link", Variation: "shared"},
-						{Mutator: "version", Variation: ver},
-					}, depTag, name)
-				}
-			}
-		}
-	}
-
 	// shared lib names without the #version suffix
 	var sharedLibNames []string
 
@@ -2060,7 +2131,10 @@
 		name, version := StubsLibNameAndVersion(lib)
 		sharedLibNames = append(sharedLibNames, name)
 
-		addSharedLibDependencies(depTag, name, version)
+		variations := []blueprint.Variation{
+			{Mutator: "link", Variation: "shared"},
+		}
+		c.addSharedLibDependenciesWithVersions(ctx, variations, depTag, name, version, false)
 	}
 
 	for _, lib := range deps.LateSharedLibs {
@@ -2071,7 +2145,10 @@
 			continue
 		}
 		depTag := libraryDependencyTag{Kind: sharedLibraryDependency, Order: lateLibraryDependency}
-		addSharedLibDependencies(depTag, lib, "")
+		variations := []blueprint.Variation{
+			{Mutator: "link", Variation: "shared"},
+		}
+		c.addSharedLibDependenciesWithVersions(ctx, variations, depTag, lib, "", false)
 	}
 
 	actx.AddVariationDependencies([]blueprint.Variation{
@@ -2324,8 +2401,9 @@
 
 	// For the dependency from platform to apex, use the latest stubs
 	c.apexSdkVersion = android.FutureApiLevel
-	if !c.IsForPlatform() {
-		c.apexSdkVersion = c.ApexProperties.Info.MinSdkVersion(ctx)
+	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+	if !apexInfo.IsForPlatform() {
+		c.apexSdkVersion = apexInfo.MinSdkVersion(ctx)
 	}
 
 	if android.InList("hwaddress", ctx.Config().SanitizeDevice()) {
@@ -2435,9 +2513,9 @@
 
 			if ccDep.CcLibrary() && !libDepTag.static() {
 				depIsStubs := ccDep.BuildStubs()
-				depHasStubs := VersionVariantAvailable(c) && ccDep.HasStubsVariants()
-				depInSameApexes := android.DirectlyInAllApexes(c.InApexes(), depName)
-				depInPlatform := !android.DirectlyInAnyApex(ctx, depName)
+				depHasStubs := CanBeOrLinkAgainstVersionVariants(c) && ccDep.HasStubsVariants()
+				depInSameApexes := android.DirectlyInAllApexes(apexInfo, depName)
+				depInPlatform := !dep.(android.ApexModule).AnyVariantDirectlyInAnyApex()
 
 				var useThisDep bool
 				if depIsStubs && libDepTag.explicitlyVersioned {
@@ -2447,7 +2525,7 @@
 					// Use non-stub variant if that is the only choice
 					// (i.e. depending on a lib without stubs.version property)
 					useThisDep = true
-				} else if c.IsForPlatform() {
+				} else if apexInfo.IsForPlatform() {
 					// If not building for APEX, use stubs only when it is from
 					// an APEX (and not from platform)
 					useThisDep = (depInPlatform != depIsStubs)
@@ -2456,11 +2534,12 @@
 						// always link to non-stub variant
 						useThisDep = !depIsStubs
 					}
-					for _, testFor := range c.TestFor() {
-						// Another exception: if this module is bundled with an APEX, then
-						// it is linked with the non-stub variant of a module in the APEX
-						// as if this is part of the APEX.
-						if android.DirectlyInApex(testFor, depName) {
+					// Another exception: if this module is bundled with an APEX, then
+					// it is linked with the non-stub variant of a module in the APEX
+					// as if this is part of the APEX.
+					testFor := ctx.Provider(android.ApexTestForInfoProvider).(android.ApexTestForInfo)
+					for _, apexContents := range testFor.ApexContents {
+						if apexContents.DirectlyInApex(depName) {
 							useThisDep = !depIsStubs
 							break
 						}
@@ -2492,7 +2571,7 @@
 					// by default, use current version of LLNDK
 					versionToUse := ""
 					versions := m.AllStubsVersions()
-					if c.ApexVariationName() != "" && len(versions) > 0 {
+					if apexInfo.ApexVariationName != "" && len(versions) > 0 {
 						// if this is for use_vendor apex && dep has stubsVersions
 						// apply the same rule of apex sdk enforcement to choose right version
 						var err error
@@ -2654,10 +2733,11 @@
 					c.Properties.AndroidMkHeaderLibs, makeLibName)
 			case libDepTag.shared():
 				if ccDep.CcLibrary() {
-					if ccDep.BuildStubs() && android.InAnyApex(depName) {
+					if ccDep.BuildStubs() && dep.(android.ApexModule).InAnyApex() {
 						// Add the dependency to the APEX(es) providing the library so that
 						// m <module> can trigger building the APEXes as well.
-						for _, an := range android.GetApexesForModule(depName) {
+						depApexInfo := ctx.OtherModuleProvider(dep, android.ApexInfoProvider).(android.ApexInfo)
+						for _, an := range depApexInfo.InApexes {
 							c.Properties.ApexesProvidingSharedLibs = append(
 								c.Properties.ApexesProvidingSharedLibs, an)
 						}
@@ -2961,7 +3041,7 @@
 		c.installer.everInstallable()
 }
 
-func (c *Module) installable() bool {
+func (c *Module) installable(apexInfo android.ApexInfo) bool {
 	ret := c.EverInstallable() &&
 		// Check to see whether the module has been configured to not be installed.
 		proptools.BoolDefault(c.Properties.Installable, true) &&
@@ -2970,7 +3050,7 @@
 	// The platform variant doesn't need further condition. Apex variants however might not
 	// be installable because it will likely to be included in the APEX and won't appear
 	// in the system partition.
-	if c.IsForPlatform() {
+	if apexInfo.IsForPlatform() {
 		return ret
 	}
 
@@ -3112,6 +3192,8 @@
 		&LTOProperties{},
 		&PgoProperties{},
 		&android.ProtoProperties{},
+		// RustBindgenProperties is included here so that cc_defaults can be used for rust_bindgen modules.
+		&RustBindgenClangProperties{},
 	)
 
 	android.InitDefaultsModule(module)
diff --git a/cc/cc_test.go b/cc/cc_test.go
index e0d4640..8d00239 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -128,6 +128,7 @@
 )
 
 func TestFuchsiaDeps(t *testing.T) {
+	t.Parallel()
 	t.Helper()
 
 	bp := `
@@ -165,6 +166,7 @@
 }
 
 func TestFuchsiaTargetDecl(t *testing.T) {
+	t.Parallel()
 	t.Helper()
 
 	bp := `
@@ -191,6 +193,7 @@
 }
 
 func TestVendorSrc(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_library {
 			name: "libTest",
@@ -321,6 +324,7 @@
 }
 
 func TestVndk(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libvndk",
@@ -447,6 +451,7 @@
 }
 
 func TestVndkWithHostSupported(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_library {
 			name: "libvndk_host_supported",
@@ -481,6 +486,7 @@
 }
 
 func TestVndkLibrariesTxtAndroidMk(t *testing.T) {
+	t.Parallel()
 	bp := `
 		vndk_libraries_txt {
 			name: "llndk.libraries.txt",
@@ -496,6 +502,7 @@
 }
 
 func TestVndkUsingCoreVariant(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libvndk",
@@ -543,6 +550,7 @@
 }
 
 func TestDataLibs(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_test_library {
 			name: "test_lib",
@@ -593,6 +601,7 @@
 }
 
 func TestDataLibsRelativeInstallPath(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_test_library {
 			name: "test_lib",
@@ -640,6 +649,7 @@
 }
 
 func TestVndkWhenVndkVersionIsNotSet(t *testing.T) {
+	t.Parallel()
 	ctx := testCcNoVndk(t, `
 		cc_library {
 			name: "libvndk",
@@ -663,6 +673,7 @@
 }
 
 func TestVndkDepError(t *testing.T) {
+	t.Parallel()
 	// Check whether an error is emitted when a VNDK lib depends on a system lib.
 	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
 		cc_library {
@@ -842,6 +853,7 @@
 }
 
 func TestDoubleLoadbleDep(t *testing.T) {
+	t.Parallel()
 	// okay to link : LLNDK -> double_loadable VNDK
 	testCc(t, `
 		cc_library {
@@ -947,6 +959,7 @@
 }
 
 func TestVendorSnapshotCapture(t *testing.T) {
+	t.Parallel()
 	bp := `
 	cc_library {
 		name: "libvndk",
@@ -1080,6 +1093,7 @@
 }
 
 func TestVendorSnapshotUse(t *testing.T) {
+	t.Parallel()
 	frameworkBp := `
 	cc_library {
 		name: "libvndk",
@@ -1289,6 +1303,7 @@
 }
 
 func TestVendorSnapshotSanitizer(t *testing.T) {
+	t.Parallel()
 	bp := `
 	vendor_snapshot_static {
 		name: "libsnapshot",
@@ -1329,6 +1344,7 @@
 }
 
 func TestVendorSnapshotExclude(t *testing.T) {
+	t.Parallel()
 
 	// This test verifies that the exclude_from_vendor_snapshot property
 	// makes its way from the Android.bp source file into the module data
@@ -1436,6 +1452,7 @@
 }
 
 func TestVendorSnapshotExcludeInVendorProprietaryPathErrors(t *testing.T) {
+	t.Parallel()
 
 	// This test verifies that using the exclude_from_vendor_snapshot
 	// property on a module in a vendor proprietary path generates an
@@ -1476,6 +1493,7 @@
 }
 
 func TestVendorSnapshotExcludeWithVendorAvailable(t *testing.T) {
+	t.Parallel()
 
 	// This test verifies that using the exclude_from_vendor_snapshot
 	// property on a module that is vendor available generates an error. A
@@ -1519,6 +1537,7 @@
 }
 
 func TestDoubleLoadableDepError(t *testing.T) {
+	t.Parallel()
 	// Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
 	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
 		cc_library {
@@ -1639,6 +1658,7 @@
 }
 
 func TestVndkExt(t *testing.T) {
+	t.Parallel()
 	// This test checks the VNDK-Ext properties.
 	bp := `
 		cc_library {
@@ -1721,6 +1741,7 @@
 }
 
 func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
+	t.Parallel()
 	// This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
 	ctx := testCcNoVndk(t, `
 		cc_library {
@@ -1751,6 +1772,7 @@
 }
 
 func TestVndkExtWithoutProductVndkVersion(t *testing.T) {
+	t.Parallel()
 	// This test checks the VNDK-Ext properties when PRODUCT_PRODUCT_VNDK_VERSION is not set.
 	ctx := testCc(t, `
 		cc_library {
@@ -1781,6 +1803,7 @@
 }
 
 func TestVndkExtError(t *testing.T) {
+	t.Parallel()
 	// This test ensures an error is emitted in ill-formed vndk-ext definition.
 	testCcError(t, "must set `vendor: true` or `product_specific: true` to set `extends: \".*\"`", `
 		cc_library {
@@ -1866,6 +1889,7 @@
 }
 
 func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
+	t.Parallel()
 	// This test ensures an error is emitted for inconsistent support_system_process.
 	testCcError(t, "module \".*\" with mismatched support_system_process", `
 		cc_library {
@@ -1913,6 +1937,7 @@
 }
 
 func TestVndkExtVendorAvailableFalseError(t *testing.T) {
+	t.Parallel()
 	// This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
 	// with `vendor_available: false`.
 	testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
@@ -1959,6 +1984,7 @@
 }
 
 func TestVendorModuleUseVndkExt(t *testing.T) {
+	t.Parallel()
 	// This test ensures a vendor module can depend on a VNDK-Ext library.
 	testCc(t, `
 		cc_library {
@@ -2011,6 +2037,7 @@
 }
 
 func TestVndkExtUseVendorLib(t *testing.T) {
+	t.Parallel()
 	// This test ensures a VNDK-Ext library can depend on a vendor library.
 	testCc(t, `
 		cc_library {
@@ -2073,6 +2100,7 @@
 }
 
 func TestProductVndkExtDependency(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libvndk",
@@ -2138,6 +2166,7 @@
 }
 
 func TestVndkSpExtUseVndkError(t *testing.T) {
+	t.Parallel()
 	// This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
 	// library.
 	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
@@ -2220,6 +2249,7 @@
 }
 
 func TestVndkUseVndkExtError(t *testing.T) {
+	t.Parallel()
 	// This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
 	// VNDK-Ext/VNDK-SP-Ext library.
 	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
@@ -2359,6 +2389,7 @@
 }
 
 func TestEnforceProductVndkVersion(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libllndk",
@@ -2433,6 +2464,7 @@
 }
 
 func TestEnforceProductVndkVersionErrors(t *testing.T) {
+	t.Parallel()
 	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.VER", `
 		cc_library {
 			name: "libprod",
@@ -2513,6 +2545,7 @@
 }
 
 func TestMakeLinkType(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libvndk",
@@ -2706,6 +2739,7 @@
 }
 
 func TestSplitListForSize(t *testing.T) {
+	t.Parallel()
 	for _, testCase := range splitListForSizeTestCases {
 		out, _ := splitListForSize(android.PathsForTesting(testCase.in...), testCase.size)
 
@@ -2891,6 +2925,7 @@
 }
 
 func TestLinkReordering(t *testing.T) {
+	t.Parallel()
 	for _, testCase := range staticLinkDepOrderTestCases {
 		errs := []string{}
 
@@ -2953,6 +2988,7 @@
 }
 
 func TestStaticLibDepReordering(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 	cc_library {
 		name: "a",
@@ -2991,6 +3027,7 @@
 }
 
 func TestStaticLibDepReorderingWithShared(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 	cc_library {
 		name: "a",
@@ -3037,6 +3074,7 @@
 }
 
 func TestLlndkLibrary(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 	cc_library {
 		name: "libllndk",
@@ -3065,6 +3103,7 @@
 }
 
 func TestLlndkHeaders(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 	llndk_headers {
 		name: "libllndk_headers",
@@ -3158,6 +3197,7 @@
 `
 
 func TestRuntimeLibs(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, runtimeLibAndroidBp)
 
 	// runtime_libs for core variants use the module names without suffixes.
@@ -3181,6 +3221,7 @@
 }
 
 func TestExcludeRuntimeLibs(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, runtimeLibAndroidBp)
 
 	variant := "android_arm64_armv8-a_shared"
@@ -3193,6 +3234,7 @@
 }
 
 func TestRuntimeLibsNoVndk(t *testing.T) {
+	t.Parallel()
 	ctx := testCcNoVndk(t, runtimeLibAndroidBp)
 
 	// If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
@@ -3230,6 +3272,7 @@
 `
 
 func TestStaticLibDepExport(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, staticLibAndroidBp)
 
 	// Check the shared version of lib2.
@@ -3317,6 +3360,7 @@
 }
 
 func TestCompilerFlags(t *testing.T) {
+	t.Parallel()
 	for _, testCase := range compilerFlagsTestCases {
 		ctx := &mockContext{result: true}
 		CheckBadCompilerFlags(ctx, "", []string{testCase.in})
@@ -3330,6 +3374,7 @@
 }
 
 func TestVendorPublicLibraries(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 	cc_library_headers {
 		name: "libvendorpublic_headers",
@@ -3396,6 +3441,7 @@
 }
 
 func TestRecovery(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_library_shared {
 			name: "librecovery",
@@ -3431,6 +3477,7 @@
 }
 
 func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_prebuilt_test_library_shared {
 			name: "test_lib",
@@ -3477,6 +3524,7 @@
 }
 
 func TestVersionedStubs(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_library_shared {
 			name: "libFoo",
@@ -3541,6 +3589,7 @@
 }
 
 func TestVersioningMacro(t *testing.T) {
+	t.Parallel()
 	for _, tc := range []struct{ moduleName, expected string }{
 		{"libc", "__LIBC_API__"},
 		{"libfoo", "__LIBFOO_API__"},
@@ -3553,6 +3602,7 @@
 }
 
 func TestStaticExecutable(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_binary {
 			name: "static_test",
@@ -3578,6 +3628,7 @@
 }
 
 func TestStaticDepsOrderWithStubs(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_binary {
 			name: "mybin",
@@ -3618,6 +3669,7 @@
 }
 
 func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
+	t.Parallel()
 	testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
 		cc_library {
 			name: "libA",
@@ -3638,6 +3690,7 @@
 // Simple smoke test for the cc_fuzz target that ensures the rule compiles
 // correctly.
 func TestFuzzTarget(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_fuzz {
 			name: "fuzz_smoke_test",
@@ -3649,6 +3702,7 @@
 }
 
 func TestAidl(t *testing.T) {
+	t.Parallel()
 }
 
 func assertString(t *testing.T, got, expected string) {
@@ -3679,6 +3733,7 @@
 }
 
 func TestDefaults(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_defaults {
 			name: "defaults",
@@ -3743,6 +3798,7 @@
 }
 
 func TestProductVariableDefaults(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_defaults {
 			name: "libfoo_defaults",
diff --git a/cc/compiler.go b/cc/compiler.go
index bb5c7bf..21da2fc 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -652,3 +652,43 @@
 	}
 	return true
 }
+
+// Properties for rust_bindgen related to generating rust bindings.
+// This exists here so these properties can be included in a cc_default
+// which can be used in both cc and rust modules.
+type RustBindgenClangProperties struct {
+	// list of directories relative to the Blueprints file that will
+	// be added to the include path using -I
+	Local_include_dirs []string `android:"arch_variant,variant_prepend"`
+
+	// list of static libraries that provide headers for this binding.
+	Static_libs []string `android:"arch_variant,variant_prepend"`
+
+	// list of shared libraries that provide headers for this binding.
+	Shared_libs []string `android:"arch_variant"`
+
+	// list of clang flags required to correctly interpret the headers.
+	Cflags []string `android:"arch_variant"`
+
+	// list of c++ specific clang flags required to correctly interpret the headers.
+	// This is provided primarily to make sure cppflags defined in cc_defaults are pulled in.
+	Cppflags []string `android:"arch_variant"`
+
+	// C standard version to use. Can be a specific version (such as "gnu11"),
+	// "experimental" (which will use draft versions like C1x when available),
+	// or the empty string (which will use the default).
+	//
+	// If this is set, the file extension will be ignored and this will be used as the std version value. Setting this
+	// to "default" will use the build system default version. This cannot be set at the same time as cpp_std.
+	C_std *string
+
+	// C++ standard version to use. Can be a specific version (such as
+	// "gnu++11"), "experimental" (which will use draft versions like C++1z when
+	// available), or the empty string (which will use the default).
+	//
+	// If this is set, the file extension will be ignored and this will be used as the std version value. Setting this
+	// to "default" will use the build system default version. This cannot be set at the same time as c_std.
+	Cpp_std *string
+
+	//TODO(b/161141999) Add support for headers from cc_library_header modules.
+}
diff --git a/cc/compiler_test.go b/cc/compiler_test.go
index c301388..cf553bd 100644
--- a/cc/compiler_test.go
+++ b/cc/compiler_test.go
@@ -19,6 +19,7 @@
 )
 
 func TestIsThirdParty(t *testing.T) {
+	t.Parallel()
 	shouldFail := []string{
 		"external/foo/",
 		"vendor/bar/",
diff --git a/cc/config/OWNERS b/cc/config/OWNERS
index b2f54e5..701db92 100644
--- a/cc/config/OWNERS
+++ b/cc/config/OWNERS
@@ -1 +1,3 @@
 per-file vndk.go = smoreland@google.com, victoryang@google.com
+per-file clang.go,global.go = srhines@google.com, chh@google.com, pirama@google.com, yikong@google.com
+
diff --git a/cc/config/global.go b/cc/config/global.go
index f9b3cc8..97e423a 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -134,8 +134,8 @@
 
 	// prebuilts/clang default settings.
 	ClangDefaultBase         = "prebuilts/clang/host"
-	ClangDefaultVersion      = "clang-r399163"
-	ClangDefaultShortVersion = "11.0.4"
+	ClangDefaultVersion      = "clang-r399163b"
+	ClangDefaultShortVersion = "11.0.5"
 
 	// Directories with warnings from Android.bp files.
 	WarningAllowedProjects = []string{
@@ -205,6 +205,7 @@
 	pctx.PrefixedExistentPathsForSourcesVariable("CommonGlobalIncludes", "-I",
 		[]string{
 			"system/core/include",
+			"system/core/liblog/include",
 			"system/media/audio/include",
 			"hardware/libhardware/include",
 			"hardware/libhardware_legacy/include",
diff --git a/cc/config/tidy_test.go b/cc/config/tidy_test.go
index 4ed8b23..3ea2f6b 100644
--- a/cc/config/tidy_test.go
+++ b/cc/config/tidy_test.go
@@ -19,6 +19,7 @@
 )
 
 func TestTidyChecksForDir(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		input    string
 		expected string
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
index 6f2e807..d18ae25 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -25,6 +25,7 @@
 	"android.hardware.power-ndk_platform",
 	"android.hardware.rebootescrow-ndk_platform",
 	"android.hardware.vibrator-ndk_platform",
+	"android.system.keystore2-unstable-ndk_platform",
 	"libbinder",
 	"libcrypto",
 	"libexpat",
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 5295418..e81b40f 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -38,6 +38,9 @@
 	// Specify whether this fuzz target was submitted by a researcher. Defaults
 	// to false.
 	Researcher_submitted *bool `json:"researcher_submitted,omitempty"`
+	// Specify who should be acknowledged for CVEs in the Android Security
+	// Bulletin.
+	Acknowledgement []string `json:"acknowledgement,omitempty"`
 }
 
 func (f *FuzzConfig) String() string {
@@ -164,7 +167,9 @@
 // that should be installed in the fuzz target output directories. This function
 // returns true, unless:
 //  - The module is not a shared library, or
-//  - The module is a header, stub, or vendor-linked library.
+//  - The module is a header, stub, or vendor-linked library, or
+//  - The module is a prebuilt and its source is available, or
+//  - The module is a versioned member of an SDK snapshot.
 func isValidSharedDependency(dependency android.Module) bool {
 	// TODO(b/144090547): We should be parsing these modules using
 	// ModuleDependencyTag instead of the current brute-force checking.
@@ -187,6 +192,20 @@
 		}
 	}
 
+	// If the same library is present both as source and a prebuilt we must pick
+	// only one to avoid a conflict. Always prefer the source since the prebuilt
+	// probably won't be built with sanitizers enabled.
+	if prebuilt, ok := dependency.(android.PrebuiltInterface); ok &&
+		prebuilt.Prebuilt() != nil && prebuilt.Prebuilt().SourceExists() {
+		return false
+	}
+
+	// Discard versioned members of SDK snapshots, because they will conflict with
+	// unversioned ones.
+	if sdkMember, ok := dependency.(android.SdkAware); ok && !sdkMember.ContainingSdk().Unversioned() {
+		return false
+	}
+
 	return true
 }
 
diff --git a/cc/gen_test.go b/cc/gen_test.go
index 4b9a36e..ee89873 100644
--- a/cc/gen_test.go
+++ b/cc/gen_test.go
@@ -21,6 +21,7 @@
 )
 
 func TestGen(t *testing.T) {
+	t.Parallel()
 	t.Run("simple", func(t *testing.T) {
 		ctx := testCc(t, `
 		cc_library_shared {
diff --git a/cc/genrule_test.go b/cc/genrule_test.go
index a366f76..6623d20 100644
--- a/cc/genrule_test.go
+++ b/cc/genrule_test.go
@@ -30,6 +30,7 @@
 }
 
 func TestArchGenruleCmd(t *testing.T) {
+	t.Parallel()
 	fs := map[string][]byte{
 		"tool": nil,
 		"foo":  nil,
@@ -78,6 +79,7 @@
 }
 
 func TestLibraryGenruleCmd(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libboth",
diff --git a/cc/library.go b/cc/library.go
index bf7868f..35828aa 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1231,18 +1231,19 @@
 					library.baseInstaller.subDir += "-" + vndkVersion
 				}
 			}
-		} else if len(library.Properties.Stubs.Versions) > 0 && android.DirectlyInAnyApex(ctx, ctx.ModuleName()) {
+		} else if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.directlyInAnyApex() {
 			// Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory.
 			// The original path becomes a symlink to the corresponding file in the
 			// runtime APEX.
 			translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled
-			if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() && !translatedArch && !ctx.inRamdisk() && !ctx.inRecovery() {
+			if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() &&
+				!translatedArch && !ctx.inRamdisk() && !ctx.inRecovery() {
 				if ctx.Device() {
 					library.installSymlinkToRuntimeApex(ctx, file)
 				}
 				library.baseInstaller.subDir = "bootstrap"
 			}
-		} else if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && ctx.isLlndk(ctx.Config()) && !isBionic(ctx.baseModuleName()) {
+		} else if ctx.directlyInAnyApex() && ctx.isLlndk(ctx.Config()) && !isBionic(ctx.baseModuleName()) {
 			// Skip installing LLNDK (non-bionic) libraries moved to APEX.
 			ctx.Module().SkipInstall()
 		}
@@ -1531,6 +1532,8 @@
 		if variants[i] != "" {
 			m.(LinkableInterface).SetBuildStubs()
 			m.(LinkableInterface).SetStubsVersion(variants[i])
+			// The stubs depend on the implementation
+			mctx.AddInterVariantDependency(stubImplDepTag, modules[i], modules[0])
 		}
 	}
 	mctx.AliasVariation("")
@@ -1541,18 +1544,33 @@
 	mctx.CreateAliasVariation("latest", latestVersion)
 }
 
-func VersionVariantAvailable(module interface {
+func CanBeOrLinkAgainstVersionVariants(module interface {
 	Host() bool
 	InRamdisk() bool
 	InRecovery() bool
+	UseSdk() bool
 }) bool {
-	return !module.Host() && !module.InRamdisk() && !module.InRecovery()
+	return !module.Host() && !module.InRamdisk() && !module.InRecovery() && !module.UseSdk()
+}
+
+func CanBeVersionVariant(module interface {
+	Host() bool
+	InRamdisk() bool
+	InRecovery() bool
+	UseSdk() bool
+	CcLibraryInterface() bool
+	Shared() bool
+	Static() bool
+}) bool {
+	return CanBeOrLinkAgainstVersionVariants(module) &&
+		module.CcLibraryInterface() && (module.Shared() || module.Static())
 }
 
 // versionSelector normalizes the versions in the Stubs.Versions property into MutatedProperties.AllStubsVersions,
 // and propagates the value from implementation libraries to llndk libraries with the same name.
 func versionSelectorMutator(mctx android.BottomUpMutatorContext) {
-	if library, ok := mctx.Module().(LinkableInterface); ok && VersionVariantAvailable(library) {
+	if library, ok := mctx.Module().(LinkableInterface); ok && CanBeVersionVariant(library) {
+
 		if library.CcLibrary() && library.BuildSharedVariant() && len(library.StubsVersions()) > 0 &&
 			!library.IsSdkVariant() {
 
@@ -1582,7 +1600,7 @@
 // versionMutator splits a module into the mandatory non-stubs variant
 // (which is unnamed) and zero or more stubs variants.
 func versionMutator(mctx android.BottomUpMutatorContext) {
-	if library, ok := mctx.Module().(LinkableInterface); ok && VersionVariantAvailable(library) {
+	if library, ok := mctx.Module().(LinkableInterface); ok && CanBeVersionVariant(library) {
 		createVersionVariations(mctx, library.AllStubsVersions())
 	}
 }
diff --git a/cc/library_headers_test.go b/cc/library_headers_test.go
index 564ef61..db42d25 100644
--- a/cc/library_headers_test.go
+++ b/cc/library_headers_test.go
@@ -20,6 +20,7 @@
 )
 
 func TestLibraryHeaders(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 	cc_library_headers {
 		name: "headers",
@@ -41,6 +42,7 @@
 }
 
 func TestPrebuiltLibraryHeaders(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 	cc_prebuilt_library_headers {
 		name: "headers",
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index 2f15544..765fe71 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -85,8 +85,11 @@
 			variations := target.Variations()
 			if mctx.Device() {
 				variations = append(variations,
-					blueprint.Variation{Mutator: "image", Variation: android.CoreVariation},
-					blueprint.Variation{Mutator: "version", Variation: version})
+					blueprint.Variation{Mutator: "image", Variation: android.CoreVariation})
+				if mt.linkTypes != nil {
+					variations = append(variations,
+						blueprint.Variation{Mutator: "version", Variation: version})
+				}
 			}
 			if mt.linkTypes == nil {
 				mctx.AddFarVariationDependencies(variations, dependencyTag, name)
@@ -221,10 +224,7 @@
 // Add properties that may, or may not, be arch specific.
 func addPossiblyArchSpecificProperties(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, libInfo *nativeLibInfoProperties, outputProperties android.BpPropertySet) {
 
-	if libInfo.SanitizeNever {
-		sanitizeSet := outputProperties.AddPropertySet("sanitize")
-		sanitizeSet.AddProperty("never", true)
-	}
+	outputProperties.AddProperty("sanitize", &libInfo.Sanitize)
 
 	// Copy the generated library to the snapshot and add a reference to it in the .bp module.
 	if libInfo.outputFile != nil {
@@ -295,9 +295,9 @@
 		outputProperties.AddProperty(property, includeDirs[property])
 	}
 
-	if len(libInfo.StubsVersion) > 0 {
+	if len(libInfo.StubsVersions) > 0 {
 		stubsSet := outputProperties.AddPropertySet("stubs")
-		stubsSet.AddProperty("versions", []string{libInfo.StubsVersion})
+		stubsSet.AddProperty("versions", libInfo.StubsVersions)
 	}
 }
 
@@ -368,13 +368,15 @@
 	// The specific stubs version for the lib variant, or empty string if stubs
 	// are not in use.
 	//
-	// Marked 'ignored-on-host' as the StubsVersion() from which this is initialized is
-	// not set on host and the stubs.versions property which this is written to is does
-	// not vary by arch so cannot be android specific.
-	StubsVersion string `sdk:"ignored-on-host"`
+	// Marked 'ignored-on-host' as the AllStubsVersions() from which this is
+	// initialized is not set on host and the stubs.versions property which this
+	// is written to does not vary by arch so cannot be android specific.
+	StubsVersions []string `sdk:"ignored-on-host"`
 
-	// Value of SanitizeProperties.Sanitize.Never. Needs to be propagated for CRT objects.
-	SanitizeNever bool `android:"arch_variant"`
+	// Value of SanitizeProperties.Sanitize. Several - but not all - of these
+	// affect the expanded variants. All are propagated to avoid entangling the
+	// sanitizer logic with the snapshot generation.
+	Sanitize SanitizeUserProps `android:"arch_variant"`
 
 	// outputFile is not exported as it is always arch specific.
 	outputFile android.Path
@@ -420,11 +422,15 @@
 	p.exportedGeneratedHeaders = ccModule.ExportedGeneratedHeaders()
 
 	if ccModule.HasStubsVariants() {
-		p.StubsVersion = ccModule.StubsVersion()
+		// TODO(b/169373910): 1. Only output the specific version (from
+		// ccModule.StubsVersion()) if the module is versioned. 2. Ensure that all
+		// the versioned stub libs are retained in the prebuilt tree; currently only
+		// the stub corresponding to ccModule.StubsVersion() is.
+		p.StubsVersions = ccModule.AllStubsVersions()
 	}
 
-	if ccModule.sanitize != nil && proptools.Bool(ccModule.sanitize.Properties.Sanitize.Never) {
-		p.SanitizeNever = true
+	if ccModule.sanitize != nil {
+		p.Sanitize = ccModule.sanitize.Properties.Sanitize
 	}
 }
 
diff --git a/cc/library_test.go b/cc/library_test.go
index 49838b4..d42f073 100644
--- a/cc/library_test.go
+++ b/cc/library_test.go
@@ -22,6 +22,7 @@
 )
 
 func TestLibraryReuse(t *testing.T) {
+	t.Parallel()
 	t.Run("simple", func(t *testing.T) {
 		ctx := testCc(t, `
 		cc_library {
@@ -190,6 +191,7 @@
 }
 
 func TestStubsVersions(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libfoo",
@@ -213,6 +215,7 @@
 }
 
 func TestStubsVersions_NotSorted(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libfoo",
@@ -228,6 +231,7 @@
 }
 
 func TestStubsVersions_ParseError(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libfoo",
diff --git a/cc/linkable.go b/cc/linkable.go
index 6d8a4b7..a67cd4e 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -63,6 +63,8 @@
 	ToolchainLibrary() bool
 	NdkPrebuiltStl() bool
 	StubDecorator() bool
+
+	SplitPerApiLevel() bool
 }
 
 var (
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index b3f9d61..a429063 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -74,6 +74,8 @@
 
 	exportHeadersTimestamp android.OptionalPath
 	versionScriptPath      android.ModuleGenPath
+
+	movedToApex bool
 }
 
 func (stub *llndkStubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
@@ -135,6 +137,11 @@
 func (stub *llndkStubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps,
 	objs Objects) android.Path {
 
+	impl := ctx.GetDirectDepWithTag(ctx.baseModuleName(), llndkImplDep)
+	if implApexModule, ok := impl.(android.ApexModule); ok {
+		stub.movedToApex = implApexModule.DirectlyInAnyApex()
+	}
+
 	if !Bool(stub.Properties.Unversioned) {
 		linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String()
 		flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlag)
diff --git a/cc/lto.go b/cc/lto.go
index acdc767..abd8dfb 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -45,8 +45,6 @@
 		Thin  *bool `android:"arch_variant"`
 	} `android:"arch_variant"`
 
-	GlobalThin *bool `blueprint:"mutated"`
-
 	// Dep properties indicate that this module needs to be built with LTO
 	// since it is an object dependency of an LTO module.
 	FullDep bool `blueprint:"mutated"`
@@ -71,7 +69,13 @@
 	if ctx.Config().IsEnvTrue("DISABLE_LTO") {
 		lto.Properties.Lto.Never = boolPtr(true)
 	} else if ctx.Config().IsEnvTrue("GLOBAL_THINLTO") {
-		lto.Properties.GlobalThin = boolPtr(true)
+		staticLib := ctx.static() && !ctx.staticBinary()
+		hostBin := ctx.Host()
+		if !staticLib && !hostBin {
+			if !lto.Never() && !lto.FullLTO() {
+				lto.Properties.Lto.Thin = boolPtr(true)
+			}
+		}
 	}
 }
 
@@ -145,12 +149,6 @@
 }
 
 func (lto *lto) ThinLTO() bool {
-	if Bool(lto.Properties.GlobalThin) {
-		if !lto.Never() && !lto.FullLTO() {
-			return true
-		}
-	}
-
 	return Bool(lto.Properties.Lto.Thin)
 }
 
diff --git a/cc/object.go b/cc/object.go
index 778d131..ab2672b 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -96,11 +96,6 @@
 func (*objectLinker) linkerInit(ctx BaseModuleContext) {}
 
 func (object *objectLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
-	if ctx.useVndk() && ctx.toolchain().Bionic() {
-		// Needed for VNDK builds where bionic headers aren't automatically added.
-		deps.LateSharedLibs = append(deps.LateSharedLibs, "libc")
-	}
-
 	deps.HeaderLibs = append(deps.HeaderLibs, object.Properties.Header_libs...)
 	deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...)
 	return deps
diff --git a/cc/object_test.go b/cc/object_test.go
index 6ff8a00..a006044 100644
--- a/cc/object_test.go
+++ b/cc/object_test.go
@@ -19,6 +19,7 @@
 )
 
 func TestLinkerScript(t *testing.T) {
+	t.Parallel()
 	t.Run("script", func(t *testing.T) {
 		testCc(t, `
 		cc_object {
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index 52416ac..afae261 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -43,6 +43,7 @@
 }
 
 func TestPrebuilt(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "liba",
@@ -172,6 +173,7 @@
 }
 
 func TestPrebuiltLibraryShared(t *testing.T) {
+	t.Parallel()
 	ctx := testPrebuilt(t, `
 	cc_prebuilt_library_shared {
 		name: "libtest",
@@ -189,6 +191,7 @@
 }
 
 func TestPrebuiltLibraryStatic(t *testing.T) {
+	t.Parallel()
 	ctx := testPrebuilt(t, `
 	cc_prebuilt_library_static {
 		name: "libtest",
@@ -203,6 +206,7 @@
 }
 
 func TestPrebuiltLibrary(t *testing.T) {
+	t.Parallel()
 	ctx := testPrebuilt(t, `
 	cc_prebuilt_library {
 		name: "libtest",
@@ -229,6 +233,7 @@
 }
 
 func TestPrebuiltLibraryStem(t *testing.T) {
+	t.Parallel()
 	ctx := testPrebuilt(t, `
 	cc_prebuilt_library {
 		name: "libfoo",
@@ -256,6 +261,7 @@
 }
 
 func TestPrebuiltLibrarySharedStem(t *testing.T) {
+	t.Parallel()
 	ctx := testPrebuilt(t, `
 	cc_prebuilt_library_shared {
 		name: "libfoo",
@@ -274,6 +280,7 @@
 }
 
 func TestPrebuiltSymlinkedHostBinary(t *testing.T) {
+	t.Parallel()
 	if android.BuildOs != android.Linux {
 		t.Skipf("Skipping host prebuilt testing that is only supported on %s not %s", android.Linux, android.BuildOs)
 	}
diff --git a/cc/proto_test.go b/cc/proto_test.go
index f8bbd26..2d059eb 100644
--- a/cc/proto_test.go
+++ b/cc/proto_test.go
@@ -22,6 +22,7 @@
 )
 
 func TestProto(t *testing.T) {
+	t.Parallel()
 	t.Run("simple", func(t *testing.T) {
 		ctx := testCc(t, `
 		cc_library_shared {
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 174dcfe..43198c1 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -139,56 +139,59 @@
 	return t == asan || t == fuzzer || t == hwasan
 }
 
-type SanitizeProperties struct {
-	// enable AddressSanitizer, ThreadSanitizer, or UndefinedBehaviorSanitizer
-	Sanitize struct {
-		Never *bool `android:"arch_variant"`
+type SanitizeUserProps struct {
+	Never *bool `android:"arch_variant"`
 
-		// main sanitizers
-		Address   *bool `android:"arch_variant"`
-		Thread    *bool `android:"arch_variant"`
-		Hwaddress *bool `android:"arch_variant"`
+	// main sanitizers
+	Address   *bool `android:"arch_variant"`
+	Thread    *bool `android:"arch_variant"`
+	Hwaddress *bool `android:"arch_variant"`
 
-		// local sanitizers
+	// local sanitizers
+	Undefined        *bool    `android:"arch_variant"`
+	All_undefined    *bool    `android:"arch_variant"`
+	Misc_undefined   []string `android:"arch_variant"`
+	Fuzzer           *bool    `android:"arch_variant"`
+	Safestack        *bool    `android:"arch_variant"`
+	Cfi              *bool    `android:"arch_variant"`
+	Integer_overflow *bool    `android:"arch_variant"`
+	Scudo            *bool    `android:"arch_variant"`
+	Scs              *bool    `android:"arch_variant"`
+
+	// A modifier for ASAN and HWASAN for write only instrumentation
+	Writeonly *bool `android:"arch_variant"`
+
+	// Sanitizers to run in the diagnostic mode (as opposed to the release mode).
+	// Replaces abort() on error with a human-readable error message.
+	// Address and Thread sanitizers always run in diagnostic mode.
+	Diag struct {
 		Undefined        *bool    `android:"arch_variant"`
-		All_undefined    *bool    `android:"arch_variant"`
-		Misc_undefined   []string `android:"arch_variant"`
-		Fuzzer           *bool    `android:"arch_variant"`
-		Safestack        *bool    `android:"arch_variant"`
 		Cfi              *bool    `android:"arch_variant"`
 		Integer_overflow *bool    `android:"arch_variant"`
-		Scudo            *bool    `android:"arch_variant"`
-		Scs              *bool    `android:"arch_variant"`
+		Misc_undefined   []string `android:"arch_variant"`
+		No_recover       []string
+	}
 
-		// A modifier for ASAN and HWASAN for write only instrumentation
-		Writeonly *bool `android:"arch_variant"`
+	// value to pass to -fsanitize-recover=
+	Recover []string
 
-		// Sanitizers to run in the diagnostic mode (as opposed to the release mode).
-		// Replaces abort() on error with a human-readable error message.
-		// Address and Thread sanitizers always run in diagnostic mode.
-		Diag struct {
-			Undefined        *bool    `android:"arch_variant"`
-			Cfi              *bool    `android:"arch_variant"`
-			Integer_overflow *bool    `android:"arch_variant"`
-			Misc_undefined   []string `android:"arch_variant"`
-			No_recover       []string
-		}
+	// value to pass to -fsanitize-blacklist
+	Blocklist *string
+}
 
-		// value to pass to -fsanitize-recover=
-		Recover []string
-
-		// value to pass to -fsanitize-blacklist
-		Blocklist *string
-	} `android:"arch_variant"`
-
-	SanitizerEnabled  bool     `blueprint:"mutated"`
-	SanitizeDep       bool     `blueprint:"mutated"`
-	MinimalRuntimeDep bool     `blueprint:"mutated"`
-	BuiltinsDep       bool     `blueprint:"mutated"`
-	UbsanRuntimeDep   bool     `blueprint:"mutated"`
-	InSanitizerDir    bool     `blueprint:"mutated"`
-	Sanitizers        []string `blueprint:"mutated"`
-	DiagSanitizers    []string `blueprint:"mutated"`
+type SanitizeProperties struct {
+	// Enable AddressSanitizer, ThreadSanitizer, UndefinedBehaviorSanitizer, and
+	// others. Please see SanitizerUserProps in build/soong/cc/sanitize.go for
+	// details.
+	Sanitize          SanitizeUserProps `android:"arch_variant"`
+	SanitizerEnabled  bool              `blueprint:"mutated"`
+	SanitizeDep       bool              `blueprint:"mutated"`
+	MinimalRuntimeDep bool              `blueprint:"mutated"`
+	BuiltinsDep       bool              `blueprint:"mutated"`
+	UbsanRuntimeDep   bool              `blueprint:"mutated"`
+	InSanitizerDir    bool              `blueprint:"mutated"`
+	Sanitizers        []string          `blueprint:"mutated"`
+	DiagSanitizers    []string          `blueprint:"mutated"`
 }
 
 type sanitize struct {
@@ -1037,7 +1040,7 @@
 				if c.Device() {
 					variations = append(variations, c.ImageVariation())
 				}
-				mctx.AddFarVariationDependencies(variations, depTag, runtimeLibrary)
+				c.addSharedLibDependenciesWithVersions(mctx, variations, depTag, runtimeLibrary, "", true)
 			}
 			// static lib does not have dependency to the runtime library. The
 			// dependency will be added to the executables or shared libs using
diff --git a/cc/sdk.go b/cc/sdk.go
index b68baad..ec57f06 100644
--- a/cc/sdk.go
+++ b/cc/sdk.go
@@ -32,11 +32,11 @@
 	switch m := ctx.Module().(type) {
 	case LinkableInterface:
 		if m.AlwaysSdk() {
-			if !m.UseSdk() {
+			if !m.UseSdk() && !m.SplitPerApiLevel() {
 				ctx.ModuleErrorf("UseSdk() must return true when AlwaysSdk is set, did the factory forget to set Sdk_version?")
 			}
 			ctx.CreateVariations("sdk")
-		} else if m.UseSdk() {
+		} else if m.UseSdk() || m.SplitPerApiLevel() {
 			modules := ctx.CreateVariations("", "sdk")
 			modules[0].(*Module).Properties.Sdk_version = nil
 			modules[1].(*Module).Properties.IsSdkVariant = true
diff --git a/cc/sdk_test.go b/cc/sdk_test.go
index 5a3c181..7b9867c 100644
--- a/cc/sdk_test.go
+++ b/cc/sdk_test.go
@@ -21,6 +21,7 @@
 )
 
 func TestSdkMutator(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libsdk",
diff --git a/cc/snapshot_utils.go b/cc/snapshot_utils.go
index f27d166..b72af44 100644
--- a/cc/snapshot_utils.go
+++ b/cc/snapshot_utils.go
@@ -58,10 +58,10 @@
 	return snapshot, found
 }
 
-func isSnapshotAware(ctx android.ModuleContext, m *Module) bool {
-	if _, _, ok := isVndkSnapshotLibrary(ctx.DeviceConfig(), m); ok {
+func isSnapshotAware(ctx android.ModuleContext, m *Module, apexInfo android.ApexInfo) bool {
+	if _, _, ok := isVndkSnapshotLibrary(ctx.DeviceConfig(), m, apexInfo); ok {
 		return ctx.Config().VndkSnapshotBuildArtifacts()
-	} else if isVendorSnapshotModule(m, isVendorProprietaryPath(ctx.ModuleDir())) {
+	} else if isVendorSnapshotModule(m, isVendorProprietaryPath(ctx.ModuleDir()), apexInfo) {
 		return true
 	}
 	return false
diff --git a/cc/test_data_test.go b/cc/test_data_test.go
index ae59e2f..7908aa0 100644
--- a/cc/test_data_test.go
+++ b/cc/test_data_test.go
@@ -109,6 +109,7 @@
 }
 
 func TestDataTests(t *testing.T) {
+	t.Parallel()
 	buildDir, err := ioutil.TempDir("", "soong_test_test")
 	if err != nil {
 		t.Fatal(err)
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index 2819f49..529ed60 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -537,7 +537,7 @@
 // AOSP. They are not guaranteed to be compatible with older vendor images. (e.g. might
 // depend on newer VNDK) So they are captured as vendor snapshot To build older vendor
 // image and newer system image altogether.
-func isVendorSnapshotModule(m *Module, inVendorProprietaryPath bool) bool {
+func isVendorSnapshotModule(m *Module, inVendorProprietaryPath bool, apexInfo android.ApexInfo) bool {
 	if !m.Enabled() || m.Properties.HideFromMake {
 		return false
 	}
@@ -562,7 +562,7 @@
 		return false
 	}
 	// the module must be installed in /vendor
-	if !m.IsForPlatform() || m.isSnapshotPrebuilt() || !m.inVendor() {
+	if !apexInfo.IsForPlatform() || m.isSnapshotPrebuilt() || !m.inVendor() {
 		return false
 	}
 	// skip kernel_headers which always depend on vendor
@@ -825,6 +825,7 @@
 
 		moduleDir := ctx.ModuleDir(module)
 		inVendorProprietaryPath := isVendorProprietaryPath(moduleDir)
+		apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
 
 		if m.ExcludeFromVendorSnapshot() {
 			if inVendorProprietaryPath {
@@ -842,7 +843,7 @@
 			}
 		}
 
-		if !isVendorSnapshotModule(m, inVendorProprietaryPath) {
+		if !isVendorSnapshotModule(m, inVendorProprietaryPath, apexInfo) {
 			return
 		}
 
diff --git a/cc/vndk.go b/cc/vndk.go
index 9a2fa09..4169e21 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -300,6 +300,7 @@
 	if !Bool(lib.Properties.Vendor_available) {
 		vndkPrivateLibraries(mctx.Config())[name] = filename
 	}
+
 	if mctx.OtherModuleExists(name) {
 		mctx.AddFarVariationDependencies(m.Target().Variations(), llndkImplDep, name)
 	}
@@ -533,11 +534,13 @@
 	vndkSnapshotZipFile android.OptionalPath
 }
 
-func isVndkSnapshotLibrary(config android.DeviceConfig, m *Module) (i snapshotLibraryInterface, vndkType string, isVndkSnapshotLib bool) {
+func isVndkSnapshotLibrary(config android.DeviceConfig, m *Module,
+	apexInfo android.ApexInfo) (i snapshotLibraryInterface, vndkType string, isVndkSnapshotLib bool) {
+
 	if m.Target().NativeBridge == android.NativeBridgeEnabled {
 		return nil, "", false
 	}
-	if !m.inVendor() || !m.installable() || m.isSnapshotPrebuilt() {
+	if !m.inVendor() || !m.installable(apexInfo) || m.isSnapshotPrebuilt() {
 		return nil, "", false
 	}
 	l, ok := m.linker.(snapshotLibraryInterface)
@@ -659,7 +662,9 @@
 			return
 		}
 
-		l, vndkType, ok := isVndkSnapshotLibrary(ctx.DeviceConfig(), m)
+		apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
+
+		l, vndkType, ok := isVndkSnapshotLibrary(ctx.DeviceConfig(), m, apexInfo)
 		if !ok {
 			return
 		}
@@ -823,14 +828,21 @@
 func (c *vndkSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
 	// Make uses LLNDK_MOVED_TO_APEX_LIBRARIES to avoid installing libraries on /system if
 	// they been moved to an apex.
-	movedToApexLlndkLibraries := []string{}
-	for lib := range llndkLibraries(ctx.Config()) {
-		// Skip bionic libs, they are handled in different manner
-		if android.DirectlyInAnyApex(&notOnHostContext{}, lib) && !isBionic(lib) {
-			movedToApexLlndkLibraries = append(movedToApexLlndkLibraries, lib)
+	movedToApexLlndkLibraries := make(map[string]bool)
+	ctx.VisitAllModules(func(module android.Module) {
+		if m, ok := module.(*Module); ok {
+			if llndk, ok := m.linker.(*llndkStubDecorator); ok {
+				// Skip bionic libs, they are handled in different manner
+				name := m.BaseModuleName()
+				if llndk.movedToApex && !isBionic(m.BaseModuleName()) {
+					movedToApexLlndkLibraries[name] = true
+				}
+			}
 		}
-	}
-	ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES", strings.Join(movedToApexLlndkLibraries, " "))
+	})
+
+	ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES",
+		strings.Join(android.SortedStringKeys(movedToApexLlndkLibraries), " "))
 
 	// Make uses LLNDK_LIBRARIES to determine which libraries to install.
 	// HWASAN is only part of the LL-NDK in builds in which libc depends on HWASAN.
diff --git a/cmd/diff_target_files/allow_list_test.go b/cmd/diff_target_files/allow_list_test.go
index 8410e5a..9f89657 100644
--- a/cmd/diff_target_files/allow_list_test.go
+++ b/cmd/diff_target_files/allow_list_test.go
@@ -58,6 +58,7 @@
 var f2 = bytesToZipArtifactFile("dir/f2", nil)
 
 func Test_applyAllowLists(t *testing.T) {
+	t.Parallel()
 	type args struct {
 		diff       zipDiff
 		allowLists []allowList
diff --git a/cmd/diff_target_files/compare_test.go b/cmd/diff_target_files/compare_test.go
index 9d3f8a5..7621246 100644
--- a/cmd/diff_target_files/compare_test.go
+++ b/cmd/diff_target_files/compare_test.go
@@ -21,6 +21,7 @@
 )
 
 func TestDiffTargetFilesLists(t *testing.T) {
+	t.Parallel()
 	zipArtifactFile := func(name string, crc32 uint32, size uint64) *ZipArtifactFile {
 		return &ZipArtifactFile{
 			File: &zip.File{
diff --git a/cmd/diff_target_files/glob_test.go b/cmd/diff_target_files/glob_test.go
index 63df68d..f2c6c6a 100644
--- a/cmd/diff_target_files/glob_test.go
+++ b/cmd/diff_target_files/glob_test.go
@@ -19,6 +19,7 @@
 )
 
 func TestMatch(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		pattern, name string
 		match         bool
diff --git a/cmd/extract_apks/main_test.go b/cmd/extract_apks/main_test.go
index c3e6a2d..40f3882 100644
--- a/cmd/extract_apks/main_test.go
+++ b/cmd/extract_apks/main_test.go
@@ -37,6 +37,7 @@
 }
 
 func TestSelectApks_ApkSet(t *testing.T) {
+	t.Parallel()
 	testCases := []testDesc{
 		{
 			protoText: `
@@ -266,6 +267,7 @@
 }
 
 func TestSelectApks_ApexSet(t *testing.T) {
+	t.Parallel()
 	testCases := []testDesc{
 		{
 			protoText: `
@@ -442,6 +444,7 @@
 }
 
 func TestWriteApks(t *testing.T) {
+	t.Parallel()
 	testCases := []testCaseWriteApks{
 		{
 			name:       "splits",
diff --git a/cmd/extract_linker/main_test.go b/cmd/extract_linker/main_test.go
index 6ac4ec6..4e1ed02 100644
--- a/cmd/extract_linker/main_test.go
+++ b/cmd/extract_linker/main_test.go
@@ -51,6 +51,7 @@
 }
 
 func TestBytesToAsm(t *testing.T) {
+	t.Parallel()
 	for _, testcase := range bytesToAsmTestCases {
 		t.Run(testcase.name, func(t *testing.T) {
 			buf := bytes.Buffer{}
diff --git a/cmd/host_bionic_inject/host_bionic_inject_test.go b/cmd/host_bionic_inject/host_bionic_inject_test.go
index b415b34..ef5120b 100644
--- a/cmd/host_bionic_inject/host_bionic_inject_test.go
+++ b/cmd/host_bionic_inject/host_bionic_inject_test.go
@@ -100,6 +100,7 @@
 }
 
 func TestCheckLinker(t *testing.T) {
+	t.Parallel()
 	cases := []struct {
 		name   string
 		err    error
diff --git a/cmd/javac_wrapper/javac_wrapper_test.go b/cmd/javac_wrapper/javac_wrapper_test.go
index ad23001..a1812fb 100644
--- a/cmd/javac_wrapper/javac_wrapper_test.go
+++ b/cmd/javac_wrapper/javac_wrapper_test.go
@@ -93,6 +93,7 @@
 }
 
 func TestJavacColorize(t *testing.T) {
+	t.Parallel()
 	for i, test := range testCases {
 		t.Run(strconv.Itoa(i), func(t *testing.T) {
 			buf := new(bytes.Buffer)
@@ -110,6 +111,7 @@
 }
 
 func TestSubprocess(t *testing.T) {
+	t.Parallel()
 	t.Run("failure", func(t *testing.T) {
 		exitCode, err := Main(ioutil.Discard, "test", []string{"sh", "-c", "exit 9"})
 		if err != nil {
diff --git a/cmd/merge_zips/merge_zips_test.go b/cmd/merge_zips/merge_zips_test.go
index cb58436..78ffb76 100644
--- a/cmd/merge_zips/merge_zips_test.go
+++ b/cmd/merge_zips/merge_zips_test.go
@@ -85,6 +85,7 @@
 }
 
 func TestMergeZips(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name             string
 		in               [][]testZipEntry
@@ -361,6 +362,7 @@
 }
 
 func TestInputZipsManager(t *testing.T) {
+	t.Parallel()
 	const nInputZips = 20
 	const nMaxOpenZips = 10
 	izm := NewInputZipsManager(20, 10)
diff --git a/cmd/multiproduct_kati/main_test.go b/cmd/multiproduct_kati/main_test.go
index 263a124..e3ddfd7 100644
--- a/cmd/multiproduct_kati/main_test.go
+++ b/cmd/multiproduct_kati/main_test.go
@@ -21,6 +21,7 @@
 )
 
 func TestSplitList(t *testing.T) {
+	t.Parallel()
 	testcases := []struct {
 		inputCount int
 		shardCount int
diff --git a/cmd/path_interposer/main_test.go b/cmd/path_interposer/main_test.go
index c89d623..3f1a5e1 100644
--- a/cmd/path_interposer/main_test.go
+++ b/cmd/path_interposer/main_test.go
@@ -61,6 +61,7 @@
 }
 
 func TestInterposer(t *testing.T) {
+	t.Parallel()
 	interposer := setup(t)
 
 	logConfig := func(name string) paths.PathConfig {
@@ -180,6 +181,7 @@
 }
 
 func TestMissingPath(t *testing.T) {
+	t.Parallel()
 	interposer := setup(t)
 	err := os.Remove(interposer + "_origpath")
 	if err != nil {
diff --git a/cmd/soong_build/bazel_overlay_test.go b/cmd/soong_build/bazel_overlay_test.go
index f0c8515..ceb342f 100644
--- a/cmd/soong_build/bazel_overlay_test.go
+++ b/cmd/soong_build/bazel_overlay_test.go
@@ -64,6 +64,7 @@
 }
 
 func TestGenerateBazelOverlayFromBlueprint(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		bp                  string
 		expectedBazelTarget string
diff --git a/cmd/zip2zip/zip2zip_test.go b/cmd/zip2zip/zip2zip_test.go
index 2c4e005..e6ac0bf 100644
--- a/cmd/zip2zip/zip2zip_test.go
+++ b/cmd/zip2zip/zip2zip_test.go
@@ -416,6 +416,7 @@
 }
 
 func TestZip2Zip(t *testing.T) {
+	t.Parallel()
 	for _, testCase := range testCases {
 		t.Run(testCase.name, func(t *testing.T) {
 			inputBuf := &bytes.Buffer{}
@@ -472,6 +473,7 @@
 }
 
 func TestConstantPartOfPattern(t *testing.T) {
+	t.Parallel()
 	testCases := []struct{ in, out string }{
 		{
 			in:  "",
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 4dbda49..814b75d 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -218,13 +218,21 @@
 	return m[sdkVer]
 }
 
-func (m classLoaderContextMap) addLibs(sdkVer int, module *ModuleConfig, libs ...string) bool {
+func (m classLoaderContextMap) addLibs(ctx android.PathContext, sdkVer int, module *ModuleConfig, libs ...string) bool {
 	clc := m.getValue(sdkVer)
 	for _, lib := range libs {
-		if p := pathForLibrary(module, lib); p != nil {
+		if p, ok := module.LibraryPaths[lib]; ok && p.Host != nil && p.Device != UnknownInstallLibraryPath {
 			clc.Host = append(clc.Host, p.Host)
 			clc.Target = append(clc.Target, p.Device)
 		} else {
+			if sdkVer == anySdkVersion {
+				// Fail the build if dexpreopt doesn't know paths to one of the <uses-library>
+				// dependencies. In the future we may need to relax this and just disable dexpreopt.
+				android.ReportPathErrorf(ctx, "dexpreopt cannot find path for <uses-library> '%s'", lib)
+			} else {
+				// No error for compatibility libraries, as Soong doesn't know if they are needed
+				// (this depends on the targetSdkVersion in the manifest).
+			}
 			return false
 		}
 	}
@@ -270,14 +278,14 @@
 	} else if module.EnforceUsesLibraries {
 		// Unconditional class loader context.
 		usesLibs := append(copyOf(module.UsesLibraries), module.OptionalUsesLibraries...)
-		if !classLoaderContexts.addLibs(anySdkVersion, module, usesLibs...) {
+		if !classLoaderContexts.addLibs(ctx, anySdkVersion, module, usesLibs...) {
 			return nil
 		}
 
 		// Conditional class loader context for API version < 28.
 		const httpLegacy = "org.apache.http.legacy"
 		if !contains(usesLibs, httpLegacy) {
-			if !classLoaderContexts.addLibs(28, module, httpLegacy) {
+			if !classLoaderContexts.addLibs(ctx, 28, module, httpLegacy) {
 				return nil
 			}
 		}
@@ -287,14 +295,14 @@
 			"android.hidl.base-V1.0-java",
 			"android.hidl.manager-V1.0-java",
 		}
-		if !classLoaderContexts.addLibs(29, module, usesLibs29...) {
+		if !classLoaderContexts.addLibs(ctx, 29, module, usesLibs29...) {
 			return nil
 		}
 
 		// Conditional class loader context for API version < 30.
 		const testBase = "android.test.base"
 		if !contains(usesLibs, testBase) {
-			if !classLoaderContexts.addLibs(30, module, testBase) {
+			if !classLoaderContexts.addLibs(ctx, 30, module, testBase) {
 				return nil
 			}
 		}
@@ -589,14 +597,6 @@
 	return filepath.Join(filepath.Dir(filepath.Dir(path.String())), filepath.Base(path.String()))
 }
 
-func pathForLibrary(module *ModuleConfig, lib string) *LibraryPath {
-	if path, ok := module.LibraryPaths[lib]; ok && path.Host != nil && path.Device != "error" {
-		return path
-	} else {
-		return nil
-	}
-}
-
 func makefileMatch(pattern, s string) bool {
 	percent := strings.IndexByte(pattern, '%')
 	switch percent {
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index ec31549..1fbd7f1 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -61,6 +61,7 @@
 }
 
 func TestDexPreopt(t *testing.T) {
+	t.Parallel()
 	config := android.TestConfig("out", nil, "", nil)
 	ctx := android.PathContextForTesting(config)
 	globalSoong := GlobalSoongConfigForTests(config)
@@ -83,6 +84,7 @@
 }
 
 func TestDexPreoptSystemOther(t *testing.T) {
+	t.Parallel()
 	config := android.TestConfig("out", nil, "", nil)
 	ctx := android.PathContextForTesting(config)
 	globalSoong := GlobalSoongConfigForTests(config)
@@ -143,6 +145,7 @@
 }
 
 func TestDexPreoptProfile(t *testing.T) {
+	t.Parallel()
 	config := android.TestConfig("out", nil, "", nil)
 	ctx := android.PathContextForTesting(config)
 	globalSoong := GlobalSoongConfigForTests(config)
diff --git a/docs/OWNERS b/docs/OWNERS
new file mode 100644
index 0000000..d143317
--- /dev/null
+++ b/docs/OWNERS
@@ -0,0 +1 @@
+per-file map_files.md = danalbert@google.com, enh@google.com, jiyong@google.com
diff --git a/etc/prebuilt_etc_test.go b/etc/prebuilt_etc_test.go
index 8fc36c2..528c484 100644
--- a/etc/prebuilt_etc_test.go
+++ b/etc/prebuilt_etc_test.go
@@ -102,6 +102,7 @@
 	t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
 }
 func TestPrebuiltEtcVariants(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testPrebuiltEtc(t, `
 		prebuilt_etc {
 			name: "foo.conf",
@@ -136,6 +137,7 @@
 }
 
 func TestPrebuiltEtcOutputPath(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testPrebuiltEtc(t, `
 		prebuilt_etc {
 			name: "foo.conf",
@@ -151,6 +153,7 @@
 }
 
 func TestPrebuiltEtcGlob(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testPrebuiltEtc(t, `
 		prebuilt_etc {
 			name: "my_foo",
@@ -175,6 +178,7 @@
 }
 
 func TestPrebuiltEtcAndroidMk(t *testing.T) {
+	t.Parallel()
 	ctx, config := testPrebuiltEtc(t, `
 		prebuilt_etc {
 			name: "foo",
@@ -211,6 +215,7 @@
 }
 
 func TestPrebuiltEtcRelativeInstallPathInstallDirPath(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testPrebuiltEtc(t, `
 		prebuilt_etc {
 			name: "foo.conf",
@@ -227,6 +232,7 @@
 }
 
 func TestPrebuiltEtcCannotSetRelativeInstallPathAndSubDir(t *testing.T) {
+	t.Parallel()
 	testPrebuiltEtcError(t, "relative_install_path is set. Cannot set sub_dir", `
 		prebuilt_etc {
 			name: "foo.conf",
@@ -238,6 +244,7 @@
 }
 
 func TestPrebuiltEtcHost(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testPrebuiltEtc(t, `
 		prebuilt_etc_host {
 			name: "foo.conf",
@@ -253,6 +260,7 @@
 }
 
 func TestPrebuiltUserShareInstallDirPath(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testPrebuiltEtc(t, `
 		prebuilt_usr_share {
 			name: "foo.conf",
@@ -269,6 +277,7 @@
 }
 
 func TestPrebuiltUserShareHostInstallDirPath(t *testing.T) {
+	t.Parallel()
 	ctx, config := testPrebuiltEtc(t, `
 		prebuilt_usr_share_host {
 			name: "foo.conf",
@@ -286,6 +295,7 @@
 }
 
 func TestPrebuiltFontInstallDirPath(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testPrebuiltEtc(t, `
 		prebuilt_font {
 			name: "foo.conf",
@@ -301,6 +311,7 @@
 }
 
 func TestPrebuiltFirmwareDirPath(t *testing.T) {
+	t.Parallel()
 	targetPath := buildDir + "/target/product/test_device"
 	tests := []struct {
 		description  string
@@ -337,6 +348,7 @@
 }
 
 func TestPrebuiltDSPDirPath(t *testing.T) {
+	t.Parallel()
 	targetPath := filepath.Join(buildDir, "/target/product/test_device")
 	tests := []struct {
 		description  string
diff --git a/finder/finder_test.go b/finder/finder_test.go
index 88b0c05..029c80f 100644
--- a/finder/finder_test.go
+++ b/finder/finder_test.go
@@ -122,6 +122,7 @@
 // end of utils, start of individual tests
 
 func TestSingleFile(t *testing.T) {
+	t.Parallel()
 	runSimpleTest(t,
 		[]string{"findme.txt"},
 		[]string{"findme.txt"},
@@ -129,6 +130,7 @@
 }
 
 func TestIncludeFiles(t *testing.T) {
+	t.Parallel()
 	runSimpleTest(t,
 		[]string{"findme.txt", "skipme.txt"},
 		[]string{"findme.txt"},
@@ -136,6 +138,7 @@
 }
 
 func TestNestedDirectories(t *testing.T) {
+	t.Parallel()
 	runSimpleTest(t,
 		[]string{"findme.txt", "skipme.txt", "subdir/findme.txt", "subdir/skipme.txt"},
 		[]string{"findme.txt", "subdir/findme.txt"},
@@ -143,6 +146,7 @@
 }
 
 func TestEmptyDirectory(t *testing.T) {
+	t.Parallel()
 	runSimpleTest(t,
 		[]string{},
 		[]string{},
@@ -150,6 +154,7 @@
 }
 
 func TestEmptyPath(t *testing.T) {
+	t.Parallel()
 	filesystem := newFs()
 	root := "/tmp"
 	fs.Create(t, filepath.Join(root, "findme.txt"), filesystem)
@@ -170,6 +175,7 @@
 }
 
 func TestFilesystemRoot(t *testing.T) {
+	t.Parallel()
 
 	testWithNumThreads := func(t *testing.T, numThreads int) {
 		filesystem := newFs()
@@ -197,6 +203,7 @@
 }
 
 func TestNonexistentDir(t *testing.T) {
+	t.Parallel()
 	filesystem := newFs()
 	fs.Create(t, "/tmp/findme.txt", filesystem)
 
@@ -215,6 +222,7 @@
 }
 
 func TestExcludeDirs(t *testing.T) {
+	t.Parallel()
 	filesystem := newFs()
 	fs.Create(t, "/tmp/exclude/findme.txt", filesystem)
 	fs.Create(t, "/tmp/exclude/subdir/findme.txt", filesystem)
@@ -243,6 +251,7 @@
 }
 
 func TestPruneFiles(t *testing.T) {
+	t.Parallel()
 	filesystem := newFs()
 	fs.Create(t, "/tmp/out/findme.txt", filesystem)
 	fs.Create(t, "/tmp/out/.ignore-out-dir", filesystem)
@@ -275,6 +284,7 @@
 // TestRootDir tests that the value of RootDirs is used
 // tests of the filesystem root are in TestFilesystemRoot
 func TestRootDir(t *testing.T) {
+	t.Parallel()
 	filesystem := newFs()
 	fs.Create(t, "/tmp/a/findme.txt", filesystem)
 	fs.Create(t, "/tmp/a/subdir/findme.txt", filesystem)
@@ -299,6 +309,7 @@
 }
 
 func TestUncachedDir(t *testing.T) {
+	t.Parallel()
 	filesystem := newFs()
 	fs.Create(t, "/tmp/a/findme.txt", filesystem)
 	fs.Create(t, "/tmp/a/subdir/findme.txt", filesystem)
@@ -326,6 +337,7 @@
 }
 
 func TestSearchingForFilesExcludedFromCache(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/findme.txt", filesystem)
@@ -353,6 +365,7 @@
 }
 
 func TestRelativeFilePaths(t *testing.T) {
+	t.Parallel()
 	filesystem := newFs()
 
 	fs.Create(t, "/tmp/ignore/hi.txt", filesystem)
@@ -397,6 +410,7 @@
 // have to run this test with the race-detector (`go test -race src/android/soong/finder/*.go`)
 // for there to be much chance of the test actually detecting any error that may be present
 func TestRootDirsContainedInOtherRootDirs(t *testing.T) {
+	t.Parallel()
 	filesystem := newFs()
 
 	fs.Create(t, "/tmp/a/b/c/d/e/f/g/h/i/j/findme.txt", filesystem)
@@ -418,6 +432,7 @@
 }
 
 func TestFindFirst(t *testing.T) {
+	t.Parallel()
 	filesystem := newFs()
 	fs.Create(t, "/tmp/a/hi.txt", filesystem)
 	fs.Create(t, "/tmp/b/hi.txt", filesystem)
@@ -442,6 +457,7 @@
 }
 
 func TestConcurrentFindSameDirectory(t *testing.T) {
+	t.Parallel()
 
 	testWithNumThreads := func(t *testing.T, numThreads int) {
 		filesystem := newFs()
@@ -493,6 +509,7 @@
 }
 
 func TestConcurrentFindDifferentDirectories(t *testing.T) {
+	t.Parallel()
 	filesystem := newFs()
 
 	// create a bunch of files and directories
@@ -556,6 +573,7 @@
 }
 
 func TestStrangelyFormattedPaths(t *testing.T) {
+	t.Parallel()
 	filesystem := newFs()
 
 	fs.Create(t, "/tmp/findme.txt", filesystem)
@@ -581,6 +599,7 @@
 }
 
 func TestCorruptedCacheHeader(t *testing.T) {
+	t.Parallel()
 	filesystem := newFs()
 
 	fs.Create(t, "/tmp/findme.txt", filesystem)
@@ -605,6 +624,7 @@
 }
 
 func TestCanUseCache(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/findme.txt", filesystem)
@@ -651,6 +671,7 @@
 }
 
 func TestCorruptedCacheBody(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/findme.txt", filesystem)
@@ -715,6 +736,7 @@
 }
 
 func TestStatCalls(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/a/findme.txt", filesystem)
@@ -738,6 +760,7 @@
 }
 
 func TestFileAdded(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/ignoreme.txt", filesystem)
@@ -780,6 +803,7 @@
 }
 
 func TestDirectoriesAdded(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/ignoreme.txt", filesystem)
@@ -824,6 +848,7 @@
 }
 
 func TestDirectoryAndSubdirectoryBothUpdated(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/hi1.txt", filesystem)
@@ -864,6 +889,7 @@
 }
 
 func TestFileDeleted(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/ignoreme.txt", filesystem)
@@ -904,6 +930,7 @@
 }
 
 func TestDirectoriesDeleted(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/findme.txt", filesystem)
@@ -959,6 +986,7 @@
 }
 
 func TestDirectoriesMoved(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/findme.txt", filesystem)
@@ -1017,6 +1045,7 @@
 }
 
 func TestDirectoriesSwapped(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/findme.txt", filesystem)
@@ -1132,6 +1161,7 @@
 }
 
 func TestChangeOfDevice(t *testing.T) {
+	t.Parallel()
 	fs1 := newFs()
 	// not as fine-grained mounting controls as a real filesystem, but should be adequate
 	fs1.SetDeviceNumber(0)
@@ -1143,6 +1173,7 @@
 }
 
 func TestChangeOfUserOrHost(t *testing.T) {
+	t.Parallel()
 	fs1 := newFs()
 	fs1.SetViewId("me@here")
 
@@ -1153,6 +1184,7 @@
 }
 
 func TestConsistentCacheOrdering(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	for i := 0; i < 5; i++ {
@@ -1205,6 +1237,7 @@
 }
 
 func TestNumSyscallsOfSecondFind(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/findme.txt", filesystem)
@@ -1235,6 +1268,7 @@
 }
 
 func TestChangingParamsOfSecondFind(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/findme.txt", filesystem)
@@ -1265,6 +1299,7 @@
 }
 
 func TestSymlinkPointingToFile(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/a/hi.txt", filesystem)
@@ -1301,6 +1336,7 @@
 }
 
 func TestSymlinkPointingToDirectory(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/dir/hi.txt", filesystem)
@@ -1335,6 +1371,7 @@
 // TestAddPruneFile confirms that adding a prune-file (into a directory for which we
 // already had a cache) causes the directory to be ignored
 func TestAddPruneFile(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/out/hi.txt", filesystem)
@@ -1373,6 +1410,7 @@
 }
 
 func TestUpdatingDbIffChanged(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/a/hi.txt", filesystem)
@@ -1432,6 +1470,7 @@
 }
 
 func TestDirectoryNotPermitted(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/hi.txt", filesystem)
@@ -1480,6 +1519,7 @@
 }
 
 func TestFileNotPermitted(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/hi.txt", filesystem)
@@ -1502,6 +1542,7 @@
 }
 
 func TestCacheEntryPathUnexpectedError(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := newFs()
 	fs.Create(t, "/tmp/a/hi.txt", filesystem)
diff --git a/finder/fs/fs_test.go b/finder/fs/fs_test.go
index 22a4d7a..5671bcf 100644
--- a/finder/fs/fs_test.go
+++ b/finder/fs/fs_test.go
@@ -20,6 +20,7 @@
 )
 
 func TestMockFs_LstatStatSymlinks(t *testing.T) {
+	t.Parallel()
 	// setup filesystem
 	filesystem := NewMockFs(nil)
 	Create(t, "/tmp/realdir/hi.txt", filesystem)
diff --git a/finder/fs/readdir_test.go b/finder/fs/readdir_test.go
index 24a6d18..d133bba 100644
--- a/finder/fs/readdir_test.go
+++ b/finder/fs/readdir_test.go
@@ -22,6 +22,7 @@
 )
 
 func TestParseDirent(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name string
 		in   []byte
diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go
index c692019..a7af4db 100644
--- a/genrule/genrule_test.go
+++ b/genrule/genrule_test.go
@@ -125,6 +125,7 @@
 }
 
 func TestGenruleCmd(t *testing.T) {
+	t.Parallel()
 	testcases := []struct {
 		name string
 		prop string
@@ -503,6 +504,7 @@
 }
 
 func TestGenruleHashInputs(t *testing.T) {
+	t.Parallel()
 
 	// The basic idea here is to verify that the sbox command (which is
 	// in the Command field of the generate rule) contains a hash of the
@@ -590,6 +592,7 @@
 }
 
 func TestGenSrcs(t *testing.T) {
+	t.Parallel()
 	testcases := []struct {
 		name string
 		prop string
@@ -682,6 +685,7 @@
 }
 
 func TestGenruleDefaults(t *testing.T) {
+	t.Parallel()
 	bp := `
 				genrule_defaults {
 					name: "gen_defaults1",
diff --git a/jar/jar_test.go b/jar/jar_test.go
index c92011e..f1c799b 100644
--- a/jar/jar_test.go
+++ b/jar/jar_test.go
@@ -21,6 +21,7 @@
 )
 
 func TestGetJavaPackage(t *testing.T) {
+	t.Parallel()
 	type args struct {
 		r   io.Reader
 		src string
@@ -78,6 +79,7 @@
 }
 
 func Test_javaIdentRune(t *testing.T) {
+	t.Parallel()
 	// runes that should be valid anywhere in an identifier
 	validAnywhere := []rune{
 		// letters, $, _
diff --git a/java/aar.go b/java/aar.go
index 9cab0bd..8d2a74a 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -477,6 +477,8 @@
 	a.aapt.buildActions(ctx, sdkContext(a))
 	a.exportedSdkLibs = a.aapt.sdkLibraries
 
+	a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
+
 	ctx.CheckbuildFile(a.proguardOptionsFile)
 	ctx.CheckbuildFile(a.exportPackage)
 	ctx.CheckbuildFile(a.aaptSrcJar)
@@ -569,6 +571,8 @@
 	manifest              android.WritablePath
 
 	exportedStaticPackages android.Paths
+
+	hideApexVariantFromMake bool
 }
 
 func (a *AARImport) sdkVersion() sdkSpec {
@@ -662,6 +666,8 @@
 		return
 	}
 
+	a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
+
 	aarName := ctx.ModuleName() + ".aar"
 	var aar android.Path
 	aar = android.PathForModuleSrc(ctx, a.properties.Aars[0])
diff --git a/java/androidmk.go b/java/androidmk.go
index 65c44a3..f72ee37 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -23,8 +23,7 @@
 
 func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries {
 	hostDexNeeded := Bool(library.deviceProperties.Hostdex) && !library.Host()
-	if !library.IsForPlatform() {
-		// Don't emit hostdex modules from the APEX variants
+	if library.hideApexVariantFromMake {
 		hostDexNeeded = false
 	}
 
@@ -61,22 +60,15 @@
 func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
 	var entriesList []android.AndroidMkEntries
 
-	mainEntries := android.AndroidMkEntries{Disabled: true}
-
-	// For a java library built for an APEX, we don't need Make module
-	hideFromMake := !library.IsForPlatform()
-	// If not available for platform, don't emit to make.
-	if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) {
-		hideFromMake = true
-	}
-	if hideFromMake {
-		// May still need to add some additional dependencies. This will be called
-		// once for the platform variant (even if it is not being used) and once each
-		// for the APEX specific variants. In order to avoid adding the dependency
-		// multiple times only add it for the platform variant.
+	if library.hideApexVariantFromMake {
+		// For a java library built for an APEX we don't need Make module
+		entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
+	} else if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) {
+		// Platform variant.  If not available for the platform, we don't need Make module.
+		// May still need to add some additional dependencies.
 		checkedModulePaths := library.additionalCheckedModules
-		if library.IsForPlatform() && len(checkedModulePaths) != 0 {
-			mainEntries = android.AndroidMkEntries{
+		if len(checkedModulePaths) != 0 {
+			entriesList = append(entriesList, android.AndroidMkEntries{
 				Class: "FAKE",
 				// Need at least one output file in order for this to take effect.
 				OutputFile: android.OptionalPathForPath(checkedModulePaths[0]),
@@ -86,10 +78,12 @@
 						entries.AddStrings("LOCAL_ADDITIONAL_CHECKED_MODULE", checkedModulePaths.Strings()...)
 					},
 				},
-			}
+			})
+		} else {
+			entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
 		}
 	} else {
-		mainEntries = android.AndroidMkEntries{
+		entriesList = append(entriesList, android.AndroidMkEntries{
 			Class:      "JAVA_LIBRARIES",
 			DistFiles:  library.distFiles,
 			OutputFile: android.OptionalPathForPath(library.outputFile),
@@ -134,12 +128,11 @@
 					entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", library.linter.reports)
 				},
 			},
-		}
+		})
 	}
 
-	hostDexEntries := library.AndroidMkEntriesHostDex()
+	entriesList = append(entriesList, library.AndroidMkEntriesHostDex())
 
-	entriesList = append(entriesList, mainEntries, hostDexEntries)
 	return entriesList
 }
 
@@ -189,7 +182,7 @@
 }
 
 func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries {
-	if !prebuilt.IsForPlatform() || !prebuilt.ContainingSdk().Unversioned() {
+	if prebuilt.hideApexVariantFromMake || !prebuilt.ContainingSdk().Unversioned() {
 		return []android.AndroidMkEntries{android.AndroidMkEntries{
 			Disabled: true,
 		}}
@@ -211,7 +204,7 @@
 }
 
 func (prebuilt *DexImport) AndroidMkEntries() []android.AndroidMkEntries {
-	if !prebuilt.IsForPlatform() {
+	if prebuilt.hideApexVariantFromMake {
 		return []android.AndroidMkEntries{android.AndroidMkEntries{
 			Disabled: true,
 		}}
@@ -239,7 +232,7 @@
 }
 
 func (prebuilt *AARImport) AndroidMkEntries() []android.AndroidMkEntries {
-	if !prebuilt.IsForPlatform() {
+	if prebuilt.hideApexVariantFromMake {
 		return []android.AndroidMkEntries{{
 			Disabled: true,
 		}}
@@ -309,7 +302,7 @@
 }
 
 func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
-	if !app.IsForPlatform() || app.appProperties.HideFromMake {
+	if app.hideApexVariantFromMake || app.appProperties.HideFromMake {
 		return []android.AndroidMkEntries{android.AndroidMkEntries{
 			Disabled: true,
 		}}
@@ -458,7 +451,7 @@
 }
 
 func (a *AndroidLibrary) AndroidMkEntries() []android.AndroidMkEntries {
-	if !a.IsForPlatform() {
+	if a.hideApexVariantFromMake {
 		return []android.AndroidMkEntries{{
 			Disabled: true,
 		}}
@@ -638,7 +631,7 @@
 }
 
 func (a *AndroidAppImport) AndroidMkEntries() []android.AndroidMkEntries {
-	if !a.IsForPlatform() {
+	if a.hideApexVariantFromMake {
 		// The non-platform variant is placed inside APEX. No reason to
 		// make it available to Make.
 		return nil
diff --git a/java/androidmk_test.go b/java/androidmk_test.go
index 075b7aa..359d8d7 100644
--- a/java/androidmk_test.go
+++ b/java/androidmk_test.go
@@ -23,6 +23,7 @@
 )
 
 func TestRequired(t *testing.T) {
+	t.Parallel()
 	ctx, config := testJava(t, `
 		java_library {
 			name: "foo",
@@ -42,6 +43,7 @@
 }
 
 func TestHostdex(t *testing.T) {
+	t.Parallel()
 	ctx, config := testJava(t, `
 		java_library {
 			name: "foo",
@@ -72,6 +74,7 @@
 }
 
 func TestHostdexRequired(t *testing.T) {
+	t.Parallel()
 	ctx, config := testJava(t, `
 		java_library {
 			name: "foo",
@@ -103,6 +106,7 @@
 }
 
 func TestHostdexSpecificRequired(t *testing.T) {
+	t.Parallel()
 	ctx, config := testJava(t, `
 		java_library {
 			name: "foo",
@@ -136,6 +140,7 @@
 }
 
 func TestDistWithTag(t *testing.T) {
+	t.Parallel()
 	ctx, config := testJava(t, `
 		java_library {
 			name: "foo_without_tag",
@@ -172,6 +177,7 @@
 }
 
 func TestDistWithDest(t *testing.T) {
+	t.Parallel()
 	ctx, config := testJava(t, `
 		java_library {
 			name: "foo",
@@ -208,6 +214,7 @@
 }
 
 func TestDistsWithAllProperties(t *testing.T) {
+	t.Parallel()
 	ctx, config := testJava(t, `
 		java_library {
 			name: "foo",
@@ -265,6 +272,7 @@
 }
 
 func TestDistsWithTag(t *testing.T) {
+	t.Parallel()
 	ctx, config := testJava(t, `
 		java_library {
 			name: "foo_without_tag",
@@ -312,6 +320,7 @@
 }
 
 func TestJavaSdkLibrary_RequireXmlPermissionFile(t *testing.T) {
+	t.Parallel()
 	ctx, config := testJava(t, `
 		java_sdk_library {
 			name: "foo-shared_library",
diff --git a/java/app.go b/java/app.go
index 13d08b9..c25835c 100755
--- a/java/app.go
+++ b/java/app.go
@@ -480,8 +480,9 @@
 		ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.minSdkVersion(), err)
 	}
 
+	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
 	return (minSdkVersion >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
-		!a.IsForPlatform()
+		!apexInfo.IsForPlatform()
 }
 
 // Returns whether this module should have the dex file stored uncompressed in the APK.
@@ -504,8 +505,9 @@
 }
 
 func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
+	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
 	return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
-		!a.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs
+		!apexInfo.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs
 }
 
 func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
@@ -756,6 +758,10 @@
 func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
 	var apkDeps android.Paths
 
+	if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() {
+		a.hideApexVariantFromMake = true
+	}
+
 	a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
 	a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
 
@@ -850,8 +856,10 @@
 	BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
 	a.bundleFile = bundleFile
 
+	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+
 	// Install the app package.
-	if (Bool(a.Module.properties.Installable) || ctx.Host()) && a.IsForPlatform() {
+	if (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() {
 		ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile)
 		for _, extra := range a.extraOutputFiles {
 			ctx.InstallFile(a.installDir, extra.Base(), extra)
@@ -979,7 +987,7 @@
 }
 
 func (a *AndroidApp) Updatable() bool {
-	return Bool(a.appProperties.Updatable) || a.ApexModuleBase.Updatable()
+	return Bool(a.appProperties.Updatable)
 }
 
 func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
@@ -1335,6 +1343,8 @@
 	preprocessed bool
 
 	installPath android.InstallPath
+
+	hideApexVariantFromMake bool
 }
 
 type AndroidAppImportProperties struct {
@@ -1481,6 +1491,11 @@
 }
 
 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++
@@ -1569,7 +1584,7 @@
 
 	// TODO: Optionally compress the output apk.
 
-	if a.IsForPlatform() {
+	if apexInfo.IsForPlatform() {
 		a.installPath = ctx.InstallFile(installDir, apkFilename, a.outputFile)
 	}
 
diff --git a/java/app_test.go b/java/app_test.go
index 4347db8..f894379 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -67,6 +67,7 @@
 }
 
 func TestApp(t *testing.T) {
+	t.Parallel()
 	for _, moduleType := range []string{"android_app", "android_library"} {
 		t.Run(moduleType, func(t *testing.T) {
 			ctx := testApp(t, moduleType+` {
@@ -113,6 +114,7 @@
 }
 
 func TestAppSplits(t *testing.T) {
+	t.Parallel()
 	ctx := testApp(t, `
 				android_app {
 					name: "foo",
@@ -142,6 +144,7 @@
 }
 
 func TestAndroidAppSet(t *testing.T) {
+	t.Parallel()
 	ctx, config := testJava(t, `
 		android_app_set {
 			name: "foo",
@@ -170,6 +173,7 @@
 }
 
 func TestAndroidAppSet_Variants(t *testing.T) {
+	t.Parallel()
 	bp := `
 		android_app_set {
 			name: "foo",
@@ -235,6 +239,7 @@
 }
 
 func TestPlatformAPIs(t *testing.T) {
+	t.Parallel()
 	testJava(t, `
 		android_app {
 			name: "foo",
@@ -269,6 +274,7 @@
 }
 
 func TestAndroidAppLinkType(t *testing.T) {
+	t.Parallel()
 	testJava(t, `
 		android_app {
 			name: "foo",
@@ -358,6 +364,7 @@
 }
 
 func TestUpdatableApps(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name          string
 		bp            string
@@ -479,6 +486,7 @@
 }
 
 func TestUpdatableApps_TransitiveDepsShouldSetMinSdkVersion(t *testing.T) {
+	t.Parallel()
 	testJavaError(t, `module "bar".*: should support min_sdk_version\(29\)`, cc.GatherRequiredDepsForTest(android.Android)+`
 		android_app {
 			name: "foo",
@@ -497,6 +505,7 @@
 }
 
 func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion(t *testing.T) {
+	t.Parallel()
 	testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
 		android_app {
 			name: "foo",
@@ -517,6 +526,7 @@
 }
 
 func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) {
+	t.Parallel()
 	bp := cc.GatherRequiredDepsForTest(android.Android) + `
 		android_app {
 			name: "foo",
@@ -571,6 +581,7 @@
 }
 
 func TestUpdatableApps_ErrorIfJniLibDoesntSupportMinSdkVersion(t *testing.T) {
+	t.Parallel()
 	bp := cc.GatherRequiredDepsForTest(android.Android) + `
 		android_app {
 			name: "foo",
@@ -591,6 +602,7 @@
 }
 
 func TestUpdatableApps_ErrorIfDepSdkVersionIsHigher(t *testing.T) {
+	t.Parallel()
 	bp := cc.GatherRequiredDepsForTest(android.Android) + `
 		android_app {
 			name: "foo",
@@ -620,6 +632,7 @@
 }
 
 func TestResourceDirs(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name      string
 		prop      string
@@ -679,6 +692,7 @@
 }
 
 func TestLibraryAssets(t *testing.T) {
+	t.Parallel()
 	bp := `
 			android_app {
 				name: "foo",
@@ -780,6 +794,7 @@
 }
 
 func TestAndroidResources(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name                       string
 		enforceRROTargets          []string
@@ -1070,6 +1085,7 @@
 }
 
 func TestAppSdkVersion(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name                  string
 		sdkVersion            string
@@ -1152,6 +1168,7 @@
 }
 
 func TestVendorAppSdkVersion(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name                                  string
 		sdkVersion                            string
@@ -1215,6 +1232,7 @@
 }
 
 func TestJNIABI(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
 		cc_library {
 			name: "libjni",
@@ -1289,6 +1307,7 @@
 }
 
 func TestAppSdkVersionByPartition(t *testing.T) {
+	t.Parallel()
 	testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
 		android_app {
 			name: "foo",
@@ -1327,6 +1346,7 @@
 }
 
 func TestJNIPackaging(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
 		cc_library {
 			name: "libjni",
@@ -1418,6 +1438,7 @@
 }
 
 func TestJNISDK(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
 		cc_library {
 			name: "libjni",
@@ -1535,6 +1556,7 @@
 }
 
 func TestCertificates(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name                string
 		bp                  string
@@ -1655,6 +1677,7 @@
 }
 
 func TestRequestV4SigningFlag(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name     string
 		bp       string
@@ -1715,6 +1738,7 @@
 }
 
 func TestPackageNameOverride(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name                string
 		bp                  string
@@ -1780,6 +1804,7 @@
 }
 
 func TestInstrumentationTargetOverridden(t *testing.T) {
+	t.Parallel()
 	bp := `
 		android_app {
 			name: "foo",
@@ -1809,6 +1834,7 @@
 }
 
 func TestOverrideAndroidApp(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		android_app {
 			name: "foo",
@@ -2010,6 +2036,7 @@
 }
 
 func TestOverrideAndroidAppDependency(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		android_app {
 			name: "foo",
@@ -2052,6 +2079,7 @@
 }
 
 func TestOverrideAndroidTest(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		android_app {
 			name: "foo",
@@ -2148,6 +2176,7 @@
 }
 
 func TestAndroidTest_FixTestConfig(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		android_app {
 			name: "foo",
@@ -2229,6 +2258,7 @@
 }
 
 func TestAndroidAppImport(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		android_app_import {
 			name: "foo",
@@ -2258,6 +2288,7 @@
 }
 
 func TestAndroidAppImport_NoDexPreopt(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		android_app_import {
 			name: "foo",
@@ -2279,6 +2310,7 @@
 }
 
 func TestAndroidAppImport_Presigned(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		android_app_import {
 			name: "foo",
@@ -2307,6 +2339,7 @@
 }
 
 func TestAndroidAppImport_SigningLineage(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 	  android_app_import {
 			name: "foo",
@@ -2328,6 +2361,7 @@
 }
 
 func TestAndroidAppImport_DefaultDevCert(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		android_app_import {
 			name: "foo",
@@ -2357,6 +2391,7 @@
 }
 
 func TestAndroidAppImport_DpiVariants(t *testing.T) {
+	t.Parallel()
 	bp := `
 		android_app_import {
 			name: "foo",
@@ -2435,6 +2470,7 @@
 }
 
 func TestAndroidAppImport_Filename(t *testing.T) {
+	t.Parallel()
 	ctx, config := testJava(t, `
 		android_app_import {
 			name: "foo",
@@ -2482,6 +2518,7 @@
 }
 
 func TestAndroidAppImport_ArchVariants(t *testing.T) {
+	t.Parallel()
 	// The test config's target arch is ARM64.
 	testCases := []struct {
 		name     string
@@ -2545,6 +2582,7 @@
 }
 
 func TestAndroidTestImport(t *testing.T) {
+	t.Parallel()
 	ctx, config := testJava(t, `
 		android_test_import {
 			name: "foo",
@@ -2573,6 +2611,7 @@
 }
 
 func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		android_test_import {
 			name: "foo",
@@ -2610,6 +2649,7 @@
 }
 
 func TestAndroidTestImport_Preprocessed(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		android_test_import {
 			name: "foo",
@@ -2646,6 +2686,7 @@
 }
 
 func TestStl(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
 		cc_library {
 			name: "libjni",
@@ -2709,6 +2750,7 @@
 }
 
 func TestUsesLibraries(t *testing.T) {
+	t.Parallel()
 	bp := `
 		java_sdk_library {
 			name: "foo",
@@ -2754,19 +2796,6 @@
 		android_app {
 			name: "app",
 			srcs: ["a.java"],
-			libs: ["qux", "quuz"],
-			static_libs: ["static-runtime-helper"],
-			uses_libs: ["foo"],
-			sdk_version: "current",
-			optional_uses_libs: [
-				"bar",
-				"baz",
-			],
-		}
-
-		android_app {
-			name: "app_with_stub_deps",
-			srcs: ["a.java"],
 			libs: ["qux", "quuz.stubs"],
 			static_libs: ["static-runtime-helper"],
 			uses_libs: ["foo"],
@@ -2797,7 +2826,6 @@
 	run(t, ctx, config)
 
 	app := ctx.ModuleForTests("app", "android_common")
-	appWithStubDeps := ctx.ModuleForTests("app_with_stub_deps", "android_common")
 	prebuilt := ctx.ModuleForTests("prebuilt", "android_common")
 
 	// Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
@@ -2828,7 +2856,7 @@
 		t.Errorf("wanted %q in %q", w, cmd)
 	}
 
-	// Test that all present libraries are preopted, including implicit SDK dependencies
+	// Test that all present libraries are preopted, including implicit SDK dependencies, possibly stubs
 	cmd = app.Rule("dexpreopt").RuleParams.Command
 	w := `--target-classpath-for-sdk any` +
 		` /system/framework/foo.jar` +
@@ -2840,11 +2868,6 @@
 		t.Errorf("wanted %q in %q", w, cmd)
 	}
 
-	// TODO(skvadrik) fix dexpreopt for stub libraries for which the implementation is present
-	if appWithStubDeps.MaybeRule("dexpreopt").RuleParams.Command != "" {
-		t.Errorf("dexpreopt should be disabled for apps with dependencies on stub libraries")
-	}
-
 	cmd = prebuilt.Rule("dexpreopt").RuleParams.Command
 	if w := `--target-classpath-for-sdk any /system/framework/foo.jar:/system/framework/bar.jar`; !strings.Contains(cmd, w) {
 		t.Errorf("wanted %q in %q", w, cmd)
@@ -2852,6 +2875,7 @@
 }
 
 func TestCodelessApp(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name   string
 		bp     string
@@ -2928,6 +2952,7 @@
 }
 
 func TestEmbedNotice(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJavaWithFS(t, cc.GatherRequiredDepsForTest(android.Android)+`
 		android_app {
 			name: "foo",
@@ -3037,6 +3062,7 @@
 }
 
 func TestUncompressDex(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name string
 		bp   string
@@ -3164,6 +3190,7 @@
 }
 
 func TestRuntimeResourceOverlay(t *testing.T) {
+	t.Parallel()
 	fs := map[string][]byte{
 		"baz/res/res/values/strings.xml": nil,
 		"bar/res/res/values/strings.xml": nil,
@@ -3268,6 +3295,7 @@
 }
 
 func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) {
+	t.Parallel()
 	ctx, config := testJava(t, `
 		java_defaults {
 			name: "rro_defaults",
@@ -3327,6 +3355,7 @@
 }
 
 func TestOverrideRuntimeResourceOverlay(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		runtime_resource_overlay {
 			name: "foo_overlay",
diff --git a/java/device_host_converter_test.go b/java/device_host_converter_test.go
index 3c9a0f3..208ea57 100644
--- a/java/device_host_converter_test.go
+++ b/java/device_host_converter_test.go
@@ -22,6 +22,7 @@
 )
 
 func TestDeviceForHost(t *testing.T) {
+	t.Parallel()
 	bp := `
 		java_library {
 			name: "device_module",
@@ -102,6 +103,7 @@
 }
 
 func TestHostForDevice(t *testing.T) {
+	t.Parallel()
 	bp := `
 		java_library_host {
 			name: "host_module",
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index f1b7178..20dbc66 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -94,7 +94,7 @@
 	}
 
 	// Don't preopt APEX variant module
-	if am, ok := ctx.Module().(android.ApexModule); ok && !am.IsForPlatform() {
+	if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() {
 		return true
 	}
 
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 3addc1a..9f49786 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -238,6 +238,13 @@
 	dumpOatRules(ctx, d.defaultBootImage)
 }
 
+func isHostdex(module android.Module) bool {
+	if lib, ok := module.(*Library); ok {
+		return Bool(lib.deviceProperties.Hostdex)
+	}
+	return false
+}
+
 // Inspect this module to see if it contains a bootclasspath dex jar.
 // Note that the same jar may occur in multiple modules.
 // This logic is tested in the apex package to avoid import cycle apex <-> java.
@@ -259,12 +266,13 @@
 	}
 
 	// Check that this module satisfies constraints for a particular boot image.
-	apex, isApexModule := module.(android.ApexModule)
-	fromUpdatableApex := isApexModule && apex.Updatable()
+	_, isApexModule := module.(android.ApexModule)
+	apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
+	fromUpdatableApex := isApexModule && apexInfo.Updatable
 	if image.name == artBootImageName {
-		if isApexModule && len(apex.InApexes()) > 0 && allHavePrefix(apex.InApexes(), "com.android.art.") {
+		if isApexModule && len(apexInfo.InApexes) > 0 && allHavePrefix(apexInfo.InApexes, "com.android.art.") {
 			// ok: found the jar in the ART apex
-		} else if isApexModule && apex.IsForPlatform() && Bool(module.(*Library).deviceProperties.Hostdex) {
+		} else if isApexModule && apexInfo.IsForPlatform() && isHostdex(module) {
 			// exception (skip and continue): special "hostdex" platform variant
 			return -1, nil
 		} else if name == "jacocoagent" && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
@@ -272,7 +280,7 @@
 			return -1, nil
 		} else if fromUpdatableApex {
 			// error: this jar is part of an updatable apex other than ART
-			ctx.Errorf("module %q from updatable apexes %q is not allowed in the ART boot image", name, apex.InApexes())
+			ctx.Errorf("module %q from updatable apexes %q is not allowed in the ART boot image", name, apexInfo.InApexes)
 		} else {
 			// error: this jar is part of the platform or a non-updatable apex
 			ctx.Errorf("module %q is not allowed in the ART boot image", name)
@@ -282,7 +290,7 @@
 			// ok: this jar is part of the platform or a non-updatable apex
 		} else {
 			// error: this jar is part of an updatable apex
-			ctx.Errorf("module %q from updatable apexes %q is not allowed in the framework boot image", name, apex.InApexes())
+			ctx.Errorf("module %q from updatable apexes %q is not allowed in the framework boot image", name, apexInfo.InApexes)
 		}
 	} else {
 		panic("unknown boot image: " + image.name)
diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go
index 4a8d3cd..00bd80c 100644
--- a/java/dexpreopt_bootjars_test.go
+++ b/java/dexpreopt_bootjars_test.go
@@ -84,6 +84,7 @@
 }
 
 func TestDexpreoptBootJars(t *testing.T) {
+	t.Parallel()
 	ruleFile := "boot-foo.art"
 
 	expectedInputs := []string{
@@ -114,6 +115,7 @@
 
 // Changes to the boot.zip structure may break the ART APK scanner.
 func TestDexpreoptBootZip(t *testing.T) {
+	t.Parallel()
 	ruleFile := "boot.zip"
 
 	ctx := android.PathContextForTesting(testConfig(nil, "", nil))
diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go
index 5550a4c..0bb3ac9 100644
--- a/java/dexpreopt_test.go
+++ b/java/dexpreopt_test.go
@@ -19,6 +19,7 @@
 )
 
 func TestDexpreoptEnabled(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name    string
 		bp      string
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 33f422d..b3bb5ab 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -1064,6 +1064,10 @@
 		return android.Paths{d.stubsSrcJar}, nil
 	case ".docs.zip":
 		return android.Paths{d.docZip}, nil
+	case ".api.txt":
+		return android.Paths{d.apiFilePath}, nil
+	case ".removed-api.txt":
+		return android.Paths{d.removedApiFile}, nil
 	case ".annotations.zip":
 		return android.Paths{d.annotationsZip}, nil
 	case ".api_versions.xml":
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 61a9b97..b140b89 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -161,10 +161,9 @@
 				// For a java lib included in an APEX, only take the one built for
 				// the platform variant, and skip the variants for APEXes.
 				// Otherwise, the hiddenapi tool will complain about duplicated classes
-				if a, ok := module.(android.ApexModule); ok {
-					if android.InAnyApex(module.Name()) && !a.IsForPlatform() {
-						return
-					}
+				apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
+				if !apexInfo.IsForPlatform() {
+					return
 				}
 
 				bootDexJars = append(bootDexJars, jar)
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index dbdab7a..97dd125 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -58,6 +58,7 @@
 }
 
 func TestHiddenAPISingleton(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testHiddenAPIBootJars(t, `
 		java_library {
 			name: "foo",
@@ -75,6 +76,7 @@
 }
 
 func TestHiddenAPISingletonWithPrebuilt(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testHiddenAPIBootJars(t, `
 		java_import {
 			name: "foo",
@@ -92,6 +94,7 @@
 }
 
 func TestHiddenAPISingletonWithPrebuiltUseSource(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testHiddenAPIBootJars(t, `
 		java_library {
 			name: "foo",
@@ -121,6 +124,7 @@
 }
 
 func TestHiddenAPISingletonWithPrebuiltOverrideSource(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testHiddenAPIBootJars(t, `
 		java_library {
 			name: "foo",
@@ -150,6 +154,7 @@
 }
 
 func TestHiddenAPISingletonSdks(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name             string
 		unbundledBuild   bool
diff --git a/java/jacoco_test.go b/java/jacoco_test.go
index 91f0553..d77c916 100644
--- a/java/jacoco_test.go
+++ b/java/jacoco_test.go
@@ -17,6 +17,7 @@
 import "testing"
 
 func TestJacocoFilterToSpecs(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name, in, out string
 	}{
@@ -66,6 +67,7 @@
 }
 
 func TestJacocoFiltersToZipCommand(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name               string
 		includes, excludes []string
diff --git a/java/java.go b/java/java.go
index 1d7eaa7..2553a30 100644
--- a/java/java.go
+++ b/java/java.go
@@ -451,6 +451,8 @@
 
 	// Collect the module directory for IDE info in java/jdeps.go.
 	modulePaths []string
+
+	hideApexVariantFromMake bool
 }
 
 func (j *Module) addHostProperties() {
@@ -638,8 +640,9 @@
 	// Force enable the instrumentation for java code that is built for APEXes ...
 	// except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent
 	// doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true.
+	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
 	isJacocoAgent := ctx.ModuleName() == "jacocoagent"
-	if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !isJacocoAgent && !j.IsForPlatform() {
+	if j.DirectlyInAnyApex() && !isJacocoAgent && !apexInfo.IsForPlatform() {
 		if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
 			return true
 		} else if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
@@ -735,9 +738,21 @@
 		return ret
 	}
 
-	ctx.AddVariationDependencies(nil, libTag, rewriteSyspropLibs(j.properties.Libs, "libs")...)
+	libDeps := ctx.AddVariationDependencies(nil, libTag, rewriteSyspropLibs(j.properties.Libs, "libs")...)
 	ctx.AddVariationDependencies(nil, staticLibTag, rewriteSyspropLibs(j.properties.Static_libs, "static_libs")...)
 
+	// For library dependencies that are component libraries (like stubs), add the implementation
+	// as a dependency (dexpreopt needs to be against the implementation library, not stubs).
+	for _, dep := range libDeps {
+		if dep != nil {
+			if component, ok := dep.(SdkLibraryComponentDependency); ok {
+				if lib := component.OptionalSdkLibraryImplementation(); lib != nil {
+					ctx.AddVariationDependencies(nil, usesLibTag, *lib)
+				}
+			}
+		}
+	}
+
 	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...)
 	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...)
 
@@ -1590,7 +1605,8 @@
 	j.implementationAndResourcesJar = implementationAndResourcesJar
 
 	// Enable dex compilation for the APEX variants, unless it is disabled explicitly
-	if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !j.IsForPlatform() {
+	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+	if j.DirectlyInAnyApex() && !apexInfo.IsForPlatform() {
 		if j.dexProperties.Compile_dex == nil {
 			j.dexProperties.Compile_dex = proptools.BoolPtr(true)
 		}
@@ -1672,7 +1688,7 @@
 		j.linter.compileSdkVersion = lintSDKVersionString(j.sdkVersion())
 		j.linter.javaLanguageLevel = flags.javaVersion.String()
 		j.linter.kotlinLanguageLevel = "1.3"
-		if j.ApexVariationName() != "" && ctx.Config().UnbundledBuildApps() {
+		if !apexInfo.IsForPlatform() && ctx.Config().UnbundledBuildApps() {
 			j.linter.buildModuleReportZip = true
 		}
 		j.linter.lint(ctx)
@@ -1934,7 +1950,7 @@
 
 func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool {
 	// Store uncompressed (and aligned) any dex files from jars in APEXes.
-	if am, ok := ctx.Module().(android.ApexModule); ok && !am.IsForPlatform() {
+	if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() {
 		return true
 	}
 
@@ -1956,6 +1972,11 @@
 }
 
 func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+	if !apexInfo.IsForPlatform() {
+		j.hideApexVariantFromMake = true
+	}
+
 	j.checkSdkVersions(ctx)
 	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
 	j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
@@ -1970,7 +1991,7 @@
 	// Collect the module directory for IDE info in java/jdeps.go.
 	j.modulePaths = append(j.modulePaths, ctx.ModuleDir())
 
-	exclusivelyForApex := android.InAnyApex(ctx.ModuleName()) && !j.IsForPlatform()
+	exclusivelyForApex := !apexInfo.IsForPlatform()
 	if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex {
 		var extraInstallDeps android.Paths
 		if j.InstallMixin != nil {
@@ -2562,6 +2583,8 @@
 	combinedClasspathFile android.Path
 	exportedSdkLibs       dexpreopt.LibraryPaths
 	exportAidlIncludeDirs android.Paths
+
+	hideApexVariantFromMake bool
 }
 
 func (j *Import) sdkVersion() sdkSpec {
@@ -2617,6 +2640,10 @@
 }
 
 func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() {
+		j.hideApexVariantFromMake = true
+	}
+
 	jars := android.PathsForModuleSrc(ctx, j.properties.Jars)
 
 	jarName := j.Stem() + ".jar"
@@ -2699,6 +2726,17 @@
 	}
 }
 
+func (j *Import) OutputFiles(tag string) (android.Paths, error) {
+	switch tag {
+	case ".jar":
+		return android.Paths{j.combinedClasspathFile}, nil
+	default:
+		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+	}
+}
+
+var _ android.OutputFileProducer = (*Import)(nil)
+
 var _ Dependency = (*Import)(nil)
 
 func (j *Import) HeaderJars() android.Paths {
@@ -2849,6 +2887,8 @@
 	maybeStrippedDexJarFile android.Path
 
 	dexpreopter
+
+	hideApexVariantFromMake bool
 }
 
 func (j *DexImport) Prebuilt() *android.Prebuilt {
@@ -2884,6 +2924,11 @@
 		ctx.PropertyErrorf("jars", "exactly one jar must be provided")
 	}
 
+	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+	if !apexInfo.IsForPlatform() {
+		j.hideApexVariantFromMake = true
+	}
+
 	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
 	j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
 
@@ -2928,7 +2973,7 @@
 
 	j.maybeStrippedDexJarFile = dexOutputFile
 
-	if j.IsForPlatform() {
+	if apexInfo.IsForPlatform() {
 		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
 			j.Stem()+".jar", dexOutputFile)
 	}
diff --git a/java/java_test.go b/java/java_test.go
index 9e63577..245654d 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -177,6 +177,7 @@
 }
 
 func TestJavaLinkType(t *testing.T) {
+	t.Parallel()
 	testJava(t, `
 		java_library {
 			name: "foo",
@@ -265,6 +266,7 @@
 }
 
 func TestSimple(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 			name: "foo",
@@ -309,6 +311,7 @@
 }
 
 func TestExportedPlugins(t *testing.T) {
+	t.Parallel()
 	type Result struct {
 		library    string
 		processors string
@@ -392,6 +395,7 @@
 }
 
 func TestSdkVersionByPartition(t *testing.T) {
+	t.Parallel()
 	testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
 		java_library {
 			name: "foo",
@@ -427,6 +431,7 @@
 }
 
 func TestArchSpecific(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 			name: "foo",
@@ -446,6 +451,7 @@
 }
 
 func TestBinary(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library_host {
 			name: "foo",
@@ -474,6 +480,7 @@
 }
 
 func TestHostBinaryNoJavaDebugInfoOverride(t *testing.T) {
+	t.Parallel()
 	bp := `
 		java_library {
 			name: "target_library",
@@ -509,6 +516,7 @@
 }
 
 func TestPrebuilts(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 			name: "foo",
@@ -604,6 +612,7 @@
 }
 
 func TestJavaSdkLibraryImport(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 			name: "foo",
@@ -660,6 +669,7 @@
 }
 
 func TestJavaSdkLibraryImport_WithSource(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_sdk_library {
 			name: "sdklib",
@@ -699,6 +709,7 @@
 }
 
 func TestJavaSdkLibraryImport_Preferred(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_sdk_library {
 			name: "sdklib",
@@ -736,6 +747,7 @@
 }
 
 func TestDefaults(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_defaults {
 			name: "defaults",
@@ -811,6 +823,7 @@
 }
 
 func TestResources(t *testing.T) {
+	t.Parallel()
 	var table = []struct {
 		name  string
 		prop  string
@@ -917,6 +930,7 @@
 }
 
 func TestIncludeSrcs(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJavaWithFS(t, `
 		java_library {
 			name: "foo",
@@ -984,6 +998,7 @@
 }
 
 func TestGeneratedSources(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJavaWithFS(t, `
 		java_library {
 			name: "foo",
@@ -1020,6 +1035,7 @@
 }
 
 func TestTurbine(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 			name: "foo",
@@ -1069,6 +1085,7 @@
 }
 
 func TestSharding(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 			name: "bar",
@@ -1087,6 +1104,7 @@
 }
 
 func TestDroiddoc(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJavaWithFS(t, `
 		droiddoc_exported_dir {
 		    name: "droiddoc-templates-sdk",
@@ -1165,6 +1183,7 @@
 }
 
 func TestDroiddocArgsAndFlagsCausesError(t *testing.T) {
+	t.Parallel()
 	testJavaError(t, "flags is set. Cannot set args", `
 		droiddoc_exported_dir {
 		    name: "droiddoc-templates-sdk",
@@ -1211,6 +1230,7 @@
 }
 
 func TestDroidstubs(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJavaWithFS(t, `
 		droiddoc_exported_dir {
 		    name: "droiddoc-templates-sdk",
@@ -1267,6 +1287,7 @@
 }
 
 func TestDroidstubsWithSystemModules(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		droidstubs {
 		    name: "stubs-source-system-modules",
@@ -1326,6 +1347,7 @@
 }
 
 func TestJarGenrules(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 			name: "foo",
@@ -1380,6 +1402,7 @@
 }
 
 func TestExcludeFileGroupInSrcs(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 			name: "foo",
@@ -1406,19 +1429,45 @@
 }
 
 func TestJavaLibrary(t *testing.T) {
+	t.Parallel()
 	config := testConfig(nil, "", map[string][]byte{
 		"libcore/Android.bp": []byte(`
 				java_library {
 						name: "core",
 						sdk_version: "none",
 						system_modules: "none",
-				}`),
+				}
+
+				filegroup {
+					name: "core-jar",
+					srcs: [":core{.jar}"],
+				}
+`),
+	})
+	ctx := testContext()
+	run(t, ctx, config)
+}
+
+func TestJavaImport(t *testing.T) {
+	config := testConfig(nil, "", map[string][]byte{
+		"libcore/Android.bp": []byte(`
+				java_import {
+						name: "core",
+						sdk_version: "none",
+				}
+
+				filegroup {
+					name: "core-jar",
+					srcs: [":core{.jar}"],
+				}
+`),
 	})
 	ctx := testContext()
 	run(t, ctx, config)
 }
 
 func TestJavaSdkLibrary(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		droiddoc_exported_dir {
 			name: "droiddoc-templates-sdk",
@@ -1487,6 +1536,12 @@
 			libs: ["foo"],
 			sdk_version: "system_29",
 		}
+		java_library {
+			name: "baz-module-30",
+			srcs: ["c.java"],
+			libs: ["foo"],
+			sdk_version: "module_30",
+		}
 		`)
 
 	// check the existence of the internal modules
@@ -1533,6 +1588,13 @@
 			"prebuilts/sdk/29/system/foo.jar")
 	}
 
+	bazModule30Javac := ctx.ModuleForTests("baz-module-30", "android_common").Rule("javac")
+	// tests if "baz-module-30" is actually linked to the module 30 stubs lib
+	if !strings.Contains(bazModule30Javac.Args["classpath"], "prebuilts/sdk/30/module-lib/foo.jar") {
+		t.Errorf("baz-module-30 javac classpath %v does not contain %q", bazModule30Javac.Args["classpath"],
+			"prebuilts/sdk/30/module-lib/foo.jar")
+	}
+
 	// test if baz has exported SDK lib names foo and bar to qux
 	qux := ctx.ModuleForTests("qux", "android_common")
 	if quxLib, ok := qux.Module().(*Library); ok {
@@ -1544,6 +1606,7 @@
 }
 
 func TestJavaSdkLibrary_DoNotAccessImplWhenItIsNotBuilt(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_sdk_library {
 			name: "foo",
@@ -1569,6 +1632,7 @@
 }
 
 func TestJavaSdkLibrary_UseSourcesFromAnotherSdkLibrary(t *testing.T) {
+	t.Parallel()
 	testJava(t, `
 		java_sdk_library {
 			name: "foo",
@@ -1587,6 +1651,7 @@
 }
 
 func TestJavaSdkLibrary_AccessOutputFiles_MissingScope(t *testing.T) {
+	t.Parallel()
 	testJavaError(t, `"foo" does not provide api scope system`, `
 		java_sdk_library {
 			name: "foo",
@@ -1605,6 +1670,7 @@
 }
 
 func TestJavaSdkLibrary_Deps(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_sdk_library {
 			name: "sdklib",
@@ -1627,6 +1693,7 @@
 }
 
 func TestJavaSdkLibraryImport_AccessOutputFiles(t *testing.T) {
+	t.Parallel()
 	testJava(t, `
 		java_sdk_library_import {
 			name: "foo",
@@ -1650,6 +1717,7 @@
 }
 
 func TestJavaSdkLibraryImport_AccessOutputFiles_Invalid(t *testing.T) {
+	t.Parallel()
 	bp := `
 		java_sdk_library_import {
 			name: "foo",
@@ -1698,6 +1766,7 @@
 }
 
 func TestJavaSdkLibrary_InvalidScopes(t *testing.T) {
+	t.Parallel()
 	testJavaError(t, `module "foo": enabled api scope "system" depends on disabled scope "public"`, `
 		java_sdk_library {
 			name: "foo",
@@ -1716,6 +1785,7 @@
 }
 
 func TestJavaSdkLibrary_SdkVersion_ForScope(t *testing.T) {
+	t.Parallel()
 	testJava(t, `
 		java_sdk_library {
 			name: "foo",
@@ -1730,6 +1800,7 @@
 }
 
 func TestJavaSdkLibrary_ModuleLib(t *testing.T) {
+	t.Parallel()
 	testJava(t, `
 		java_sdk_library {
 			name: "foo",
@@ -1746,6 +1817,7 @@
 }
 
 func TestJavaSdkLibrary_SystemServer(t *testing.T) {
+	t.Parallel()
 	testJava(t, `
 		java_sdk_library {
 			name: "foo",
@@ -1762,6 +1834,7 @@
 }
 
 func TestJavaSdkLibrary_MissingScope(t *testing.T) {
+	t.Parallel()
 	testJavaError(t, `requires api scope module-lib from foo but it only has \[\] available`, `
 		java_sdk_library {
 			name: "foo",
@@ -1781,6 +1854,7 @@
 }
 
 func TestJavaSdkLibrary_FallbackScope(t *testing.T) {
+	t.Parallel()
 	testJava(t, `
 		java_sdk_library {
 			name: "foo",
@@ -1801,6 +1875,7 @@
 }
 
 func TestJavaSdkLibrary_DefaultToStubs(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_sdk_library {
 			name: "foo",
@@ -1876,6 +1951,7 @@
 }
 
 func TestCompilerFlags(t *testing.T) {
+	t.Parallel()
 	for _, testCase := range compilerFlagsTestCases {
 		ctx := &mockContext{result: true}
 		CheckKotlincFlags(ctx, []string{testCase.in})
@@ -1906,6 +1982,7 @@
 }
 
 func TestPatchModule(t *testing.T) {
+	t.Parallel()
 	t.Run("Java language level 8", func(t *testing.T) {
 		// Test with legacy javac -source 1.8 -target 1.8
 		bp := `
@@ -1971,6 +2048,7 @@
 }
 
 func TestJavaSystemModules(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_system_modules {
 			name: "system-modules",
@@ -2005,6 +2083,7 @@
 }
 
 func TestJavaSystemModulesImport(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_system_modules_import {
 			name: "system-modules",
@@ -2035,6 +2114,7 @@
 }
 
 func TestJavaLibraryWithSystemModules(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 		    name: "lib-with-source-system-modules",
@@ -2091,6 +2171,7 @@
 }
 
 func TestAidlExportIncludeDirsFromImports(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 			name: "foo",
@@ -2115,6 +2196,7 @@
 }
 
 func TestDataNativeBinaries(t *testing.T) {
+	t.Parallel()
 	ctx, config := testJava(t, `
 		java_test_host {
 			name: "foo",
diff --git a/java/jdeps_test.go b/java/jdeps_test.go
index 874d1d7..46e7296 100644
--- a/java/jdeps_test.go
+++ b/java/jdeps_test.go
@@ -22,6 +22,7 @@
 )
 
 func TestCollectJavaLibraryPropertiesAddLibsDeps(t *testing.T) {
+	t.Parallel()
 	expected := []string{"Foo", "Bar"}
 	module := LibraryFactory().(*Library)
 	module.properties.Libs = append(module.properties.Libs, expected...)
@@ -35,6 +36,7 @@
 }
 
 func TestCollectJavaLibraryPropertiesAddStaticLibsDeps(t *testing.T) {
+	t.Parallel()
 	expected := []string{"Foo", "Bar"}
 	module := LibraryFactory().(*Library)
 	module.properties.Static_libs = append(module.properties.Static_libs, expected...)
@@ -48,6 +50,7 @@
 }
 
 func TestCollectJavaLibraryPropertiesAddScrs(t *testing.T) {
+	t.Parallel()
 	expected := []string{"Foo", "Bar"}
 	module := LibraryFactory().(*Library)
 	module.expandIDEInfoCompiledSrcs = append(module.expandIDEInfoCompiledSrcs, expected...)
@@ -61,6 +64,7 @@
 }
 
 func TestCollectJavaLibraryPropertiesAddAidlIncludeDirs(t *testing.T) {
+	t.Parallel()
 	expected := []string{"Foo", "Bar"}
 	module := LibraryFactory().(*Library)
 	module.deviceProperties.Aidl.Include_dirs = append(module.deviceProperties.Aidl.Include_dirs, expected...)
@@ -74,6 +78,7 @@
 }
 
 func TestCollectJavaLibraryPropertiesAddJarjarRules(t *testing.T) {
+	t.Parallel()
 	expected := "Jarjar_rules.txt"
 	module := LibraryFactory().(*Library)
 	module.expandJarjarRules = android.PathForTesting(expected)
diff --git a/java/kotlin_test.go b/java/kotlin_test.go
index 60ca1c4..530f7fe 100644
--- a/java/kotlin_test.go
+++ b/java/kotlin_test.go
@@ -22,6 +22,7 @@
 )
 
 func TestKotlin(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 			name: "foo",
@@ -84,6 +85,7 @@
 }
 
 func TestKapt(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 			name: "foo",
@@ -163,6 +165,7 @@
 }
 
 func TestKaptEncodeFlags(t *testing.T) {
+	t.Parallel()
 	// Compares the kaptEncodeFlags against the results of the example implementation at
 	// https://kotlinlang.org/docs/reference/kapt.html#apjavac-options-encoding
 	tests := []struct {
diff --git a/java/lint.go b/java/lint.go
index 3a210cc..3df582f 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -451,10 +451,13 @@
 			return
 		}
 
-		if apex, ok := m.(android.ApexModule); ok && apex.NotAvailableForPlatform() && apex.IsForPlatform() {
-			// There are stray platform variants of modules in apexes that are not available for
-			// the platform, and they sometimes can't be built.  Don't depend on them.
-			return
+		if apex, ok := m.(android.ApexModule); ok && apex.NotAvailableForPlatform() {
+			apexInfo := ctx.ModuleProvider(m, android.ApexInfoProvider).(android.ApexInfo)
+			if apexInfo.IsForPlatform() {
+				// There are stray platform variants of modules in apexes that are not available for
+				// the platform, and they sometimes can't be built.  Don't depend on them.
+				return
+			}
 		}
 
 		if l, ok := m.(lintOutputsIntf); ok {
diff --git a/java/plugin_test.go b/java/plugin_test.go
index c7913d3..3eb0215 100644
--- a/java/plugin_test.go
+++ b/java/plugin_test.go
@@ -20,6 +20,7 @@
 )
 
 func TestNoPlugin(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 			name: "foo",
@@ -44,6 +45,7 @@
 }
 
 func TestPlugin(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 			name: "foo",
@@ -83,6 +85,7 @@
 }
 
 func TestPluginGeneratesApi(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testJava(t, `
 		java_library {
 			name: "foo",
diff --git a/java/sdk.go b/java/sdk.go
index f599265..971791f 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -222,7 +222,7 @@
 		return ctx.Config().AlwaysUsePrebuiltSdks()
 	} else if s.version.isNumbered() {
 		// validation check
-		if s.kind != sdkPublic && s.kind != sdkSystem && s.kind != sdkTest {
+		if s.kind != sdkPublic && s.kind != sdkSystem && s.kind != sdkTest && s.kind != sdkModule {
 			panic(fmt.Errorf("prebuilt SDK is not not available for sdkKind=%q", s.kind))
 			return false
 		}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 0d29a37..119eb65 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -589,6 +589,9 @@
 	// An Android shared library is one that can be referenced in a <uses-library> element
 	// in an AndroidManifest.xml.
 	Shared_library *bool
+
+	// Files containing information about supported java doc tags.
+	Doctag_files []string `android:"path"`
 }
 
 // Common code between sdk library and sdk library import
@@ -601,6 +604,9 @@
 
 	commonSdkLibraryProperties commonToSdkLibraryAndImportProperties
 
+	// Paths to commonSdkLibraryProperties.Doctag_files
+	doctagPaths android.Paths
+
 	// Functionality related to this being used as a component of a java_sdk_library.
 	EmbeddableSdkLibraryComponent
 }
@@ -633,6 +639,10 @@
 	return true
 }
 
+func (c *commonToSdkLibraryAndImport) generateCommonBuildActions(ctx android.ModuleContext) {
+	c.doctagPaths = android.PathsForModuleSrc(ctx, c.commonSdkLibraryProperties.Doctag_files)
+}
+
 // Module name of the runtime implementation library
 func (c *commonToSdkLibraryAndImport) implLibraryModuleName() string {
 	return c.moduleBase.BaseModuleName() + ".impl"
@@ -732,6 +742,14 @@
 		}
 
 	} else {
+		switch tag {
+		case ".doctags":
+			if c.doctagPaths != nil {
+				return c.doctagPaths, nil
+			} else {
+				return nil, fmt.Errorf("no doctag_files specified on %s", c.moduleBase.BaseModuleName())
+			}
+		}
 		return nil, nil
 	}
 }
@@ -852,6 +870,12 @@
 	return e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack
 }
 
+// to satisfy SdkLibraryComponentDependency
+func (e *EmbeddableSdkLibraryComponent) OptionalSdkLibraryImplementation() *string {
+	// Currently implementation library name is the same as the SDK library name.
+	return e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack
+}
+
 // Implemented by modules that are (or possibly could be) a component of a java_sdk_library
 // (including the java_sdk_library) itself.
 type SdkLibraryComponentDependency interface {
@@ -862,6 +886,9 @@
 	//
 	// Returns the name of the optional implicit SDK library or nil, if there isn't one.
 	OptionalImplicitSdkLibrary() *string
+
+	// The name of the implementation library for the optional SDK library or nil, if there isn't one.
+	OptionalSdkLibraryImplementation() *string
 }
 
 // Make sure that all the module types that are components of java_sdk_library/_import
@@ -1014,6 +1041,8 @@
 }
 
 func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	module.generateCommonBuildActions(ctx)
+
 	// Only build an implementation library if required.
 	if module.requiresRuntimeImplementationLibrary() {
 		module.Library.GenerateAndroidBuildActions(ctx)
@@ -1390,22 +1419,14 @@
 	return android.Paths{jarPath.Path()}
 }
 
-// Get the apex names for module, nil if it is for platform.
-func getApexNamesForModule(module android.Module) []string {
-	if apex, ok := module.(android.ApexModule); ok {
-		return apex.InApexes()
-	}
-
-	return nil
-}
-
 // Check to see if the other module is within the same set of named APEXes as this module.
 //
 // If either this or the other module are on the platform then this will return
 // false.
-func withinSameApexesAs(module android.ApexModule, other android.Module) bool {
-	names := module.InApexes()
-	return len(names) > 0 && reflect.DeepEqual(names, getApexNamesForModule(other))
+func withinSameApexesAs(ctx android.BaseModuleContext, other android.Module) bool {
+	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+	otherApexInfo := ctx.OtherModuleProvider(other, android.ApexInfoProvider).(android.ApexInfo)
+	return len(otherApexInfo.InApexes) > 0 && reflect.DeepEqual(apexInfo.InApexes, otherApexInfo.InApexes)
 }
 
 func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {
@@ -1424,7 +1445,7 @@
 		// Only allow access to the implementation library in the following condition:
 		// * No sdk_version specified on the referencing module.
 		// * The referencing module is in the same apex as this.
-		if sdkVersion.kind == sdkPrivate || withinSameApexesAs(module, ctx.Module()) {
+		if sdkVersion.kind == sdkPrivate || withinSameApexesAs(ctx, module) {
 			if headerJars {
 				return module.HeaderJars()
 			} else {
@@ -1895,6 +1916,8 @@
 }
 
 func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	module.generateCommonBuildActions(ctx)
+
 	// Record the paths to the prebuilt stubs library and stubs source.
 	ctx.VisitDirectDeps(func(to android.Module) {
 		tag := ctx.OtherModuleDependencyTag(to)
@@ -1939,7 +1962,7 @@
 	// For consistency with SdkLibrary make the implementation jar available to libraries that
 	// are within the same APEX.
 	implLibraryModule := module.implLibraryModule
-	if implLibraryModule != nil && withinSameApexesAs(module, ctx.Module()) {
+	if implLibraryModule != nil && withinSameApexesAs(ctx, module) {
 		if headerJars {
 			return implLibraryModule.HeaderJars()
 		} else {
@@ -2035,6 +2058,8 @@
 
 	outputFilePath android.OutputPath
 	installDirPath android.InstallPath
+
+	hideApexVariantFromMake bool
 }
 
 type sdkLibraryXmlProperties struct {
@@ -2092,13 +2117,13 @@
 }
 
 // File path to the runtime implementation library
-func (module *sdkLibraryXml) implPath() string {
+func (module *sdkLibraryXml) implPath(ctx android.ModuleContext) string {
 	implName := proptools.String(module.properties.Lib_name)
-	if apexName := module.ApexVariationName(); apexName != "" {
+	if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() {
 		// TODO(b/146468504): ApexVariationName() is only a soong module name, not apex name.
 		// In most cases, this works fine. But when apex_name is set or override_apex is used
 		// this can be wrong.
-		return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, implName)
+		return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexInfo.ApexVariationName, implName)
 	}
 	partition := "system"
 	if module.SocSpecific() {
@@ -2114,8 +2139,10 @@
 }
 
 func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	module.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
+
 	libName := proptools.String(module.properties.Lib_name)
-	xmlContent := fmt.Sprintf(permissionsTemplate, libName, module.implPath())
+	xmlContent := fmt.Sprintf(permissionsTemplate, libName, module.implPath(ctx))
 
 	module.outputFilePath = android.PathForModuleOut(ctx, libName+".xml").OutputPath
 	rule := android.NewRuleBuilder()
@@ -2129,7 +2156,7 @@
 }
 
 func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries {
-	if !module.IsForPlatform() {
+	if module.hideApexVariantFromMake {
 		return []android.AndroidMkEntries{android.AndroidMkEntries{
 			Disabled: true,
 		}}
@@ -2187,6 +2214,9 @@
 	// True if the java_sdk_library_import is for a shared library, false
 	// otherwise.
 	Shared_library *bool
+
+	// The paths to the doctag files to add to the prebuilt.
+	Doctag_paths android.Paths
 }
 
 type scopeProperties struct {
@@ -2226,6 +2256,7 @@
 	s.Libs = sdk.properties.Libs
 	s.Naming_scheme = sdk.commonSdkLibraryProperties.Naming_scheme
 	s.Shared_library = proptools.BoolPtr(sdk.sharedLibrary())
+	s.Doctag_paths = sdk.doctagPaths
 }
 
 func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
@@ -2274,6 +2305,16 @@
 		}
 	}
 
+	if len(s.Doctag_paths) > 0 {
+		dests := []string{}
+		for _, p := range s.Doctag_paths {
+			dest := filepath.Join("doctags", p.Rel())
+			ctx.SnapshotBuilder().CopyToSnapshot(p, dest)
+			dests = append(dests, dest)
+		}
+		propertySet.AddProperty("doctag_files", dests)
+	}
+
 	if len(s.Libs) > 0 {
 		propertySet.AddPropertyWithTag("libs", s.Libs, ctx.SnapshotBuilder().SdkMemberReferencePropertyTag(false))
 	}
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 776069d..374da11 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -27,6 +27,7 @@
 )
 
 func TestClasspath(t *testing.T) {
+	t.Parallel()
 	var classpathTestcases = []struct {
 		name       string
 		unbundled  bool
diff --git a/java/testing.go b/java/testing.go
index a472413..461fd3f 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -55,6 +55,8 @@
 		"prebuilts/sdk/30/public/framework.aidl":                   nil,
 		"prebuilts/sdk/30/system/android.jar":                      nil,
 		"prebuilts/sdk/30/system/foo.jar":                          nil,
+		"prebuilts/sdk/30/module-lib/android.jar":                  nil,
+		"prebuilts/sdk/30/module-lib/foo.jar":                      nil,
 		"prebuilts/sdk/30/public/core-for-system-modules.jar":      nil,
 		"prebuilts/sdk/current/core/android.jar":                   nil,
 		"prebuilts/sdk/current/public/android.jar":                 nil,
diff --git a/makedeps/deps_test.go b/makedeps/deps_test.go
index ac2f699..17e77c4 100644
--- a/makedeps/deps_test.go
+++ b/makedeps/deps_test.go
@@ -23,6 +23,7 @@
 )
 
 func TestParse(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name   string
 		input  string
@@ -339,6 +340,7 @@
 }
 
 func TestDepPrint(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name   string
 		input  Deps
diff --git a/partner/androidmk/androidmk_test.go b/partner/androidmk/androidmk_test.go
index 6bae836..2a0ddc8 100644
--- a/partner/androidmk/androidmk_test.go
+++ b/partner/androidmk/androidmk_test.go
@@ -54,6 +54,7 @@
 }
 
 func TestEndToEnd(t *testing.T) {
+	t.Parallel()
 	for i, test := range testCases {
 		expected, err := bpfix.Reformat(test.expected)
 		if err != nil {
diff --git a/python/androidmk.go b/python/androidmk.go
index 247b80d..8ad5889 100644
--- a/python/androidmk.go
+++ b/python/androidmk.go
@@ -15,11 +15,12 @@
 package python
 
 import (
-	"android/soong/android"
 	"fmt"
 	"io"
 	"path/filepath"
 	"strings"
+
+	"android/soong/android"
 )
 
 type subAndroidMkProvider interface {
@@ -74,6 +75,11 @@
 		if !BoolDefault(p.binaryProperties.Auto_gen_config, true) {
 			fmt.Fprintln(w, "LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG := true")
 		}
+
+		if len(p.data) > 0 {
+			fmt.Fprintln(w, "LOCAL_TEST_DATA :=",
+				strings.Join(android.AndroidMkDataPaths(p.data), " "))
+		}
 	})
 	base.subAndroidMk(ret, p.binaryDecorator.pythonInstaller)
 }
diff --git a/python/python_test.go b/python/python_test.go
index 23db24e..455d84a 100644
--- a/python/python_test.go
+++ b/python/python_test.go
@@ -326,6 +326,7 @@
 )
 
 func TestPythonModule(t *testing.T) {
+	t.Parallel()
 	for _, d := range data {
 		t.Run(d.desc, func(t *testing.T) {
 			config := android.TestConfig(buildDir, nil, "", d.mockFiles)
diff --git a/python/test.go b/python/test.go
index a669c73..434e71a 100644
--- a/python/test.go
+++ b/python/test.go
@@ -34,6 +34,10 @@
 	// the name of the test configuration template (for example "AndroidTestTemplate.xml") that
 	// should be installed with the module.
 	Test_config_template *string `android:"path,arch_variant"`
+
+	// list of files or filegroup modules that provide data that should be installed alongside
+	// the test
+	Data []string `android:"path,arch_variant"`
 }
 
 type testDecorator struct {
@@ -42,6 +46,8 @@
 	testProperties TestProperties
 
 	testConfig android.Path
+
+	data []android.DataPath
 }
 
 func (test *testDecorator) bootstrapperProps() []interface{} {
@@ -59,6 +65,12 @@
 	test.binaryDecorator.pythonInstaller.relative = ctx.ModuleName()
 
 	test.binaryDecorator.pythonInstaller.install(ctx, file)
+
+	dataSrcPaths := android.PathsForModuleSrc(ctx, test.testProperties.Data)
+
+	for _, dataSrcPath := range dataSrcPaths {
+		test.data = append(test.data, android.DataPath{SrcPath: dataSrcPath})
+	}
 }
 
 func NewTest(hod android.HostOrDeviceSupported) *Module {
diff --git a/remoteexec/remoteexec_test.go b/remoteexec/remoteexec_test.go
index 56985d3..2fd3687 100644
--- a/remoteexec/remoteexec_test.go
+++ b/remoteexec/remoteexec_test.go
@@ -22,6 +22,7 @@
 )
 
 func TestTemplate(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name   string
 		params *REParams
@@ -67,6 +68,7 @@
 }
 
 func TestNoVarTemplate(t *testing.T) {
+	t.Parallel()
 	params := &REParams{
 		Labels:      map[string]string{"type": "compile", "lang": "cpp", "compiler": "clang"},
 		Inputs:      []string{"$in"},
@@ -83,6 +85,7 @@
 }
 
 func TestTemplateDeterminism(t *testing.T) {
+	t.Parallel()
 	r := &REParams{
 		Labels:      map[string]string{"type": "compile", "lang": "cpp", "compiler": "clang"},
 		Inputs:      []string{"$in"},
diff --git a/rust/binary.go b/rust/binary.go
index e95cb3a..af39d38 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -28,6 +28,12 @@
 	// Also link libstd as an rlib as well on device targets.
 	// Note: This is the default behavior for host targets.
 	Prefer_rlib *bool `android:"arch_variant"`
+
+	// Builds this binary as a static binary. Implies prefer_rlib true.
+	//
+	// Static executables currently only support for bionic targets. Non-bionic targets will not produce a fully static
+	// binary, but will still implicitly imply prefer_rlib true.
+	Static_executable *bool `android:"arch_variant"`
 }
 
 type binaryDecorator struct {
@@ -72,6 +78,11 @@
 			"-Wl,--gc-sections",
 			"-Wl,-z,nocopyreloc",
 			"-Wl,--no-undefined-version")
+
+		if Bool(binary.Properties.Static_executable) {
+			flags.LinkFlags = append(flags.LinkFlags, "-static")
+			flags.RustFlags = append(flags.RustFlags, "-C relocation-model=static")
+		}
 	}
 
 	return flags
@@ -81,8 +92,12 @@
 	deps = binary.baseCompiler.compilerDeps(ctx, deps)
 
 	if ctx.toolchain().Bionic() {
-		deps = bionicDeps(deps)
-		deps.CrtBegin = "crtbegin_dynamic"
+		deps = bionicDeps(deps, Bool(binary.Properties.Static_executable))
+		if Bool(binary.Properties.Static_executable) {
+			deps.CrtBegin = "crtbegin_static"
+		} else {
+			deps.CrtBegin = "crtbegin_dynamic"
+		}
 		deps.CrtEnd = "crtend_android"
 	}
 
@@ -99,6 +114,10 @@
 	return true
 }
 
+func (binary *binaryDecorator) preferRlib() bool {
+	return Bool(binary.Properties.Prefer_rlib) || Bool(binary.Properties.Static_executable)
+}
+
 func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
 	fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
 	srcPath, _ := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
@@ -135,7 +154,7 @@
 
 func (binary *binaryDecorator) autoDep(ctx BaseModuleContext) autoDep {
 	// Binaries default to dylib dependencies for device, rlib for host.
-	if Bool(binary.Properties.Prefer_rlib) {
+	if binary.preferRlib() {
 		return rlibAutoDep
 	}
 	if ctx.Device() {
@@ -145,6 +164,9 @@
 	}
 }
 
-func (binary *binaryDecorator) staticStd(ctx *depsContext) bool {
-	return binary.baseCompiler.staticStd(ctx) || Bool(binary.Properties.Prefer_rlib)
+func (binary *binaryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
+	if binary.preferRlib() {
+		return RlibLinkage
+	}
+	return binary.baseCompiler.stdLinkage(ctx)
 }
diff --git a/rust/binary_test.go b/rust/binary_test.go
index f31a7fc..692a066 100644
--- a/rust/binary_test.go
+++ b/rust/binary_test.go
@@ -23,6 +23,7 @@
 
 // Test that rustlibs default linkage is correct for binaries.
 func TestBinaryLinkage(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_binary {
 			name: "fizz-buzz",
@@ -86,6 +87,7 @@
 
 // Test that the path returned by HostToolPath is correct
 func TestHostToolPath(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_binary_host {
 			name: "fizz-buzz",
@@ -100,6 +102,7 @@
 
 // Test that the flags being passed to rust_binary modules are as expected
 func TestBinaryFlags(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_binary_host {
 			name: "fizz-buzz",
@@ -114,7 +117,36 @@
 	}
 }
 
+func TestStaticBinaryFlags(t *testing.T) {
+	ctx := testRust(t, `
+		rust_binary {
+			name: "fizz",
+			srcs: ["foo.rs"],
+			static_executable: true,
+		}`)
+
+	fizzOut := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Output("fizz")
+	fizzMod := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module)
+
+	flags := fizzOut.Args["rustcFlags"]
+	linkFlags := fizzOut.Args["linkFlags"]
+	if !strings.Contains(flags, "-C relocation-model=static") {
+		t.Errorf("static binary missing '-C relocation-model=static' in rustcFlags, found: %#v", flags)
+	}
+	if !strings.Contains(linkFlags, "-static") {
+		t.Errorf("static binary missing '-static' in linkFlags, found: %#v", flags)
+	}
+
+	if !android.InList("libc", fizzMod.Properties.AndroidMkStaticLibs) {
+		t.Errorf("static binary not linking against libc as a static library")
+	}
+	if len(fizzMod.Properties.AndroidMkSharedLibs) > 0 {
+		t.Errorf("static binary incorrectly linking against shared libraries")
+	}
+}
+
 func TestLinkObjects(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_binary {
 			name: "fizz-buzz",
@@ -134,6 +166,7 @@
 
 // Test that stripped versions are correctly generated and used.
 func TestStrippedBinary(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_binary {
 			name: "foo",
diff --git a/rust/bindgen.go b/rust/bindgen.go
index d8d126d..ac33ff7 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -21,6 +21,7 @@
 	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
+	"android/soong/cc"
 	cc_config "android/soong/cc/config"
 )
 
@@ -67,48 +68,18 @@
 	// list of bindgen-specific flags and options
 	Bindgen_flags []string `android:"arch_variant"`
 
-	// list of clang flags required to correctly interpret the headers.
-	Cflags []string `android:"arch_variant"`
-
-	// list of directories relative to the Blueprints file that will
-	// be added to the include path using -I
-	Local_include_dirs []string `android:"arch_variant,variant_prepend"`
-
-	// list of static libraries that provide headers for this binding.
-	Static_libs []string `android:"arch_variant,variant_prepend"`
-
-	// list of shared libraries that provide headers for this binding.
-	Shared_libs []string `android:"arch_variant"`
-
 	// module name of a custom binary/script which should be used instead of the 'bindgen' binary. This custom
 	// binary must expect arguments in a similar fashion to bindgen, e.g.
 	//
 	// "my_bindgen [flags] wrapper_header.h -o [output_path] -- [clang flags]"
 	Custom_bindgen string `android:"path"`
-
-	// C standard version to use. Can be a specific version (such as "gnu11"),
-	// "experimental" (which will use draft versions like C1x when available),
-	// or the empty string (which will use the default).
-	//
-	// If this is set, the file extension will be ignored and this will be used as the std version value. Setting this
-	// to "default" will use the build system default version. This cannot be set at the same time as cpp_std.
-	C_std *string
-
-	// C++ standard version to use. Can be a specific version (such as
-	// "gnu++11"), "experimental" (which will use draft versions like C++1z when
-	// available), or the empty string (which will use the default).
-	//
-	// If this is set, the file extension will be ignored and this will be used as the std version value. Setting this
-	// to "default" will use the build system default version. This cannot be set at the same time as c_std.
-	Cpp_std *string
-
-	//TODO(b/161141999) Add support for headers from cc_library_header modules.
 }
 
 type bindgenDecorator struct {
 	*BaseSourceProvider
 
-	Properties BindgenProperties
+	Properties      BindgenProperties
+	ClangProperties cc.RustBindgenClangProperties
 }
 
 func (b *bindgenDecorator) getStdVersion(ctx ModuleContext, src android.Path) (string, bool) {
@@ -121,25 +92,25 @@
 		isCpp = true
 	}
 
-	if String(b.Properties.Cpp_std) != "" && String(b.Properties.C_std) != "" {
+	if String(b.ClangProperties.Cpp_std) != "" && String(b.ClangProperties.C_std) != "" {
 		ctx.PropertyErrorf("c_std", "c_std and cpp_std cannot both be defined at the same time.")
 	}
 
-	if String(b.Properties.Cpp_std) != "" {
-		if String(b.Properties.Cpp_std) == "experimental" {
+	if String(b.ClangProperties.Cpp_std) != "" {
+		if String(b.ClangProperties.Cpp_std) == "experimental" {
 			stdVersion = cc_config.ExperimentalCppStdVersion
-		} else if String(b.Properties.Cpp_std) == "default" {
+		} else if String(b.ClangProperties.Cpp_std) == "default" {
 			stdVersion = cc_config.CppStdVersion
 		} else {
-			stdVersion = String(b.Properties.Cpp_std)
+			stdVersion = String(b.ClangProperties.Cpp_std)
 		}
-	} else if b.Properties.C_std != nil {
-		if String(b.Properties.C_std) == "experimental" {
+	} else if b.ClangProperties.C_std != nil {
+		if String(b.ClangProperties.C_std) == "experimental" {
 			stdVersion = cc_config.ExperimentalCStdVersion
-		} else if String(b.Properties.C_std) == "default" {
+		} else if String(b.ClangProperties.C_std) == "default" {
 			stdVersion = cc_config.CStdVersion
 		} else {
-			stdVersion = String(b.Properties.C_std)
+			stdVersion = String(b.ClangProperties.C_std)
 		}
 	} else if isCpp {
 		stdVersion = cc_config.CppStdVersion
@@ -180,8 +151,8 @@
 	esc := proptools.NinjaAndShellEscapeList
 
 	// Module defined clang flags and include paths
-	cflags = append(cflags, esc(b.Properties.Cflags)...)
-	for _, include := range b.Properties.Local_include_dirs {
+	cflags = append(cflags, esc(b.ClangProperties.Cflags)...)
+	for _, include := range b.ClangProperties.Local_include_dirs {
 		cflags = append(cflags, "-I"+android.PathForModuleSrc(ctx, include).String())
 		implicits = append(implicits, android.PathForModuleSrc(ctx, include))
 	}
@@ -201,6 +172,8 @@
 	// Specify the header source language to avoid ambiguity.
 	if isCpp {
 		cflags = append(cflags, "-x c++")
+		// Add any C++ only flags.
+		cflags = append(cflags, esc(b.ClangProperties.Cppflags)...)
 	} else {
 		cflags = append(cflags, "-x c")
 	}
@@ -235,7 +208,7 @@
 
 func (b *bindgenDecorator) SourceProviderProps() []interface{} {
 	return append(b.BaseSourceProvider.SourceProviderProps(),
-		&b.Properties)
+		&b.Properties, &b.ClangProperties)
 }
 
 // rust_bindgen generates Rust FFI bindings to C libraries using bindgen given a wrapper header as the primary input.
@@ -257,6 +230,7 @@
 	bindgen := &bindgenDecorator{
 		BaseSourceProvider: NewSourceProvider(),
 		Properties:         BindgenProperties{},
+		ClangProperties:    cc.RustBindgenClangProperties{},
 	}
 
 	module := NewSourceProviderModule(hod, bindgen, false)
@@ -267,10 +241,10 @@
 func (b *bindgenDecorator) SourceProviderDeps(ctx DepsContext, deps Deps) Deps {
 	deps = b.BaseSourceProvider.SourceProviderDeps(ctx, deps)
 	if ctx.toolchain().Bionic() {
-		deps = bionicDeps(deps)
+		deps = bionicDeps(deps, false)
 	}
 
-	deps.SharedLibs = append(deps.SharedLibs, b.Properties.Shared_libs...)
-	deps.StaticLibs = append(deps.StaticLibs, b.Properties.Static_libs...)
+	deps.SharedLibs = append(deps.SharedLibs, b.ClangProperties.Shared_libs...)
+	deps.StaticLibs = append(deps.StaticLibs, b.ClangProperties.Static_libs...)
 	return deps
 }
diff --git a/rust/bindgen_test.go b/rust/bindgen_test.go
index e69bce2..7ff996d 100644
--- a/rust/bindgen_test.go
+++ b/rust/bindgen_test.go
@@ -20,9 +20,11 @@
 )
 
 func TestRustBindgen(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_bindgen {
 			name: "libbindgen",
+			defaults: ["cc_defaults_flags"],
 			wrapper_src: "src/any.h",
 			crate_name: "bindgen",
 			stem: "libbindgen",
@@ -40,6 +42,10 @@
 			name: "libfoo_static",
 			export_include_dirs: ["static_include"],
 		}
+		cc_defaults {
+			name: "cc_defaults_flags",
+			cflags: ["--default-flag"],
+		}
 	`)
 	libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs")
 	// Ensure that the flags are present and escaped
@@ -55,9 +61,13 @@
 	if !strings.Contains(libbindgen.Args["cflags"], "-Istatic_include") {
 		t.Errorf("missing static_libs exported includes in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"])
 	}
+	if !strings.Contains(libbindgen.Args["cflags"], "--default-flag") {
+		t.Errorf("rust_bindgen missing cflags defined in cc_defaults: cflags %#v", libbindgen.Args["cflags"])
+	}
 }
 
 func TestRustBindgenCustomBindgen(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_bindgen {
 			name: "libbindgen",
diff --git a/rust/builder_test.go b/rust/builder_test.go
index 5c11cb7..cda03a9 100644
--- a/rust/builder_test.go
+++ b/rust/builder_test.go
@@ -17,6 +17,7 @@
 import "testing"
 
 func TestSourceProviderCollision(t *testing.T) {
+	t.Parallel()
 	testRustError(t, "multiple source providers generate the same filename output: bindings.rs", `
 		rust_binary {
 			name: "source_collider",
diff --git a/rust/clippy_test.go b/rust/clippy_test.go
index 7815aab..786dc15 100644
--- a/rust/clippy_test.go
+++ b/rust/clippy_test.go
@@ -21,6 +21,7 @@
 )
 
 func TestClippy(t *testing.T) {
+	t.Parallel()
 
 	bp := `
 		// foo uses the default value of clippy_lints
diff --git a/rust/compiler.go b/rust/compiler.go
index aeb904b..8d2f09c 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -24,6 +24,14 @@
 	"android/soong/rust/config"
 )
 
+type RustLinkage int
+
+const (
+	DefaultLinkage RustLinkage = iota
+	RlibLinkage
+	DylibLinkage
+)
+
 func (compiler *baseCompiler) edition() string {
 	return proptools.StringDefault(compiler.Properties.Edition, config.DefaultEdition)
 }
@@ -146,12 +154,12 @@
 	panic("baseCompiler does not implement coverageOutputZipPath()")
 }
 
-func (compiler *baseCompiler) staticStd(ctx *depsContext) bool {
+func (compiler *baseCompiler) stdLinkage(ctx *depsContext) RustLinkage {
 	// For devices, we always link stdlibs in as dylibs by default.
 	if ctx.Device() {
-		return false
+		return DylibLinkage
 	} else {
-		return true
+		return RlibLinkage
 	}
 }
 
@@ -232,11 +240,18 @@
 	return deps
 }
 
-func bionicDeps(deps Deps) Deps {
-	deps.SharedLibs = append(deps.SharedLibs, "liblog")
-	deps.SharedLibs = append(deps.SharedLibs, "libc")
-	deps.SharedLibs = append(deps.SharedLibs, "libm")
-	deps.SharedLibs = append(deps.SharedLibs, "libdl")
+func bionicDeps(deps Deps, static bool) Deps {
+	bionicLibs := []string{}
+	bionicLibs = append(bionicLibs, "liblog")
+	bionicLibs = append(bionicLibs, "libc")
+	bionicLibs = append(bionicLibs, "libm")
+	bionicLibs = append(bionicLibs, "libdl")
+
+	if static {
+		deps.StaticLibs = append(deps.StaticLibs, bionicLibs...)
+	} else {
+		deps.SharedLibs = append(deps.SharedLibs, bionicLibs...)
+	}
 
 	//TODO(b/141331117) libstd requires libgcc on Android
 	deps.StaticLibs = append(deps.StaticLibs, "libgcc")
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index a25523c..70f0dff 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -23,6 +23,7 @@
 
 // Test that feature flags are being correctly generated.
 func TestFeaturesToFlags(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_library_host_dylib {
 			name: "libfoo",
@@ -44,6 +45,7 @@
 
 // Test that we reject multiple source files.
 func TestEnforceSingleSourceFile(t *testing.T) {
+	t.Parallel()
 
 	singleSrcError := "srcs can only contain one path for a rust file and source providers prefixed by \":\""
 
@@ -78,6 +80,7 @@
 }
 
 func TestInstallDir(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_library_dylib {
 			name: "libfoo",
@@ -108,6 +111,7 @@
 }
 
 func TestLints(t *testing.T) {
+	t.Parallel()
 
 	bp := `
 		// foo uses the default value of lints
@@ -180,6 +184,7 @@
 
 // Test that devices are linking the stdlib dynamically
 func TestStdDeviceLinkage(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_binary {
 			name: "fizz",
diff --git a/rust/config/OWNERS b/rust/config/OWNERS
new file mode 100644
index 0000000..dfff873
--- /dev/null
+++ b/rust/config/OWNERS
@@ -0,0 +1,2 @@
+per-file global.go = srhines@google.com, chh@google.com, pirama@google.com, yikong@google.com
+
diff --git a/rust/config/allowed_list.go b/rust/config/allowed_list.go
index 62d469e..678f822 100644
--- a/rust/config/allowed_list.go
+++ b/rust/config/allowed_list.go
@@ -1,6 +1,10 @@
 package config
 
 var (
+	// When adding a new path below, add a rustfmt.toml file at the root of
+	// the repository and enable the rustfmt repo hook. See aosp/1347562
+	// for an example.
+	// TODO(b/160223496): enable rustfmt globally.
 	RustAllowedPaths = []string{
 		"external/minijail",
 		"external/rust",
@@ -9,6 +13,7 @@
 		"frameworks/native/libs/binder/rust",
 		"prebuilts/rust",
 		"system/extras/profcollectd",
+		"system/hardware/interfaces/keystore2",
 		"system/security",
 		"system/tools/aidl",
 	}
diff --git a/rust/coverage_test.go b/rust/coverage_test.go
index 90155ca..ced548d 100644
--- a/rust/coverage_test.go
+++ b/rust/coverage_test.go
@@ -23,6 +23,7 @@
 
 // Test that coverage flags are being correctly generated.
 func TestCoverageFlags(t *testing.T) {
+	t.Parallel()
 	ctx := testRustCov(t, `
 		rust_library {
 			name: "libfoo_cov",
@@ -98,6 +99,7 @@
 
 // Test coverage files are included correctly
 func TestCoverageZip(t *testing.T) {
+	t.Parallel()
 	ctx := testRustCov(t, `
 		rust_library {
 			name: "libfoo",
@@ -174,6 +176,7 @@
 }
 
 func TestCoverageDeps(t *testing.T) {
+	t.Parallel()
 	ctx := testRustCov(t, `
 		rust_binary {
 			name: "fizz",
diff --git a/rust/library.go b/rust/library.go
index 2792c5b..3bba089 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -158,9 +158,12 @@
 	return library.MutatedProperties.VariantIsStatic
 }
 
-func (library *libraryDecorator) staticStd(ctx *depsContext) bool {
-	// libraries should only request the staticStd when building a static FFI or when variant is staticStd
-	return library.static() || library.MutatedProperties.VariantIsStaticStd
+func (library *libraryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
+	// libraries should only request the RlibLinkage when building a static FFI or when variant is StaticStd
+	if library.static() || library.MutatedProperties.VariantIsStaticStd {
+		return RlibLinkage
+	}
+	return DefaultLinkage
 }
 
 func (library *libraryDecorator) source() bool {
@@ -393,7 +396,7 @@
 	deps = library.baseCompiler.compilerDeps(ctx, deps)
 
 	if ctx.toolchain().Bionic() && (library.dylib() || library.shared()) {
-		deps = bionicDeps(deps)
+		deps = bionicDeps(deps, false)
 		deps.CrtBegin = "crtbegin_so"
 		deps.CrtEnd = "crtend_so"
 	}
diff --git a/rust/library_test.go b/rust/library_test.go
index fec3992..fdab78d 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -23,6 +23,7 @@
 
 // Test that variants are being generated correctly, and that crate-types are correct.
 func TestLibraryVariants(t *testing.T) {
+	t.Parallel()
 
 	ctx := testRust(t, `
 		rust_library_host {
@@ -71,6 +72,7 @@
 
 // Test that dylibs are not statically linking the standard library.
 func TestDylibPreferDynamic(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_library_host_dylib {
 			name: "libfoo",
@@ -86,6 +88,7 @@
 }
 
 func TestValidateLibraryStem(t *testing.T) {
+	t.Parallel()
 	testRustError(t, "crate_name must be defined.", `
 			rust_library_host {
 				name: "libfoo",
@@ -123,6 +126,7 @@
 }
 
 func TestSharedLibrary(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_ffi_shared {
 			name: "libfoo",
@@ -145,6 +149,7 @@
 }
 
 func TestStaticLibraryLinkage(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_ffi_static {
 			name: "libfoo",
@@ -162,6 +167,7 @@
 
 // Test that variants pull in the right type of rustlib autodep
 func TestAutoDeps(t *testing.T) {
+	t.Parallel()
 
 	ctx := testRust(t, `
                 rust_library_host {
@@ -209,6 +215,7 @@
 
 // Test that stripped versions are correctly generated and used.
 func TestStrippedLibrary(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_library_dylib {
 			name: "libfoo",
@@ -240,6 +247,7 @@
 }
 
 func TestLibstdLinkage(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_library {
 			name: "libfoo",
diff --git a/rust/project_json.go b/rust/project_json.go
index 8310479..8d161b2 100644
--- a/rust/project_json.go
+++ b/rust/project_json.go
@@ -30,16 +30,6 @@
 //
 //   $ SOONG_GEN_RUST_PROJECT=1 m nothing
 
-func init() {
-	android.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
-}
-
-func rustProjectGeneratorSingleton() android.Singleton {
-	return &projectGeneratorSingleton{}
-}
-
-type projectGeneratorSingleton struct{}
-
 const (
 	// Environment variables used to control the behavior of this singleton.
 	envVariableCollectRustDeps = "SOONG_GEN_RUST_PROJECT"
@@ -49,6 +39,7 @@
 // The format of rust-project.json is not yet finalized. A current description is available at:
 // https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/manual.adoc#non-cargo-based-projects
 type rustProjectDep struct {
+	// The Crate attribute is the index of the dependency in the Crates array in rustProjectJson.
 	Crate int    `json:"crate"`
 	Name  string `json:"name"`
 }
@@ -71,12 +62,50 @@
 	Deps map[string]int
 }
 
-func mergeDependencies(ctx android.SingletonContext, project *rustProjectJson,
-	knownCrates map[string]crateInfo, module android.Module,
-	crate *rustProjectCrate, deps map[string]int) {
+type projectGeneratorSingleton struct {
+	project     rustProjectJson
+	knownCrates map[string]crateInfo
+}
+
+func rustProjectGeneratorSingleton() android.Singleton {
+	return &projectGeneratorSingleton{}
+}
+
+func init() {
+	android.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
+}
+
+// librarySource finds the main source file (.rs) for a crate.
+func librarySource(ctx android.SingletonContext, rModule *Module, rustLib *libraryDecorator) (string, bool) {
+	srcs := rustLib.baseCompiler.Properties.Srcs
+	if len(srcs) != 0 {
+		return path.Join(ctx.ModuleDir(rModule), srcs[0]), true
+	}
+	if !rustLib.source() {
+		return "", false
+	}
+	// It is a SourceProvider module. If this module is host only, uses the variation for the host.
+	// Otherwise, use the variation for the primary target.
+	switch rModule.hod {
+	case android.HostSupported:
+	case android.HostSupportedNoCross:
+		if rModule.Target().String() != ctx.Config().BuildOSTarget.String() {
+			return "", false
+		}
+	default:
+		if rModule.Target().String() != ctx.Config().Targets[android.Android][0].String() {
+			return "", false
+		}
+	}
+	src := rustLib.sourceProvider.Srcs()[0]
+	return src.String(), true
+}
+
+func (singleton *projectGeneratorSingleton) mergeDependencies(ctx android.SingletonContext,
+	module android.Module, crate *rustProjectCrate, deps map[string]int) {
 
 	ctx.VisitDirectDeps(module, func(child android.Module) {
-		childId, childCrateName, ok := appendLibraryAndDeps(ctx, project, knownCrates, child)
+		childId, childCrateName, ok := singleton.appendLibraryAndDeps(ctx, child)
 		if !ok {
 			return
 		}
@@ -88,12 +117,10 @@
 	})
 }
 
-// appendLibraryAndDeps creates a rustProjectCrate for the module argument and
-// appends it to the rustProjectJson struct.  It visits the dependencies of the
-// module depth-first. If the current module is already in knownCrates, its
-// dependencies are merged. Returns a tuple (id, crate_name, ok).
-func appendLibraryAndDeps(ctx android.SingletonContext, project *rustProjectJson,
-	knownCrates map[string]crateInfo, module android.Module) (int, string, bool) {
+// appendLibraryAndDeps creates a rustProjectCrate for the module argument and appends it to singleton.project.
+// It visits the dependencies of the module depth-first so the dependency ID can be added to the current module. If the
+// current module is already in singleton.knownCrates, its dependencies are merged. Returns a tuple (id, crate_name, ok).
+func (singleton *projectGeneratorSingleton) appendLibraryAndDeps(ctx android.SingletonContext, module android.Module) (int, string, bool) {
 	rModule, ok := module.(*Module)
 	if !ok {
 		return 0, "", false
@@ -107,46 +134,45 @@
 	}
 	moduleName := ctx.ModuleName(module)
 	crateName := rModule.CrateName()
-	if cInfo, ok := knownCrates[moduleName]; ok {
+	if cInfo, ok := singleton.knownCrates[moduleName]; ok {
 		// We have seen this crate already; merge any new dependencies.
-		crate := project.Crates[cInfo.ID]
-		mergeDependencies(ctx, project, knownCrates, module, &crate, cInfo.Deps)
-		project.Crates[cInfo.ID] = crate
+		crate := singleton.project.Crates[cInfo.ID]
+		singleton.mergeDependencies(ctx, module, &crate, cInfo.Deps)
+		singleton.project.Crates[cInfo.ID] = crate
 		return cInfo.ID, crateName, true
 	}
 	crate := rustProjectCrate{Deps: make([]rustProjectDep, 0), Cfgs: make([]string, 0)}
-	srcs := rustLib.baseCompiler.Properties.Srcs
-	if len(srcs) == 0 {
+	rootModule, ok := librarySource(ctx, rModule, rustLib)
+	if !ok {
 		return 0, "", false
 	}
-	crate.RootModule = path.Join(ctx.ModuleDir(rModule), srcs[0])
+	crate.RootModule = rootModule
 	crate.Edition = rustLib.baseCompiler.edition()
 
 	deps := make(map[string]int)
-	mergeDependencies(ctx, project, knownCrates, module, &crate, deps)
+	singleton.mergeDependencies(ctx, module, &crate, deps)
 
-	id := len(project.Crates)
-	knownCrates[moduleName] = crateInfo{ID: id, Deps: deps}
-	project.Crates = append(project.Crates, crate)
+	id := len(singleton.project.Crates)
+	singleton.knownCrates[moduleName] = crateInfo{ID: id, Deps: deps}
+	singleton.project.Crates = append(singleton.project.Crates, crate)
 	// rust-analyzer requires that all crates belong to at least one root:
 	// https://github.com/rust-analyzer/rust-analyzer/issues/4735.
-	project.Roots = append(project.Roots, path.Dir(crate.RootModule))
+	singleton.project.Roots = append(singleton.project.Roots, path.Dir(crate.RootModule))
 	return id, crateName, true
 }
 
-func (r *projectGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+func (singleton *projectGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) {
 	if !ctx.Config().IsEnvTrue(envVariableCollectRustDeps) {
 		return
 	}
 
-	project := rustProjectJson{}
-	knownCrates := make(map[string]crateInfo)
+	singleton.knownCrates = make(map[string]crateInfo)
 	ctx.VisitAllModules(func(module android.Module) {
-		appendLibraryAndDeps(ctx, &project, knownCrates, module)
+		singleton.appendLibraryAndDeps(ctx, module)
 	})
 
 	path := android.PathForOutput(ctx, rustProjectJsonFileName)
-	err := createJsonFile(project, path)
+	err := createJsonFile(singleton.project, path)
 	if err != nil {
 		ctx.Errorf(err.Error())
 	}
diff --git a/rust/project_json_test.go b/rust/project_json_test.go
index 8521940..69288fc 100644
--- a/rust/project_json_test.go
+++ b/rust/project_json_test.go
@@ -18,25 +18,19 @@
 	"encoding/json"
 	"io/ioutil"
 	"path/filepath"
+	"strings"
 	"testing"
 
 	"android/soong/android"
-	"android/soong/cc"
 )
 
 // testProjectJson run the generation of rust-project.json. It returns the raw
 // content of the generated file.
-func testProjectJson(t *testing.T, bp string, fs map[string][]byte) []byte {
-	cc.GatherRequiredFilesForTest(fs)
-
-	env := map[string]string{"SOONG_GEN_RUST_PROJECT": "1"}
-	config := android.TestArchConfig(buildDir, env, bp, fs)
-	ctx := CreateTestContext()
-	ctx.Register(config)
-	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
-	android.FailIfErrored(t, errs)
-	_, errs = ctx.PrepareBuildActions(config)
-	android.FailIfErrored(t, errs)
+func testProjectJson(t *testing.T, bp string) []byte {
+	tctx := newTestRustCtx(t, bp)
+	tctx.env = map[string]string{"SOONG_GEN_RUST_PROJECT": "1"}
+	tctx.generateConfig()
+	tctx.parse(t)
 
 	// The JSON file is generated via WriteFileToOutputDir. Therefore, it
 	// won't appear in the Output of the TestingSingleton. Manually verify
@@ -86,12 +80,8 @@
 		crate_name: "b",
 		rlibs: ["liba"],
 	}
-	` + GatherRequiredDepsForTest()
-	fs := map[string][]byte{
-		"a/src/lib.rs": nil,
-		"b/src/lib.rs": nil,
-	}
-	jsonContent := testProjectJson(t, bp, fs)
+	`
+	jsonContent := testProjectJson(t, bp)
 	validateJsonCrates(t, jsonContent)
 }
 
@@ -100,22 +90,48 @@
 	rust_library {
 		name: "liba",
 		srcs: ["src/lib.rs"],
-		rlibs: ["libbindings"],
+		rlibs: ["libbindings1"],
 		crate_name: "a"
 	}
 	rust_bindgen {
-		name: "libbindings",
-		crate_name: "bindings",
-		source_stem: "bindings",
+		name: "libbindings1",
+		crate_name: "bindings1",
+		source_stem: "bindings1",
 		host_supported: true,
 		wrapper_src: "src/any.h",
 	}
-	` + GatherRequiredDepsForTest()
-	fs := map[string][]byte{
-		"src/lib.rs": nil,
+	rust_library_host {
+		name: "libb",
+		srcs: ["src/lib.rs"],
+		rustlibs: ["libbindings2"],
+		crate_name: "b"
 	}
-	jsonContent := testProjectJson(t, bp, fs)
-	validateJsonCrates(t, jsonContent)
+	rust_bindgen_host {
+		name: "libbindings2",
+		crate_name: "bindings2",
+		source_stem: "bindings2",
+		wrapper_src: "src/any.h",
+	}
+	`
+	jsonContent := testProjectJson(t, bp)
+	crates := validateJsonCrates(t, jsonContent)
+	for _, c := range crates {
+		crate, ok := c.(map[string]interface{})
+		if !ok {
+			t.Fatalf("Unexpected type for crate: %v", c)
+		}
+		rootModule, ok := crate["root_module"].(string)
+		if !ok {
+			t.Fatalf("Unexpected type for root_module: %v", crate["root_module"])
+		}
+		if strings.Contains(rootModule, "libbindings1") && !strings.Contains(rootModule, "android_arm64") {
+			t.Errorf("The source path for libbindings1 does not contain android_arm64, got %v", rootModule)
+		}
+		if strings.Contains(rootModule, "libbindings2") && !strings.Contains(rootModule, android.BuildOs.String()) {
+			t.Errorf("The source path for libbindings2 does not contain the BuildOs, got %v; want %v",
+				rootModule, android.BuildOs.String())
+		}
+	}
 }
 
 func TestProjectJsonMultiVersion(t *testing.T) {
@@ -136,13 +152,8 @@
 		crate_name: "b",
 		rustlibs: ["liba1", "liba2"],
 	}
-	` + GatherRequiredDepsForTest()
-	fs := map[string][]byte{
-		"a1/src/lib.rs": nil,
-		"a2/src/lib.rs": nil,
-		"b/src/lib.rs":  nil,
-	}
-	jsonContent := testProjectJson(t, bp, fs)
+	`
+	jsonContent := testProjectJson(t, bp)
 	crates := validateJsonCrates(t, jsonContent)
 	for _, crate := range crates {
 		c := crate.(map[string]interface{})
diff --git a/rust/protobuf_test.go b/rust/protobuf_test.go
index bd11a5a..cfe56a3 100644
--- a/rust/protobuf_test.go
+++ b/rust/protobuf_test.go
@@ -20,6 +20,7 @@
 )
 
 func TestRustProtobuf(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_protobuf {
 			name: "librust_proto",
diff --git a/rust/rust.go b/rust/rust.go
index 1f8b904..ba8673c 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -221,6 +221,10 @@
 	return false
 }
 
+func (mod *Module) SplitPerApiLevel() bool {
+	return false
+}
+
 func (mod *Module) ToolchainLibrary() bool {
 	return false
 }
@@ -294,7 +298,7 @@
 	Disabled() bool
 	SetDisabled()
 
-	staticStd(ctx *depsContext) bool
+	stdLinkage(ctx *depsContext) RustLinkage
 }
 
 type exportedFlagsProducer interface {
@@ -387,6 +391,7 @@
 	module.AddProperties(props...)
 	module.AddProperties(
 		&BaseProperties{},
+		&BindgenProperties{},
 		&BaseCompilerProperties{},
 		&BinaryCompilerProperties{},
 		&LibraryCompilerProperties{},
@@ -395,6 +400,7 @@
 		&SourceProviderProperties{},
 		&TestProperties{},
 		&cc.CoverageProperties{},
+		&cc.RustBindgenClangProperties{},
 		&ClippyProperties{},
 	)
 
@@ -993,17 +999,14 @@
 	}
 
 	deps := mod.deps(ctx)
-	commonDepVariations := []blueprint.Variation{}
-	if cc.VersionVariantAvailable(mod) {
-		commonDepVariations = append(commonDepVariations,
-			blueprint.Variation{Mutator: "version", Variation: ""})
-	}
+	var commonDepVariations []blueprint.Variation
 	if !mod.Host() {
 		commonDepVariations = append(commonDepVariations,
 			blueprint.Variation{Mutator: "image", Variation: android.CoreVariation})
 	}
+
 	stdLinkage := "dylib-std"
-	if mod.compiler.staticStd(ctx) {
+	if mod.compiler.stdLinkage(ctx) == RlibLinkage {
 		stdLinkage = "rlib-std"
 	}
 
@@ -1035,7 +1038,7 @@
 		}
 	}
 	if deps.Stdlibs != nil {
-		if mod.compiler.staticStd(ctx) {
+		if mod.compiler.stdLinkage(ctx) == RlibLinkage {
 			actx.AddVariationDependencies(
 				append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: "rlib"}),
 				rlibDepTag, deps.Stdlibs...)
@@ -1052,7 +1055,7 @@
 		blueprint.Variation{Mutator: "link", Variation: "static"}),
 		cc.StaticDepTag(), deps.StaticLibs...)
 
-	crtVariations := append(cc.GetCrtVariations(ctx, mod), commonDepVariations...)
+	crtVariations := cc.GetCrtVariations(ctx, mod)
 	if deps.CrtBegin != "" {
 		actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag, deps.CrtBegin)
 	}
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 4842a4c..ec78860 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -54,10 +54,58 @@
 	os.Exit(run())
 }
 
-func testConfig(bp string) android.Config {
-	bp = bp + GatherRequiredDepsForTest()
+// testRust returns a TestContext in which a basic environment has been setup.
+// This environment contains a few mocked files. See testRustCtx.useMockedFs
+// for the list of these files.
+func testRust(t *testing.T, bp string) *android.TestContext {
+	tctx := newTestRustCtx(t, bp)
+	tctx.useMockedFs()
+	tctx.generateConfig()
+	return tctx.parse(t)
+}
 
-	fs := map[string][]byte{
+// testRustCov returns a TestContext in which a basic environment has been
+// setup. This environment explicitly enables coverage.
+func testRustCov(t *testing.T, bp string) *android.TestContext {
+	tctx := newTestRustCtx(t, bp)
+	tctx.useMockedFs()
+	tctx.generateConfig()
+	tctx.enableCoverage(t)
+	return tctx.parse(t)
+}
+
+// testRustError ensures that at least one error was raised and its value
+// matches the pattern provided. The error can be either in the parsing of the
+// Blueprint or when generating the build actions.
+func testRustError(t *testing.T, pattern string, bp string) {
+	tctx := newTestRustCtx(t, bp)
+	tctx.useMockedFs()
+	tctx.generateConfig()
+	tctx.parseError(t, pattern)
+}
+
+// testRustCtx is used to build a particular test environment. Unless your
+// tests requires a specific setup, prefer the wrapping functions: testRust,
+// testRustCov or testRustError.
+type testRustCtx struct {
+	bp     string
+	fs     map[string][]byte
+	env    map[string]string
+	config *android.Config
+}
+
+// newTestRustCtx returns a new testRustCtx for the Blueprint definition argument.
+func newTestRustCtx(t *testing.T, bp string) *testRustCtx {
+	// TODO (b/140435149)
+	if runtime.GOOS != "linux" {
+		t.Skip("Rust Soong tests can only be run on Linux hosts currently")
+	}
+	return &testRustCtx{bp: bp}
+}
+
+// useMockedFs setup a default mocked filesystem for the test environment.
+func (tctx *testRustCtx) useMockedFs() {
+	tctx.fs = map[string][]byte{
 		"foo.rs":     nil,
 		"foo.c":      nil,
 		"src/bar.rs": nil,
@@ -66,57 +114,51 @@
 		"liby.so":    nil,
 		"libz.so":    nil,
 	}
-
-	cc.GatherRequiredFilesForTest(fs)
-
-	return android.TestArchConfig(buildDir, nil, bp, fs)
 }
 
-func testRust(t *testing.T, bp string) *android.TestContext {
-	return testRustContext(t, bp, false)
+// generateConfig creates the android.Config based on the bp, fs and env
+// attributes of the testRustCtx.
+func (tctx *testRustCtx) generateConfig() {
+	tctx.bp = tctx.bp + GatherRequiredDepsForTest()
+	cc.GatherRequiredFilesForTest(tctx.fs)
+	config := android.TestArchConfig(buildDir, tctx.env, tctx.bp, tctx.fs)
+	tctx.config = &config
 }
 
-func testRustCov(t *testing.T, bp string) *android.TestContext {
-	return testRustContext(t, bp, true)
-}
-
-func testRustContext(t *testing.T, bp string, coverage bool) *android.TestContext {
-	// TODO (b/140435149)
-	if runtime.GOOS != "linux" {
-		t.Skip("Only the Linux toolchain is supported for Rust")
+// enableCoverage configures the test to enable coverage.
+func (tctx *testRustCtx) enableCoverage(t *testing.T) {
+	if tctx.config == nil {
+		t.Fatalf("tctx.config not been generated yet. Please call generateConfig first.")
 	}
+	tctx.config.TestProductVariables.GcovCoverage = proptools.BoolPtr(true)
+	tctx.config.TestProductVariables.Native_coverage = proptools.BoolPtr(true)
+	tctx.config.TestProductVariables.NativeCoveragePaths = []string{"*"}
+}
 
-	t.Helper()
-	config := testConfig(bp)
-
-	if coverage {
-		config.TestProductVariables.GcovCoverage = proptools.BoolPtr(true)
-		config.TestProductVariables.Native_coverage = proptools.BoolPtr(true)
-		config.TestProductVariables.NativeCoveragePaths = []string{"*"}
+// parse validates the configuration and parses the Blueprint file. It returns
+// a TestContext which can be used to retrieve the generated modules via
+// ModuleForTests.
+func (tctx testRustCtx) parse(t *testing.T) *android.TestContext {
+	if tctx.config == nil {
+		t.Fatalf("tctx.config not been generated yet. Please call generateConfig first.")
 	}
-
 	ctx := CreateTestContext()
-	ctx.Register(config)
-
+	ctx.Register(*tctx.config)
 	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
 	android.FailIfErrored(t, errs)
-	_, errs = ctx.PrepareBuildActions(config)
+	_, errs = ctx.PrepareBuildActions(*tctx.config)
 	android.FailIfErrored(t, errs)
-
 	return ctx
 }
 
-func testRustError(t *testing.T, pattern string, bp string) {
-	// TODO (b/140435149)
-	if runtime.GOOS != "linux" {
-		t.Skip("Only the Linux toolchain is supported for Rust")
+// parseError parses the Blueprint file and ensure that at least one error
+// matching the provided pattern is observed.
+func (tctx testRustCtx) parseError(t *testing.T, pattern string) {
+	if tctx.config == nil {
+		t.Fatalf("tctx.config not been generated yet. Please call generateConfig first.")
 	}
-
-	t.Helper()
-	config := testConfig(bp)
-
 	ctx := CreateTestContext()
-	ctx.Register(config)
+	ctx.Register(*tctx.config)
 
 	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
 	if len(errs) > 0 {
@@ -124,7 +166,7 @@
 		return
 	}
 
-	_, errs = ctx.PrepareBuildActions(config)
+	_, errs = ctx.PrepareBuildActions(*tctx.config)
 	if len(errs) > 0 {
 		android.FailIfNoMatchingErrors(t, pattern, errs)
 		return
@@ -135,6 +177,7 @@
 
 // Test that we can extract the link path from a lib path.
 func TestLinkPathFromFilePath(t *testing.T) {
+	t.Parallel()
 	barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so")
 	libName := linkPathFromFilePath(barPath)
 	expectedResult := "out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/"
@@ -146,6 +189,7 @@
 
 // Test to make sure dependencies are being picked up correctly.
 func TestDepsTracking(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_ffi_host_static {
 			name: "libstatic",
@@ -207,6 +251,7 @@
 }
 
 func TestSourceProviderDeps(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_binary {
 			name: "fizz-buzz-dep",
@@ -294,6 +339,7 @@
 }
 
 func TestSourceProviderTargetMismatch(t *testing.T) {
+	t.Parallel()
 	// This might error while building the dependency tree or when calling depsToPaths() depending on the lunched
 	// target, which results in two different errors. So don't check the error, just confirm there is one.
 	testRustError(t, ".*", `
@@ -316,6 +362,7 @@
 
 // Test to make sure proc_macros use host variants when building device modules.
 func TestProcMacroDeviceDeps(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_library_host_rlib {
 			name: "libbar",
@@ -343,6 +390,7 @@
 
 // Test that no_stdlibs suppresses dependencies on rust standard libraries
 func TestNoStdlibs(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_binary {
 			name: "fizz-buzz",
@@ -358,6 +406,7 @@
 
 // Test that libraries provide both 32-bit and 64-bit variants.
 func TestMultilib(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_library_rlib {
 			name: "libfoo",
diff --git a/rust/source_provider_test.go b/rust/source_provider_test.go
index 6e68ae6..f16d694 100644
--- a/rust/source_provider_test.go
+++ b/rust/source_provider_test.go
@@ -21,6 +21,7 @@
 var stemRequiredError = "source_stem property is undefined but required for rust_bindgen modules"
 
 func TestSourceProviderRequiredFields(t *testing.T) {
+	t.Parallel()
 	testRustError(t, stemRequiredError, `
 		rust_bindgen {
 			name: "libbindgen",
diff --git a/rust/test.go b/rust/test.go
index 0679448..bc7f53c 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -134,6 +134,6 @@
 	return module.Init()
 }
 
-func (test *testDecorator) staticStd(ctx *depsContext) bool {
-	return true
+func (test *testDecorator) stdLinkage(ctx *depsContext) RustLinkage {
+	return RlibLinkage
 }
diff --git a/rust/test_test.go b/rust/test_test.go
index fea2ad0..bb4695a 100644
--- a/rust/test_test.go
+++ b/rust/test_test.go
@@ -22,6 +22,7 @@
 )
 
 func TestRustTest(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_test_host {
 			name: "my_test",
@@ -37,6 +38,7 @@
 }
 
 func TestRustTestLinkage(t *testing.T) {
+	t.Parallel()
 	ctx := testRust(t, `
 		rust_test {
 			name: "my_test",
diff --git a/rust/testing.go b/rust/testing.go
index ee303ed..42b0da1 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -117,6 +117,7 @@
 	ctx.RegisterModuleType("rust_binary", RustBinaryFactory)
 	ctx.RegisterModuleType("rust_binary_host", RustBinaryHostFactory)
 	ctx.RegisterModuleType("rust_bindgen", RustBindgenFactory)
+	ctx.RegisterModuleType("rust_bindgen_host", RustBindgenHostFactory)
 	ctx.RegisterModuleType("rust_test", RustTestFactory)
 	ctx.RegisterModuleType("rust_test_host", RustTestHostFactory)
 	ctx.RegisterModuleType("rust_library", RustLibraryFactory)
diff --git a/scripts/update-apex-allowed-deps.sh b/scripts/update-apex-allowed-deps.sh
new file mode 100755
index 0000000..872d746
--- /dev/null
+++ b/scripts/update-apex-allowed-deps.sh
@@ -0,0 +1,39 @@
+#!/bin/bash -e
+#
+# The script to run locally to re-generate global allowed list of dependencies
+# for updatable modules.
+
+if [ ! -e "build/envsetup.sh" ]; then
+  echo "ERROR: $0 must be run from the top of the tree"
+  exit 1
+fi
+
+source build/envsetup.sh > /dev/null || exit 1
+
+readonly OUT_DIR=$(get_build_var OUT_DIR)
+
+readonly ALLOWED_DEPS_FILE="build/soong/apex/allowed_deps.txt"
+readonly NEW_ALLOWED_DEPS_FILE="${OUT_DIR}/soong/apex/depsinfo/new-allowed-deps.txt"
+
+# If the script is run after droidcore failure, ${NEW_ALLOWED_DEPS_FILE}
+# should already be built. If running the script manually, make sure it exists.
+m "${NEW_ALLOWED_DEPS_FILE}" -j
+
+cat > "${ALLOWED_DEPS_FILE}" << EndOfFileComment
+# A list of allowed dependencies for all updatable modules.
+#
+# The list tracks all direct and transitive dependencies that end up within any
+# of the updatable binaries; specifically excluding external dependencies
+# required to compile those binaries. This prevents potential regressions in
+# case a new dependency is not aware of the different functional and
+# non-functional requirements being part of an updatable module, for example
+# setting correct min_sdk_version.
+#
+# To update the list, run:
+# repo-root$ build/soong/scripts/update-apex-allowed-deps.sh
+#
+# See go/apex-allowed-deps-error for more details.
+# TODO(b/157465465): introduce automated quality signals and remove this list.
+EndOfFileComment
+
+cat "${NEW_ALLOWED_DEPS_FILE}" >> "${ALLOWED_DEPS_FILE}"
diff --git a/sdk/bp_test.go b/sdk/bp_test.go
index e1edc51..4cd54c7 100644
--- a/sdk/bp_test.go
+++ b/sdk/bp_test.go
@@ -180,6 +180,7 @@
 }
 
 func TestTransformRemoveProperty(t *testing.T) {
+	t.Parallel()
 
 	helper := &TestHelper{t}
 
@@ -195,6 +196,7 @@
 }
 
 func TestTransformRemovePropertySet(t *testing.T) {
+	t.Parallel()
 
 	helper := &TestHelper{t}
 
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 8c9e228..e0cba09 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -40,6 +40,7 @@
 // Contains tests for SDK members provided by the cc package.
 
 func TestSingleDeviceOsAssumption(t *testing.T) {
+	t.Parallel()
 	// Mock a module with DeviceSupported() == true.
 	s := &sdk{}
 	android.InitAndroidArchModule(s, android.DeviceSupported, android.MultilibCommon)
@@ -54,6 +55,7 @@
 }
 
 func TestSdkIsCompileMultilibBoth(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -84,6 +86,7 @@
 }
 
 func TestSdkCompileMultilibOverride(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -108,6 +111,7 @@
 cc_prebuilt_library_shared {
     name: "mysdk_sdkmember@current",
     sdk_member_name: "sdkmember",
+    visibility: ["//visibility:public"],
     host_supported: true,
     installable: false,
     stl: "none",
@@ -131,6 +135,7 @@
 cc_prebuilt_library_shared {
     name: "sdkmember",
     prefer: false,
+    visibility: ["//visibility:public"],
     host_supported: true,
     stl: "none",
     compile_multilib: "64",
@@ -152,6 +157,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     host_supported: true,
     native_shared_libs: ["mysdk_sdkmember@current"],
     compile_multilib: "64",
@@ -172,6 +178,7 @@
 }
 
 func TestBasicSdkWithCc(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -278,6 +285,7 @@
 
 // Make sure the sdk can use host specific cc libraries static/shared and both.
 func TestHostSdkWithCc(t *testing.T) {
+	t.Parallel()
 	testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -301,6 +309,7 @@
 
 // Make sure the sdk can use cc libraries static/shared and both.
 func TestSdkWithCc(t *testing.T) {
+	t.Parallel()
 	testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -331,6 +340,7 @@
 }
 
 func TestSnapshotWithObject(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -353,6 +363,7 @@
 cc_prebuilt_object {
     name: "mysdk_crtobj@current",
     sdk_member_name: "crtobj",
+    visibility: ["//visibility:public"],
     stl: "none",
     compile_multilib: "both",
     sanitize: {
@@ -371,6 +382,7 @@
 cc_prebuilt_object {
     name: "crtobj",
     prefer: false,
+    visibility: ["//visibility:public"],
     stl: "none",
     compile_multilib: "both",
     sanitize: {
@@ -388,6 +400,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     native_objects: ["mysdk_crtobj@current"],
 }
 `),
@@ -399,6 +412,7 @@
 }
 
 func TestSnapshotWithCcDuplicateHeaders(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -435,9 +449,12 @@
 	)
 }
 
-// Verify that when the shared library has some common and some arch specific properties that the generated
-// snapshot is optimized properly.
+// Verify that when the shared library has some common and some arch specific
+// properties that the generated snapshot is optimized properly. Substruct
+// handling is tested with the sanitize clauses (but note there's a lot of
+// built-in logic in sanitize.go that can affect those flags).
 func TestSnapshotWithCcSharedLibraryCommonProperties(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -451,9 +468,18 @@
 				"aidl/foo/bar/Test.aidl",
 			],
 			export_include_dirs: ["include"],
+			sanitize: {
+				fuzzer: false,
+				integer_overflow: true,
+				diag: { undefined: false },
+			},
 			arch: {
 				arm64: {
 					export_system_include_dirs: ["arm64/include"],
+					sanitize: {
+						hwaddress: true,
+						integer_overflow: false,
+					},
 				},
 			},
 			stl: "none",
@@ -467,17 +493,31 @@
 cc_prebuilt_library_shared {
     name: "mysdk_mynativelib@current",
     sdk_member_name: "mynativelib",
+    visibility: ["//visibility:public"],
     installable: false,
     stl: "none",
     compile_multilib: "both",
     export_include_dirs: ["include/include"],
+    sanitize: {
+        fuzzer: false,
+        diag: {
+            undefined: false,
+        },
+    },
     arch: {
         arm64: {
             srcs: ["arm64/lib/mynativelib.so"],
             export_system_include_dirs: ["arm64/include/arm64/include"],
+            sanitize: {
+                hwaddress: true,
+                integer_overflow: false,
+            },
         },
         arm: {
             srcs: ["arm/lib/mynativelib.so"],
+            sanitize: {
+                integer_overflow: true,
+            },
         },
     },
 }
@@ -485,34 +525,50 @@
 cc_prebuilt_library_shared {
     name: "mynativelib",
     prefer: false,
+    visibility: ["//visibility:public"],
     stl: "none",
     compile_multilib: "both",
     export_include_dirs: ["include/include"],
+    sanitize: {
+        fuzzer: false,
+        diag: {
+            undefined: false,
+        },
+    },
     arch: {
         arm64: {
             srcs: ["arm64/lib/mynativelib.so"],
             export_system_include_dirs: ["arm64/include/arm64/include"],
+            sanitize: {
+                hwaddress: true,
+                integer_overflow: false,
+            },
         },
         arm: {
             srcs: ["arm/lib/mynativelib.so"],
+            sanitize: {
+                integer_overflow: true,
+            },
         },
     },
 }
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     native_shared_libs: ["mysdk_mynativelib@current"],
 }
 `),
 		checkAllCopyRules(`
 include/Test.h -> include/include/Test.h
-.intermediates/mynativelib/android_arm64_armv8-a_shared/mynativelib.so -> arm64/lib/mynativelib.so
+.intermediates/mynativelib/android_arm64_armv8-a_shared_hwasan/mynativelib.so -> arm64/lib/mynativelib.so
 arm64/include/Arm64Test.h -> arm64/include/arm64/include/Arm64Test.h
 .intermediates/mynativelib/android_arm_armv7-a-neon_shared/mynativelib.so -> arm/lib/mynativelib.so`),
 	)
 }
 
 func TestSnapshotWithCcBinary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		module_exports {
 			name: "mymodule_exports",
@@ -535,6 +591,7 @@
 cc_prebuilt_binary {
     name: "mymodule_exports_mynativebinary@current",
     sdk_member_name: "mynativebinary",
+    visibility: ["//visibility:public"],
     installable: false,
     compile_multilib: "both",
     arch: {
@@ -550,6 +607,7 @@
 cc_prebuilt_binary {
     name: "mynativebinary",
     prefer: false,
+    visibility: ["//visibility:public"],
     compile_multilib: "both",
     arch: {
         arm64: {
@@ -563,6 +621,7 @@
 
 module_exports_snapshot {
     name: "mymodule_exports@current",
+    visibility: ["//visibility:public"],
     native_binaries: ["mymodule_exports_mynativebinary@current"],
 }
 `),
@@ -574,6 +633,7 @@
 }
 
 func TestMultipleHostOsTypesSnapshotWithCcBinary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		module_exports {
 			name: "myexports",
@@ -611,6 +671,7 @@
 cc_prebuilt_binary {
     name: "myexports_mynativebinary@current",
     sdk_member_name: "mynativebinary",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     installable: false,
@@ -642,6 +703,7 @@
 cc_prebuilt_binary {
     name: "mynativebinary",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     stl: "none",
@@ -671,6 +733,7 @@
 
 module_exports_snapshot {
     name: "myexports@current",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     native_binaries: ["myexports_mynativebinary@current"],
@@ -697,6 +760,7 @@
 }
 
 func TestSnapshotWithSingleHostOsType(t *testing.T) {
+	t.Parallel()
 	ctx, config := testSdkContext(`
 		cc_defaults {
 			name: "mydefaults",
@@ -749,6 +813,7 @@
 cc_prebuilt_binary {
     name: "myexports_mynativebinary@current",
     sdk_member_name: "mynativebinary",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     installable: false,
@@ -770,6 +835,7 @@
 cc_prebuilt_binary {
     name: "mynativebinary",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     stl: "none",
@@ -790,6 +856,7 @@
 cc_prebuilt_library_shared {
     name: "myexports_mynativelib@current",
     sdk_member_name: "mynativelib",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     installable: false,
@@ -811,6 +878,7 @@
 cc_prebuilt_library_shared {
     name: "mynativelib",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     stl: "none",
@@ -830,6 +898,7 @@
 
 module_exports_snapshot {
     name: "myexports@current",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     native_binaries: ["myexports_mynativebinary@current"],
@@ -855,6 +924,7 @@
 // Test that we support the necessary flags for the linker binary, which is
 // special in several ways.
 func TestSnapshotWithCcStaticNocrtBinary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		module_exports {
 			name: "mymodule_exports",
@@ -883,6 +953,7 @@
 cc_prebuilt_binary {
     name: "mymodule_exports_linker@current",
     sdk_member_name: "linker",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     installable: false,
@@ -909,6 +980,7 @@
 cc_prebuilt_binary {
     name: "linker",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     stl: "none",
@@ -933,6 +1005,7 @@
 
 module_exports_snapshot {
     name: "mymodule_exports@current",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     native_binaries: ["mymodule_exports_linker@current"],
@@ -954,6 +1027,7 @@
 }
 
 func TestSnapshotWithCcSharedLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -982,6 +1056,7 @@
 cc_prebuilt_library_shared {
     name: "mysdk_mynativelib@current",
     sdk_member_name: "mynativelib",
+    visibility: ["//visibility:public"],
     apex_available: [
         "apex1",
         "apex2",
@@ -1005,6 +1080,7 @@
 cc_prebuilt_library_shared {
     name: "mynativelib",
     prefer: false,
+    visibility: ["//visibility:public"],
     apex_available: [
         "apex1",
         "apex2",
@@ -1026,6 +1102,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     native_shared_libs: ["mysdk_mynativelib@current"],
 }
 `),
@@ -1044,6 +1121,7 @@
 }
 
 func TestSnapshotWithCcSharedLibrarySharedLibs(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -1110,6 +1188,7 @@
 cc_prebuilt_library_shared {
     name: "mysdk_mynativelib@current",
     sdk_member_name: "mynativelib",
+    visibility: ["//visibility:public"],
     installable: false,
     stl: "none",
     compile_multilib: "both",
@@ -1130,6 +1209,7 @@
 cc_prebuilt_library_shared {
     name: "mynativelib",
     prefer: false,
+    visibility: ["//visibility:public"],
     stl: "none",
     compile_multilib: "both",
     shared_libs: [
@@ -1149,6 +1229,7 @@
 cc_prebuilt_library_shared {
     name: "mysdk_myothernativelib@current",
     sdk_member_name: "myothernativelib",
+    visibility: ["//visibility:public"],
     installable: false,
     stl: "none",
     compile_multilib: "both",
@@ -1166,6 +1247,7 @@
 cc_prebuilt_library_shared {
     name: "myothernativelib",
     prefer: false,
+    visibility: ["//visibility:public"],
     stl: "none",
     compile_multilib: "both",
     system_shared_libs: ["libm"],
@@ -1182,6 +1264,7 @@
 cc_prebuilt_library_shared {
     name: "mysdk_mysystemnativelib@current",
     sdk_member_name: "mysystemnativelib",
+    visibility: ["//visibility:public"],
     installable: false,
     stl: "none",
     compile_multilib: "both",
@@ -1198,6 +1281,7 @@
 cc_prebuilt_library_shared {
     name: "mysystemnativelib",
     prefer: false,
+    visibility: ["//visibility:public"],
     stl: "none",
     compile_multilib: "both",
     arch: {
@@ -1212,6 +1296,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     native_shared_libs: [
         "mysdk_mynativelib@current",
         "mysdk_myothernativelib@current",
@@ -1231,6 +1316,7 @@
 }
 
 func TestHostSnapshotWithCcSharedLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -1263,6 +1349,7 @@
 cc_prebuilt_library_shared {
     name: "mysdk_mynativelib@current",
     sdk_member_name: "mynativelib",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     installable: false,
@@ -1291,6 +1378,7 @@
 cc_prebuilt_library_shared {
     name: "mynativelib",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     sdk_version: "minimum",
@@ -1317,6 +1405,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     native_shared_libs: ["mysdk_mynativelib@current"],
@@ -1345,6 +1434,7 @@
 }
 
 func TestMultipleHostOsTypesSnapshotWithCcSharedLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -1381,6 +1471,7 @@
 cc_prebuilt_library_shared {
     name: "mysdk_mynativelib@current",
     sdk_member_name: "mynativelib",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     installable: false,
@@ -1412,6 +1503,7 @@
 cc_prebuilt_library_shared {
     name: "mynativelib",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     stl: "none",
@@ -1441,6 +1533,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     native_shared_libs: ["mysdk_mynativelib@current"],
@@ -1467,6 +1560,7 @@
 }
 
 func TestSnapshotWithCcStaticLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		module_exports {
 			name: "myexports",
@@ -1494,6 +1588,7 @@
 cc_prebuilt_library_static {
     name: "myexports_mynativelib@current",
     sdk_member_name: "mynativelib",
+    visibility: ["//visibility:public"],
     installable: false,
     stl: "none",
     compile_multilib: "both",
@@ -1513,6 +1608,7 @@
 cc_prebuilt_library_static {
     name: "mynativelib",
     prefer: false,
+    visibility: ["//visibility:public"],
     stl: "none",
     compile_multilib: "both",
     export_include_dirs: ["include/include"],
@@ -1530,6 +1626,7 @@
 
 module_exports_snapshot {
     name: "myexports@current",
+    visibility: ["//visibility:public"],
     native_static_libs: ["myexports_mynativelib@current"],
 }
 `),
@@ -1548,6 +1645,7 @@
 }
 
 func TestHostSnapshotWithCcStaticLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		module_exports {
 			name: "myexports",
@@ -1579,6 +1677,7 @@
 cc_prebuilt_library_static {
     name: "myexports_mynativelib@current",
     sdk_member_name: "mynativelib",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     installable: false,
@@ -1606,6 +1705,7 @@
 cc_prebuilt_library_static {
     name: "mynativelib",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     stl: "none",
@@ -1631,6 +1731,7 @@
 
 module_exports_snapshot {
     name: "myexports@current",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     native_static_libs: ["myexports_mynativelib@current"],
@@ -1659,6 +1760,7 @@
 }
 
 func TestSnapshotWithCcLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		module_exports {
 			name: "myexports",
@@ -1684,6 +1786,7 @@
 cc_prebuilt_library {
     name: "myexports_mynativelib@current",
     sdk_member_name: "mynativelib",
+    visibility: ["//visibility:public"],
     installable: false,
     recovery_available: true,
     vendor_available: true,
@@ -1713,6 +1816,7 @@
 cc_prebuilt_library {
     name: "mynativelib",
     prefer: false,
+    visibility: ["//visibility:public"],
     recovery_available: true,
     vendor_available: true,
     stl: "none",
@@ -1740,6 +1844,7 @@
 
 module_exports_snapshot {
     name: "myexports@current",
+    visibility: ["//visibility:public"],
     native_libs: ["myexports_mynativelib@current"],
 }
 `),
@@ -1753,6 +1858,7 @@
 }
 
 func TestHostSnapshotWithMultiLib64(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		module_exports {
 			name: "myexports",
@@ -1789,6 +1895,7 @@
 cc_prebuilt_library_static {
     name: "myexports_mynativelib@current",
     sdk_member_name: "mynativelib",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     installable: false,
@@ -1812,6 +1919,7 @@
 cc_prebuilt_library_static {
     name: "mynativelib",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     stl: "none",
@@ -1833,6 +1941,7 @@
 
 module_exports_snapshot {
     name: "myexports@current",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     native_static_libs: ["myexports_mynativelib@current"],
@@ -1857,6 +1966,7 @@
 }
 
 func TestSnapshotWithCcHeadersLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -1877,6 +1987,7 @@
 cc_prebuilt_library_headers {
     name: "mysdk_mynativeheaders@current",
     sdk_member_name: "mynativeheaders",
+    visibility: ["//visibility:public"],
     stl: "none",
     compile_multilib: "both",
     export_include_dirs: ["include/include"],
@@ -1885,6 +1996,7 @@
 cc_prebuilt_library_headers {
     name: "mynativeheaders",
     prefer: false,
+    visibility: ["//visibility:public"],
     stl: "none",
     compile_multilib: "both",
     export_include_dirs: ["include/include"],
@@ -1892,6 +2004,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     native_header_libs: ["mysdk_mynativeheaders@current"],
 }
 `),
@@ -1902,6 +2015,7 @@
 }
 
 func TestHostSnapshotWithCcHeadersLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -1926,6 +2040,7 @@
 cc_prebuilt_library_headers {
     name: "mysdk_mynativeheaders@current",
     sdk_member_name: "mynativeheaders",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     stl: "none",
@@ -1944,6 +2059,7 @@
 cc_prebuilt_library_headers {
     name: "mynativeheaders",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     stl: "none",
@@ -1961,6 +2077,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     native_header_libs: ["mysdk_mynativeheaders@current"],
@@ -1981,6 +2098,7 @@
 }
 
 func TestDeviceAndHostSnapshotWithCcHeadersLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -2011,6 +2129,7 @@
 cc_prebuilt_library_headers {
     name: "mysdk_mynativeheaders@current",
     sdk_member_name: "mynativeheaders",
+    visibility: ["//visibility:public"],
     host_supported: true,
     stl: "none",
     compile_multilib: "both",
@@ -2032,6 +2151,7 @@
 cc_prebuilt_library_headers {
     name: "mynativeheaders",
     prefer: false,
+    visibility: ["//visibility:public"],
     host_supported: true,
     stl: "none",
     compile_multilib: "both",
@@ -2052,6 +2172,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     host_supported: true,
     native_header_libs: ["mysdk_mynativeheaders@current"],
     target: {
@@ -2073,6 +2194,7 @@
 }
 
 func TestSystemSharedLibPropagation(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -2102,6 +2224,7 @@
 cc_prebuilt_library_shared {
     name: "mysdk_sslnil@current",
     sdk_member_name: "sslnil",
+    visibility: ["//visibility:public"],
     installable: false,
     compile_multilib: "both",
     arch: {
@@ -2117,6 +2240,7 @@
 cc_prebuilt_library_shared {
     name: "sslnil",
     prefer: false,
+    visibility: ["//visibility:public"],
     compile_multilib: "both",
     arch: {
         arm64: {
@@ -2131,6 +2255,7 @@
 cc_prebuilt_library_shared {
     name: "mysdk_sslempty@current",
     sdk_member_name: "sslempty",
+    visibility: ["//visibility:public"],
     installable: false,
     compile_multilib: "both",
     system_shared_libs: [],
@@ -2147,6 +2272,7 @@
 cc_prebuilt_library_shared {
     name: "sslempty",
     prefer: false,
+    visibility: ["//visibility:public"],
     compile_multilib: "both",
     system_shared_libs: [],
     arch: {
@@ -2162,6 +2288,7 @@
 cc_prebuilt_library_shared {
     name: "mysdk_sslnonempty@current",
     sdk_member_name: "sslnonempty",
+    visibility: ["//visibility:public"],
     installable: false,
     compile_multilib: "both",
     system_shared_libs: ["mysdk_sslnil@current"],
@@ -2178,6 +2305,7 @@
 cc_prebuilt_library_shared {
     name: "sslnonempty",
     prefer: false,
+    visibility: ["//visibility:public"],
     compile_multilib: "both",
     system_shared_libs: ["sslnil"],
     arch: {
@@ -2192,6 +2320,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     native_shared_libs: [
         "mysdk_sslnil@current",
         "mysdk_sslempty@current",
@@ -2225,6 +2354,7 @@
 cc_prebuilt_library_shared {
     name: "mysdk_sslvariants@current",
     sdk_member_name: "sslvariants",
+    visibility: ["//visibility:public"],
     host_supported: true,
     installable: false,
     compile_multilib: "both",
@@ -2256,6 +2386,7 @@
 cc_prebuilt_library_shared {
     name: "sslvariants",
     prefer: false,
+    visibility: ["//visibility:public"],
     host_supported: true,
     compile_multilib: "both",
     target: {
@@ -2285,6 +2416,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     host_supported: true,
     native_shared_libs: ["mysdk_sslvariants@current"],
     target: {
@@ -2300,6 +2432,7 @@
 }
 
 func TestStubsLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -2327,10 +2460,15 @@
 cc_prebuilt_library_shared {
     name: "mysdk_stubslib@current",
     sdk_member_name: "stubslib",
+    visibility: ["//visibility:public"],
     installable: false,
     compile_multilib: "both",
     stubs: {
-        versions: ["3"],
+        versions: [
+            "1",
+            "2",
+            "3",
+        ],
     },
     arch: {
         arm64: {
@@ -2345,9 +2483,14 @@
 cc_prebuilt_library_shared {
     name: "stubslib",
     prefer: false,
+    visibility: ["//visibility:public"],
     compile_multilib: "both",
     stubs: {
-        versions: ["3"],
+        versions: [
+            "1",
+            "2",
+            "3",
+        ],
     },
     arch: {
         arm64: {
@@ -2361,12 +2504,14 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     native_shared_libs: ["mysdk_stubslib@current"],
 }
 `))
 }
 
 func TestDeviceAndHostSnapshotWithStubsLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -2397,11 +2542,16 @@
 cc_prebuilt_library_shared {
     name: "mysdk_stubslib@current",
     sdk_member_name: "stubslib",
+    visibility: ["//visibility:public"],
     host_supported: true,
     installable: false,
     compile_multilib: "both",
     stubs: {
-        versions: ["3"],
+        versions: [
+            "1",
+            "2",
+            "3",
+        ],
     },
     target: {
         host: {
@@ -2428,10 +2578,15 @@
 cc_prebuilt_library_shared {
     name: "stubslib",
     prefer: false,
+    visibility: ["//visibility:public"],
     host_supported: true,
     compile_multilib: "both",
     stubs: {
-        versions: ["3"],
+        versions: [
+            "1",
+            "2",
+            "3",
+        ],
     },
     target: {
         host: {
@@ -2457,6 +2612,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     host_supported: true,
     native_shared_libs: ["mysdk_stubslib@current"],
     target: {
@@ -2472,6 +2628,7 @@
 }
 
 func TestUniqueHostSoname(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithCc(t, `
 		sdk {
 			name: "mysdk",
@@ -2493,6 +2650,7 @@
 cc_prebuilt_library_shared {
     name: "mysdk_mylib@current",
     sdk_member_name: "mylib",
+    visibility: ["//visibility:public"],
     host_supported: true,
     installable: false,
     unique_host_soname: true,
@@ -2522,6 +2680,7 @@
 cc_prebuilt_library_shared {
     name: "mylib",
     prefer: false,
+    visibility: ["//visibility:public"],
     host_supported: true,
     unique_host_soname: true,
     compile_multilib: "both",
@@ -2549,6 +2708,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     host_supported: true,
     native_shared_libs: ["mysdk_mylib@current"],
     target: {
diff --git a/sdk/exports_test.go b/sdk/exports_test.go
index 20e2521..173ccb9 100644
--- a/sdk/exports_test.go
+++ b/sdk/exports_test.go
@@ -20,6 +20,7 @@
 
 // Ensure that module_exports generates a module_exports_snapshot module.
 func TestModuleExportsSnapshot(t *testing.T) {
+	t.Parallel()
 	packageBp := `
 		module_exports {
 			name: "myexports",
@@ -49,17 +50,20 @@
 java_import {
     name: "myexports_myjavalib@current",
     sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
     jars: ["java/myjavalib.jar"],
 }
 
 java_import {
     name: "myjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     jars: ["java/myjavalib.jar"],
 }
 
 module_exports_snapshot {
     name: "myexports@current",
+    visibility: ["//visibility:public"],
     java_libs: ["myexports_myjavalib@current"],
 }
 `))
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index a7ee8d1..f86ab57 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -43,6 +43,7 @@
 		"api/system-server-current.txt":                     nil,
 		"api/system-server-removed.txt":                     nil,
 		"build/soong/scripts/gen-java-current-api-files.sh": nil,
+		"docs/known_doctags":                                nil,
 	}
 
 	// for java_sdk_library tests
@@ -91,6 +92,7 @@
 // Contains tests for SDK members provided by the java package.
 
 func TestSdkDependsOnSourceEvenWhenPrebuiltPreferred(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		sdk {
 			name: "mysdk",
@@ -120,23 +122,27 @@
 java_import {
     name: "mysdk_sdkmember@current",
     sdk_member_name: "sdkmember",
+    visibility: ["//visibility:public"],
     jars: ["java/sdkmember.jar"],
 }
 
 java_import {
     name: "sdkmember",
     prefer: false,
+    visibility: ["//visibility:public"],
     jars: ["java/sdkmember.jar"],
 }
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     java_header_libs: ["mysdk_sdkmember@current"],
 }
 `))
 }
 
 func TestBasicSdkWithJavaLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		sdk {
 			name: "mysdk",
@@ -216,6 +222,7 @@
 }
 
 func TestSnapshotWithJavaHeaderLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		sdk {
 			name: "mysdk",
@@ -242,17 +249,20 @@
 java_import {
     name: "mysdk_myjavalib@current",
     sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
     jars: ["java/myjavalib.jar"],
 }
 
 java_import {
     name: "myjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     jars: ["java/myjavalib.jar"],
 }
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     java_header_libs: ["mysdk_myjavalib@current"],
 }
 
@@ -265,6 +275,7 @@
 }
 
 func TestHostSnapshotWithJavaHeaderLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		sdk {
 			name: "mysdk",
@@ -294,6 +305,7 @@
 java_import {
     name: "mysdk_myjavalib@current",
     sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     jars: ["java/myjavalib.jar"],
@@ -302,6 +314,7 @@
 java_import {
     name: "myjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     jars: ["java/myjavalib.jar"],
@@ -309,6 +322,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     java_header_libs: ["mysdk_myjavalib@current"],
@@ -322,6 +336,7 @@
 }
 
 func TestDeviceAndHostSnapshotWithJavaHeaderLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		sdk {
 			name: "mysdk",
@@ -346,6 +361,7 @@
 java_import {
     name: "mysdk_myjavalib@current",
     sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
     host_supported: true,
     target: {
         android: {
@@ -360,6 +376,7 @@
 java_import {
     name: "myjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     host_supported: true,
     target: {
         android: {
@@ -373,6 +390,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     host_supported: true,
     java_header_libs: ["mysdk_myjavalib@current"],
 }
@@ -385,6 +403,7 @@
 }
 
 func TestSnapshotWithJavaImplLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		module_exports {
 			name: "myexports",
@@ -412,17 +431,20 @@
 java_import {
     name: "myexports_myjavalib@current",
     sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
     jars: ["java/myjavalib.jar"],
 }
 
 java_import {
     name: "myjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     jars: ["java/myjavalib.jar"],
 }
 
 module_exports_snapshot {
     name: "myexports@current",
+    visibility: ["//visibility:public"],
     java_libs: ["myexports_myjavalib@current"],
 }
 
@@ -435,6 +457,7 @@
 }
 
 func TestHostSnapshotWithJavaImplLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		module_exports {
 			name: "myexports",
@@ -464,6 +487,7 @@
 java_import {
     name: "myexports_myjavalib@current",
     sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     jars: ["java/myjavalib.jar"],
@@ -472,6 +496,7 @@
 java_import {
     name: "myjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     jars: ["java/myjavalib.jar"],
@@ -479,6 +504,7 @@
 
 module_exports_snapshot {
     name: "myexports@current",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     java_libs: ["myexports_myjavalib@current"],
@@ -492,6 +518,7 @@
 }
 
 func TestSnapshotWithJavaTest(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		module_exports {
 			name: "myexports",
@@ -515,6 +542,7 @@
 java_test_import {
     name: "myexports_myjavatests@current",
     sdk_member_name: "myjavatests",
+    visibility: ["//visibility:public"],
     jars: ["java/myjavatests.jar"],
     test_config: "java/myjavatests-AndroidTest.xml",
 }
@@ -522,12 +550,14 @@
 java_test_import {
     name: "myjavatests",
     prefer: false,
+    visibility: ["//visibility:public"],
     jars: ["java/myjavatests.jar"],
     test_config: "java/myjavatests-AndroidTest.xml",
 }
 
 module_exports_snapshot {
     name: "myexports@current",
+    visibility: ["//visibility:public"],
     java_tests: ["myexports_myjavatests@current"],
 }
 `),
@@ -539,6 +569,7 @@
 }
 
 func TestHostSnapshotWithJavaTest(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		module_exports {
 			name: "myexports",
@@ -565,6 +596,7 @@
 java_test_import {
     name: "myexports_myjavatests@current",
     sdk_member_name: "myjavatests",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     jars: ["java/myjavatests.jar"],
@@ -574,6 +606,7 @@
 java_test_import {
     name: "myjavatests",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     jars: ["java/myjavatests.jar"],
@@ -582,6 +615,7 @@
 
 module_exports_snapshot {
     name: "myexports@current",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     java_tests: ["myexports_myjavatests@current"],
@@ -608,6 +642,7 @@
 // directly or indirectly from an APEX as droidstubs can never be a part of an
 // apex.
 func TestBasicSdkWithDroidstubs(t *testing.T) {
+	t.Parallel()
 	testSdkWithDroidstubs(t, `
 		sdk {
 				name: "mysdk",
@@ -638,6 +673,7 @@
 }
 
 func TestSnapshotWithDroidstubs(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithDroidstubs(t, `
 		module_exports {
 			name: "myexports",
@@ -659,17 +695,20 @@
 prebuilt_stubs_sources {
     name: "myexports_myjavaapistubs@current",
     sdk_member_name: "myjavaapistubs",
+    visibility: ["//visibility:public"],
     srcs: ["java/myjavaapistubs_stubs_sources"],
 }
 
 prebuilt_stubs_sources {
     name: "myjavaapistubs",
     prefer: false,
+    visibility: ["//visibility:public"],
     srcs: ["java/myjavaapistubs_stubs_sources"],
 }
 
 module_exports_snapshot {
     name: "myexports@current",
+    visibility: ["//visibility:public"],
     stubs_sources: ["myexports_myjavaapistubs@current"],
 }
 
@@ -680,6 +719,7 @@
 }
 
 func TestHostSnapshotWithDroidstubs(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithDroidstubs(t, `
 		module_exports {
 			name: "myexports",
@@ -705,6 +745,7 @@
 prebuilt_stubs_sources {
     name: "myexports_myjavaapistubs@current",
     sdk_member_name: "myjavaapistubs",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     srcs: ["java/myjavaapistubs_stubs_sources"],
@@ -713,6 +754,7 @@
 prebuilt_stubs_sources {
     name: "myjavaapistubs",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     srcs: ["java/myjavaapistubs_stubs_sources"],
@@ -720,6 +762,7 @@
 
 module_exports_snapshot {
     name: "myexports@current",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     stubs_sources: ["myexports_myjavaapistubs@current"],
@@ -731,6 +774,7 @@
 }
 
 func TestSnapshotWithJavaSystemModules(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		sdk {
 			name: "mysdk",
@@ -765,12 +809,14 @@
 java_import {
     name: "mysdk_exported-system-module@current",
     sdk_member_name: "exported-system-module",
+    visibility: ["//visibility:public"],
     jars: ["java/exported-system-module.jar"],
 }
 
 java_import {
     name: "exported-system-module",
     prefer: false,
+    visibility: ["//visibility:public"],
     jars: ["java/exported-system-module.jar"],
 }
 
@@ -791,6 +837,7 @@
 java_system_modules_import {
     name: "mysdk_my-system-modules@current",
     sdk_member_name: "my-system-modules",
+    visibility: ["//visibility:public"],
     libs: [
         "mysdk_system-module@current",
         "mysdk_exported-system-module@current",
@@ -800,6 +847,7 @@
 java_system_modules_import {
     name: "my-system-modules",
     prefer: false,
+    visibility: ["//visibility:public"],
     libs: [
         "mysdk_system-module",
         "exported-system-module",
@@ -808,6 +856,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     java_header_libs: ["mysdk_exported-system-module@current"],
     java_system_modules: ["mysdk_my-system-modules@current"],
 }
@@ -820,6 +869,7 @@
 }
 
 func TestHostSnapshotWithJavaSystemModules(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		sdk {
 			name: "mysdk",
@@ -870,6 +920,7 @@
 java_system_modules_import {
     name: "mysdk_my-system-modules@current",
     sdk_member_name: "my-system-modules",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     libs: ["mysdk_system-module@current"],
@@ -878,6 +929,7 @@
 java_system_modules_import {
     name: "my-system-modules",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     libs: ["mysdk_system-module"],
@@ -885,6 +937,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     java_system_modules: ["mysdk_my-system-modules@current"],
@@ -895,6 +948,7 @@
 }
 
 func TestDeviceAndHostSnapshotWithOsSpecificMembers(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		module_exports {
 			name: "myexports",
@@ -938,6 +992,7 @@
 java_import {
     name: "myexports_hostjavalib@current",
     sdk_member_name: "hostjavalib",
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     jars: ["java/hostjavalib.jar"],
@@ -946,6 +1001,7 @@
 java_import {
     name: "hostjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     device_supported: false,
     host_supported: true,
     jars: ["java/hostjavalib.jar"],
@@ -954,18 +1010,21 @@
 java_import {
     name: "myexports_androidjavalib@current",
     sdk_member_name: "androidjavalib",
+    visibility: ["//visibility:public"],
     jars: ["java/androidjavalib.jar"],
 }
 
 java_import {
     name: "androidjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     jars: ["java/androidjavalib.jar"],
 }
 
 java_import {
     name: "myexports_myjavalib@current",
     sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
     host_supported: true,
     target: {
         android: {
@@ -980,6 +1039,7 @@
 java_import {
     name: "myjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     host_supported: true,
     target: {
         android: {
@@ -993,6 +1053,7 @@
 
 module_exports_snapshot {
     name: "myexports@current",
+    visibility: ["//visibility:public"],
     host_supported: true,
     java_libs: ["myexports_myjavalib@current"],
     target: {
@@ -1015,6 +1076,7 @@
 }
 
 func TestSnapshotWithJavaSdkLibrary(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		sdk {
 			name: "mysdk",
@@ -1039,6 +1101,7 @@
 java_sdk_library_import {
     name: "mysdk_myjavalib@current",
     sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
     apex_available: ["//apex_available:anyapex"],
     shared_library: false,
     public: {
@@ -1067,6 +1130,7 @@
 java_sdk_library_import {
     name: "myjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     apex_available: ["//apex_available:anyapex"],
     shared_library: false,
     public: {
@@ -1094,6 +1158,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     java_sdk_libs: ["mysdk_myjavalib@current"],
 }
 `),
@@ -1116,6 +1181,7 @@
 }
 
 func TestSnapshotWithJavaSdkLibrary_SdkVersion_None(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		sdk {
 			name: "mysdk",
@@ -1137,6 +1203,7 @@
 java_sdk_library_import {
     name: "mysdk_myjavalib@current",
     sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
     shared_library: true,
     public: {
         jars: ["sdk_library/public/myjavalib-stubs.jar"],
@@ -1150,6 +1217,7 @@
 java_sdk_library_import {
     name: "myjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     shared_library: true,
     public: {
         jars: ["sdk_library/public/myjavalib-stubs.jar"],
@@ -1162,6 +1230,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     java_sdk_libs: ["mysdk_myjavalib@current"],
 }
 `),
@@ -1177,6 +1246,7 @@
 }
 
 func TestSnapshotWithJavaSdkLibrary_SdkVersion_ForScope(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		sdk {
 			name: "mysdk",
@@ -1201,6 +1271,7 @@
 java_sdk_library_import {
     name: "mysdk_myjavalib@current",
     sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
     shared_library: true,
     public: {
         jars: ["sdk_library/public/myjavalib-stubs.jar"],
@@ -1214,6 +1285,7 @@
 java_sdk_library_import {
     name: "myjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     shared_library: true,
     public: {
         jars: ["sdk_library/public/myjavalib-stubs.jar"],
@@ -1226,6 +1298,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     java_sdk_libs: ["mysdk_myjavalib@current"],
 }
 `),
@@ -1241,6 +1314,7 @@
 }
 
 func TestSnapshotWithJavaSdkLibrary_ApiScopes(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		sdk {
 			name: "mysdk",
@@ -1268,6 +1342,7 @@
 java_sdk_library_import {
     name: "mysdk_myjavalib@current",
     sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
     apex_available: ["//apex_available:anyapex"],
     shared_library: true,
     public: {
@@ -1289,6 +1364,7 @@
 java_sdk_library_import {
     name: "myjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     apex_available: ["//apex_available:anyapex"],
     shared_library: true,
     public: {
@@ -1309,6 +1385,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     java_sdk_libs: ["mysdk_myjavalib@current"],
 }
 `),
@@ -1328,6 +1405,7 @@
 }
 
 func TestSnapshotWithJavaSdkLibrary_ModuleLib(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		sdk {
 			name: "mysdk",
@@ -1358,6 +1436,7 @@
 java_sdk_library_import {
     name: "mysdk_myjavalib@current",
     sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
     apex_available: ["//apex_available:anyapex"],
     shared_library: true,
     public: {
@@ -1386,6 +1465,7 @@
 java_sdk_library_import {
     name: "myjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     apex_available: ["//apex_available:anyapex"],
     shared_library: true,
     public: {
@@ -1413,6 +1493,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     java_sdk_libs: ["mysdk_myjavalib@current"],
 }
 `),
@@ -1436,6 +1517,7 @@
 }
 
 func TestSnapshotWithJavaSdkLibrary_SystemServer(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		sdk {
 			name: "mysdk",
@@ -1463,6 +1545,7 @@
 java_sdk_library_import {
     name: "mysdk_myjavalib@current",
     sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
     apex_available: ["//apex_available:anyapex"],
     shared_library: true,
     public: {
@@ -1484,6 +1567,7 @@
 java_sdk_library_import {
     name: "myjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     apex_available: ["//apex_available:anyapex"],
     shared_library: true,
     public: {
@@ -1504,6 +1588,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     java_sdk_libs: ["mysdk_myjavalib@current"],
 }
 `),
@@ -1523,6 +1608,7 @@
 }
 
 func TestSnapshotWithJavaSdkLibrary_NamingScheme(t *testing.T) {
+	t.Parallel()
 	result := testSdkWithJava(t, `
 		sdk {
 			name: "mysdk",
@@ -1548,6 +1634,7 @@
 java_sdk_library_import {
     name: "mysdk_myjavalib@current",
     sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
     apex_available: ["//apex_available:anyapex"],
     naming_scheme: "default",
     shared_library: true,
@@ -1563,6 +1650,7 @@
 java_sdk_library_import {
     name: "myjavalib",
     prefer: false,
+    visibility: ["//visibility:public"],
     apex_available: ["//apex_available:anyapex"],
     naming_scheme: "default",
     shared_library: true,
@@ -1577,6 +1665,7 @@
 
 sdk_snapshot {
     name: "mysdk@current",
+    visibility: ["//visibility:public"],
     java_sdk_libs: ["mysdk_myjavalib@current"],
 }
 `),
@@ -1590,3 +1679,75 @@
 		),
 	)
 }
+
+func TestSnapshotWithJavaSdkLibrary_DoctagFiles(t *testing.T) {
+	result := testSdkWithJava(t, `
+		sdk {
+			name: "mysdk",
+			java_sdk_libs: ["myjavalib"],
+		}
+
+		java_sdk_library {
+			name: "myjavalib",
+			srcs: ["Test.java"],
+			sdk_version: "current",
+			public: {
+				enabled: true,
+			},
+			doctag_files: ["docs/known_doctags"],
+		}
+
+		filegroup {
+			name: "mygroup",
+			srcs: [":myjavalib{.doctags}"],
+		}
+	`)
+
+	result.CheckSnapshot("mysdk", "",
+		checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_sdk_library_import {
+    name: "mysdk_myjavalib@current",
+    sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
+    shared_library: true,
+    doctag_files: ["doctags/docs/known_doctags"],
+    public: {
+        jars: ["sdk_library/public/myjavalib-stubs.jar"],
+        stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
+        current_api: "sdk_library/public/myjavalib.txt",
+        removed_api: "sdk_library/public/myjavalib-removed.txt",
+        sdk_version: "current",
+    },
+}
+
+java_sdk_library_import {
+    name: "myjavalib",
+    prefer: false,
+    visibility: ["//visibility:public"],
+    shared_library: true,
+    doctag_files: ["doctags/docs/known_doctags"],
+    public: {
+        jars: ["sdk_library/public/myjavalib-stubs.jar"],
+        stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
+        current_api: "sdk_library/public/myjavalib.txt",
+        removed_api: "sdk_library/public/myjavalib-removed.txt",
+        sdk_version: "current",
+    },
+}
+
+sdk_snapshot {
+    name: "mysdk@current",
+    visibility: ["//visibility:public"],
+    java_sdk_libs: ["mysdk_myjavalib@current"],
+}
+`),
+		checkAllCopyRules(`
+.intermediates/myjavalib.stubs/android_common/javac/myjavalib.stubs.jar -> sdk_library/public/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_removed.txt -> sdk_library/public/myjavalib-removed.txt
+docs/known_doctags -> doctags/docs/known_doctags
+`),
+	)
+}
diff --git a/sdk/sdk.go b/sdk/sdk.go
index 7591020..50b0886 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -75,6 +75,20 @@
 
 	// True if this is a module_exports (or module_exports_snapshot) module type.
 	Module_exports bool `blueprint:"mutated"`
+
+	// The additional visibility to add to the prebuilt modules to allow them to
+	// reference each other.
+	//
+	// This can only be used to widen the visibility of the members:
+	//
+	// * Specifying //visibility:public here will make all members visible and
+	//   essentially ignore their own visibility.
+	// * Specifying //visibility:private here is an error.
+	// * Specifying any other rule here will add it to the members visibility and
+	//   be output to the member prebuilt in the snapshot. Duplicates will be
+	//   dropped. Adding a rule to members that have //visibility:private will
+	//   cause the //visibility:private to be discarded.
+	Prebuilt_visibility []string
 }
 
 // Contains information about the sdk properties that list sdk members, e.g.
@@ -211,6 +225,9 @@
 	// properties for the member type specific list properties.
 	s.dynamicMemberTypeListProperties = s.dynamicSdkMemberTypes.createMemberListProperties()
 	s.AddProperties(&s.properties, s.dynamicMemberTypeListProperties)
+
+	// Make sure that the prebuilt visibility property is verified for errors.
+	android.AddVisibilityProperty(s, "prebuilt_visibility", &s.properties.Prebuilt_visibility)
 	android.InitCommonOSAndroidMultiTargetsArchModule(s, android.HostAndDeviceSupported, android.MultilibCommon)
 	android.InitDefaultableModule(s)
 	android.AddLoadHook(s, func(ctx android.LoadHookContext) {
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index ef62b79..a6afdc5 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -35,6 +35,7 @@
 }
 
 func TestDepNotInRequiredSdks(t *testing.T) {
+	t.Parallel()
 	testSdkError(t, `module "myjavalib".*depends on "otherlib".*that isn't part of the required SDKs:.*`, `
 		sdk {
 			name: "mysdk",
@@ -95,6 +96,7 @@
 // Ensure that prebuilt modules have the same effective visibility as the source
 // modules.
 func TestSnapshotVisibility(t *testing.T) {
+	t.Parallel()
 	packageBp := `
 		package {
 			default_visibility: ["//other/foo"],
@@ -108,6 +110,9 @@
 				// generated sdk_snapshot.
 				":__subpackages__",
 			],
+			prebuilt_visibility: [
+				"//prebuilts/mysdk",
+			],
 			java_header_libs: [
 				"myjavalib",
 				"mypublicjavalib",
@@ -176,6 +181,7 @@
     visibility: [
         "//other/foo",
         "//package",
+        "//prebuilts/mysdk",
     ],
     jars: ["java/myjavalib.jar"],
 }
@@ -186,6 +192,7 @@
     visibility: [
         "//other/foo",
         "//package",
+        "//prebuilts/mysdk",
     ],
     jars: ["java/myjavalib.jar"],
 }
@@ -210,6 +217,7 @@
     visibility: [
         "//other/bar",
         "//package",
+        "//prebuilts/mysdk",
     ],
     jars: ["java/mydefaultedjavalib.jar"],
 }
@@ -220,6 +228,7 @@
     visibility: [
         "//other/bar",
         "//package",
+        "//prebuilts/mysdk",
     ],
     jars: ["java/mydefaultedjavalib.jar"],
 }
@@ -227,14 +236,20 @@
 java_import {
     name: "mysdk_myprivatejavalib@current",
     sdk_member_name: "myprivatejavalib",
-    visibility: ["//package"],
+    visibility: [
+        "//package",
+        "//prebuilts/mysdk",
+    ],
     jars: ["java/myprivatejavalib.jar"],
 }
 
 java_import {
     name: "myprivatejavalib",
     prefer: false,
-    visibility: ["//package"],
+    visibility: [
+        "//package",
+        "//prebuilts/mysdk",
+    ],
     jars: ["java/myprivatejavalib.jar"],
 }
 
@@ -254,7 +269,42 @@
 `))
 }
 
+func TestPrebuiltVisibilityProperty_IsValidated(t *testing.T) {
+	testSdkError(t, `prebuilt_visibility: cannot mix "//visibility:private" with any other visibility rules`, `
+		sdk {
+			name: "mysdk",
+			prebuilt_visibility: [
+				"//foo",
+				"//visibility:private",
+			],
+		}
+`)
+}
+
+func TestPrebuiltVisibilityProperty_AddPrivate(t *testing.T) {
+	testSdkError(t, `prebuilt_visibility: "//visibility:private" does not widen the visibility`, `
+		sdk {
+			name: "mysdk",
+			prebuilt_visibility: [
+				"//visibility:private",
+			],
+			java_header_libs: [
+				"myjavalib",
+			],
+		}
+
+		java_library {
+			name: "myjavalib",
+			// Uses package default visibility
+			srcs: ["Test.java"],
+			system_modules: "none",
+			sdk_version: "none",
+		}
+`)
+}
+
 func TestSDkInstall(t *testing.T) {
+	t.Parallel()
 	sdk := `
 		sdk {
 			name: "mysdk",
@@ -299,6 +349,7 @@
 var _ propertiesContainer = (*testPropertiesStruct)(nil)
 
 func TestCommonValueOptimization(t *testing.T) {
+	t.Parallel()
 	common := &testPropertiesStruct{name: "common"}
 	structs := []propertiesContainer{
 		&testPropertiesStruct{
@@ -396,6 +447,7 @@
 }
 
 func TestCommonValueOptimization_InvalidArchSpecificVariants(t *testing.T) {
+	t.Parallel()
 	common := &testPropertiesStruct{name: "common"}
 	structs := []propertiesContainer{
 		&testPropertiesStruct{
diff --git a/sdk/testing.go b/sdk/testing.go
index ae1e448..0b280ef 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -94,6 +94,7 @@
 
 	// from android package
 	android.RegisterPackageBuildComponents(ctx)
+	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
 	ctx.PreArchMutators(android.RegisterVisibilityRuleChecker)
 	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
 	ctx.PreArchMutators(android.RegisterComponentsMutator)
diff --git a/sdk/update.go b/sdk/update.go
index 3c4309c..f29b5a0 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -300,7 +300,7 @@
 	snapshotModule.AddProperty("name", snapshotName)
 
 	// Make sure that the snapshot has the same visibility as the sdk.
-	visibility := android.EffectiveVisibilityRules(ctx, s)
+	visibility := android.EffectiveVisibilityRules(ctx, s).Strings()
 	if len(visibility) != 0 {
 		snapshotModule.AddProperty("visibility", visibility)
 	}
@@ -719,7 +719,15 @@
 	} else {
 		// Extract visibility information from a member variant. All variants have the same
 		// visibility so it doesn't matter which one is used.
-		visibility := android.EffectiveVisibilityRules(s.ctx, variant)
+		visibilityRules := android.EffectiveVisibilityRules(s.ctx, variant)
+
+		// Add any additional visibility rules needed for the prebuilts to reference each other.
+		err := visibilityRules.Widen(s.sdk.properties.Prebuilt_visibility)
+		if err != nil {
+			s.ctx.PropertyErrorf("prebuilt_visibility", "%s", err)
+		}
+
+		visibility := visibilityRules.Strings()
 		if len(visibility) != 0 {
 			m.AddProperty("visibility", visibility)
 		}
@@ -1346,7 +1354,8 @@
 
 // A property that can be optimized by the commonValueExtractor.
 type extractorProperty struct {
-	// The name of the field for this property.
+	// The name of the field for this property. It is a "."-separated path for
+	// fields in non-anonymous substructs.
 	name string
 
 	// Filter that can use metadata associated with the properties being optimized
@@ -1383,18 +1392,18 @@
 func newCommonValueExtractor(propertiesStruct interface{}) *commonValueExtractor {
 	structType := getStructValue(reflect.ValueOf(propertiesStruct)).Type()
 	extractor := &commonValueExtractor{}
-	extractor.gatherFields(structType, nil)
+	extractor.gatherFields(structType, nil, "")
 	return extractor
 }
 
 // Gather the fields from the supplied structure type from which common values will
 // be extracted.
 //
-// This is recursive function. If it encounters an embedded field (no field name)
-// that is a struct then it will recurse into that struct passing in the accessor
-// for the field. That will then be used in the accessors for the fields in the
-// embedded struct.
-func (e *commonValueExtractor) gatherFields(structType reflect.Type, containingStructAccessor fieldAccessorFunc) {
+// This is recursive function. If it encounters a struct then it will recurse
+// into it, passing in the accessor for the field and the struct name as prefix
+// for the nested fields. That will then be used in the accessors for the fields
+// in the embedded struct.
+func (e *commonValueExtractor) gatherFields(structType reflect.Type, containingStructAccessor fieldAccessorFunc, namePrefix string) {
 	for f := 0; f < structType.NumField(); f++ {
 		field := structType.Field(f)
 		if field.PkgPath != "" {
@@ -1424,7 +1433,7 @@
 		// Save a copy of the field index for use in the function.
 		fieldIndex := f
 
-		name := field.Name
+		name := namePrefix + field.Name
 
 		fieldGetter := func(value reflect.Value) reflect.Value {
 			if containingStructAccessor != nil {
@@ -1446,9 +1455,15 @@
 			return value.Field(fieldIndex)
 		}
 
-		if field.Type.Kind() == reflect.Struct && field.Anonymous {
-			// Gather fields from the embedded structure.
-			e.gatherFields(field.Type, fieldGetter)
+		if field.Type.Kind() == reflect.Struct {
+			// Gather fields from the nested or embedded structure.
+			var subNamePrefix string
+			if field.Anonymous {
+				subNamePrefix = namePrefix
+			} else {
+				subNamePrefix = name + "."
+			}
+			e.gatherFields(field.Type, fieldGetter, subNamePrefix)
 		} else {
 			property := extractorProperty{
 				name,
@@ -1512,7 +1527,8 @@
 // Iterates over each exported field (capitalized name) and checks to see whether they
 // have the same value (using DeepEquals) across all the input properties. If it does not then no
 // change is made. Otherwise, the common value is stored in the field in the commonProperties
-// and the field in each of the input properties structure is set to its default value.
+// and the field in each of the input properties structure is set to its default value. Nested
+// structs are visited recursively and their non-struct fields are compared.
 func (e *commonValueExtractor) extractCommonProperties(commonProperties interface{}, inputPropertiesSlice interface{}) error {
 	commonPropertiesValue := reflect.ValueOf(commonProperties)
 	commonStructValue := commonPropertiesValue.Elem()
diff --git a/sh/sh_binary_test.go b/sh/sh_binary_test.go
index 0aa607b..e9086be 100644
--- a/sh/sh_binary_test.go
+++ b/sh/sh_binary_test.go
@@ -61,6 +61,7 @@
 }
 
 func TestShTestSubDir(t *testing.T) {
+	t.Parallel()
 	ctx, config := testShBinary(t, `
 		sh_test {
 			name: "foo",
@@ -81,6 +82,7 @@
 }
 
 func TestShTest(t *testing.T) {
+	t.Parallel()
 	ctx, config := testShBinary(t, `
 		sh_test {
 			name: "foo",
@@ -111,6 +113,7 @@
 }
 
 func TestShTest_dataModules(t *testing.T) {
+	t.Parallel()
 	ctx, config := testShBinary(t, `
 		sh_test {
 			name: "foo",
@@ -170,6 +173,7 @@
 }
 
 func TestShTestHost(t *testing.T) {
+	t.Parallel()
 	ctx, _ := testShBinary(t, `
 		sh_test_host {
 			name: "foo",
@@ -190,6 +194,7 @@
 }
 
 func TestShTestHost_dataDeviceModules(t *testing.T) {
+	t.Parallel()
 	ctx, config := testShBinary(t, `
 		sh_test_host {
 			name: "foo",
diff --git a/symbol_inject/elf_test.go b/symbol_inject/elf_test.go
index aceee44..316c69a 100644
--- a/symbol_inject/elf_test.go
+++ b/symbol_inject/elf_test.go
@@ -20,6 +20,7 @@
 )
 
 func TestElfSymbolTable(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		file         *mockElfFile
 		symbol       string
diff --git a/symbol_inject/macho_test.go b/symbol_inject/macho_test.go
index 50df131..d5b962d 100644
--- a/symbol_inject/macho_test.go
+++ b/symbol_inject/macho_test.go
@@ -21,6 +21,7 @@
 )
 
 func TestMachoSymbolTable(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		file         *macho.File
 		symbol       string
diff --git a/symbol_inject/pe_test.go b/symbol_inject/pe_test.go
index df7bac3..16b2009 100644
--- a/symbol_inject/pe_test.go
+++ b/symbol_inject/pe_test.go
@@ -21,6 +21,7 @@
 )
 
 func TestPESymbolTable(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		file         *pe.File
 		symbol       string
diff --git a/symbol_inject/symbol_inject_test.go b/symbol_inject/symbol_inject_test.go
index 6607e65..ab874b9 100644
--- a/symbol_inject/symbol_inject_test.go
+++ b/symbol_inject/symbol_inject_test.go
@@ -21,6 +21,7 @@
 )
 
 func TestCopyAndInject(t *testing.T) {
+	t.Parallel()
 	s := "abcdefghijklmnopqrstuvwxyz"
 	testCases := []struct {
 		offset   uint64
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index 711129c..7df0f3d 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -158,6 +158,7 @@
 }
 
 func TestSyspropLibrary(t *testing.T) {
+	t.Parallel()
 	ctx := test(t, `
 		sysprop_library {
 			name: "sysprop-platform",
diff --git a/ui/build/cleanbuild_test.go b/ui/build/cleanbuild_test.go
index 89f4ad9..be60362 100644
--- a/ui/build/cleanbuild_test.go
+++ b/ui/build/cleanbuild_test.go
@@ -27,6 +27,7 @@
 )
 
 func TestCleanOldFiles(t *testing.T) {
+	t.Parallel()
 	dir, err := ioutil.TempDir("", "testcleanoldfiles")
 	if err != nil {
 		t.Fatal(err)
diff --git a/ui/build/config_test.go b/ui/build/config_test.go
index 7b14c47..35c6ed4 100644
--- a/ui/build/config_test.go
+++ b/ui/build/config_test.go
@@ -39,6 +39,7 @@
 }
 
 func TestConfigParseArgsJK(t *testing.T) {
+	t.Parallel()
 	ctx := testContext()
 
 	testCases := []struct {
@@ -111,6 +112,7 @@
 }
 
 func TestConfigParseArgsVars(t *testing.T) {
+	t.Parallel()
 	ctx := testContext()
 
 	testCases := []struct {
@@ -638,6 +640,7 @@
 }
 
 func TestConfigSplitArgs(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		// ********* Setup *********
 		// Test description.
diff --git a/ui/build/environment_test.go b/ui/build/environment_test.go
index 37f500f..d8f83f4 100644
--- a/ui/build/environment_test.go
+++ b/ui/build/environment_test.go
@@ -21,6 +21,7 @@
 )
 
 func TestEnvUnset(t *testing.T) {
+	t.Parallel()
 	initial := &Environment{"TEST=1", "TEST2=0"}
 	initial.Unset("TEST")
 	got := initial.Environ()
@@ -30,6 +31,7 @@
 }
 
 func TestEnvUnsetMissing(t *testing.T) {
+	t.Parallel()
 	initial := &Environment{"TEST2=0"}
 	initial.Unset("TEST")
 	got := initial.Environ()
@@ -39,6 +41,7 @@
 }
 
 func TestEnvSet(t *testing.T) {
+	t.Parallel()
 	initial := &Environment{}
 	initial.Set("TEST", "0")
 	got := initial.Environ()
@@ -48,6 +51,7 @@
 }
 
 func TestEnvSetDup(t *testing.T) {
+	t.Parallel()
 	initial := &Environment{"TEST=1"}
 	initial.Set("TEST", "0")
 	got := initial.Environ()
@@ -57,6 +61,7 @@
 }
 
 func TestEnvAllow(t *testing.T) {
+	t.Parallel()
 	initial := &Environment{"TEST=1", "TEST2=0", "TEST3=2"}
 	initial.Allow("TEST3", "TEST")
 	got := initial.Environ()
@@ -73,6 +78,7 @@
 `
 
 func TestEnvAppendFromKati(t *testing.T) {
+	t.Parallel()
 	initial := &Environment{"CLANG=/usr/bin/clang", "TEST=0"}
 	err := initial.appendFromKati(strings.NewReader(testKatiEnvFileContents))
 	if err != nil {
diff --git a/ui/build/paths/logs_test.go b/ui/build/paths/logs_test.go
index 3b1005f..d5921a8 100644
--- a/ui/build/paths/logs_test.go
+++ b/ui/build/paths/logs_test.go
@@ -26,6 +26,7 @@
 )
 
 func TestSendLog(t *testing.T) {
+	t.Parallel()
 	t.Run("Short name", func(t *testing.T) {
 		d, err := ioutil.TempDir("", "s")
 		if err != nil {
@@ -105,6 +106,7 @@
 }
 
 func TestSendLogError(t *testing.T) {
+	t.Parallel()
 	d, err := ioutil.TempDir("", "log_socket")
 	if err != nil {
 		t.Fatal(err)
diff --git a/ui/build/proc_sync_test.go b/ui/build/proc_sync_test.go
index 857bea3..1b52fce 100644
--- a/ui/build/proc_sync_test.go
+++ b/ui/build/proc_sync_test.go
@@ -108,6 +108,7 @@
 
 // simple test
 func TestGetLock(t *testing.T) {
+	t.Parallel()
 	lockfile := lockOrFail(t)
 	defer removeTestLock(lockfile)
 }
@@ -119,6 +120,7 @@
 var busyStatus = 2
 
 func TestTrylock(t *testing.T) {
+	t.Parallel()
 	lockpath := os.Getenv(lockPathVariable)
 	if len(lockpath) < 1 {
 		checkTrylockMainProcess(t)
@@ -204,6 +206,7 @@
 }
 
 func TestLockFirstTrySucceeds(t *testing.T) {
+	t.Parallel()
 	noopLogger := logger.New(ioutil.Discard)
 	lock := testLockCountingTo(0)
 	waiter := newCountWaiter(0)
@@ -216,6 +219,7 @@
 	}
 }
 func TestLockThirdTrySucceeds(t *testing.T) {
+	t.Parallel()
 	noopLogger := logger.New(ioutil.Discard)
 	lock := testLockCountingTo(2)
 	waiter := newCountWaiter(2)
@@ -228,6 +232,7 @@
 	}
 }
 func TestLockTimedOut(t *testing.T) {
+	t.Parallel()
 	noopLogger := logger.New(ioutil.Discard)
 	lock := testLockCountingTo(3)
 	waiter := newCountWaiter(2)
diff --git a/ui/build/rbe_test.go b/ui/build/rbe_test.go
index 8ff96bc..fa371bb 100644
--- a/ui/build/rbe_test.go
+++ b/ui/build/rbe_test.go
@@ -26,6 +26,7 @@
 )
 
 func TestDumpRBEMetrics(t *testing.T) {
+	t.Parallel()
 	ctx := testContext()
 	tests := []struct {
 		description string
@@ -81,6 +82,7 @@
 }
 
 func TestDumpRBEMetricsErrors(t *testing.T) {
+	t.Parallel()
 	ctx := testContext()
 	tests := []struct {
 		description      string
diff --git a/ui/build/util_test.go b/ui/build/util_test.go
index b22e997..a06c3e9 100644
--- a/ui/build/util_test.go
+++ b/ui/build/util_test.go
@@ -25,6 +25,7 @@
 )
 
 func TestEnsureEmptyDirs(t *testing.T) {
+	t.Parallel()
 	ctx := testContext()
 	defer logger.Recover(func(err error) {
 		t.Error(err)
@@ -52,6 +53,7 @@
 }
 
 func TestCopyFile(t *testing.T) {
+	t.Parallel()
 	tmpDir, err := ioutil.TempDir("", "test_copy_file")
 	if err != nil {
 		t.Fatalf("failed to create temporary directory to hold test text files: %v", err)
@@ -86,6 +88,7 @@
 }
 
 func TestCopyFileErrors(t *testing.T) {
+	t.Parallel()
 	tmpDir, err := ioutil.TempDir("", "test_copy_file_errors")
 	if err != nil {
 		t.Fatalf("failed to create temporary directory to hold test text files: %v", err)
diff --git a/ui/logger/logger_test.go b/ui/logger/logger_test.go
index 044e6f0..7b3791c 100644
--- a/ui/logger/logger_test.go
+++ b/ui/logger/logger_test.go
@@ -29,6 +29,7 @@
 )
 
 func TestCreateFileWithRotation(t *testing.T) {
+	t.Parallel()
 	dir, err := ioutil.TempDir("", "test-rotation")
 	if err != nil {
 		t.Fatalf("Failed to get TempDir: %v", err)
@@ -96,6 +97,7 @@
 }
 
 func TestPanic(t *testing.T) {
+	t.Parallel()
 	if os.Getenv("ACTUALLY_PANIC") == "1" {
 		panicValue := "foo"
 		log := New(&bytes.Buffer{})
@@ -128,6 +130,7 @@
 }
 
 func TestFatal(t *testing.T) {
+	t.Parallel()
 	if os.Getenv("ACTUALLY_FATAL") == "1" {
 		log := New(&bytes.Buffer{})
 		defer func() {
@@ -150,6 +153,7 @@
 }
 
 func TestNonFatal(t *testing.T) {
+	t.Parallel()
 	if os.Getenv("ACTUAL_TEST") == "1" {
 		log := New(&bytes.Buffer{})
 		defer log.Cleanup()
@@ -166,6 +170,7 @@
 }
 
 func TestRecoverFatal(t *testing.T) {
+	t.Parallel()
 	log := New(&bytes.Buffer{})
 	defer func() {
 		if p := recover(); p != nil {
@@ -182,6 +187,7 @@
 }
 
 func TestRecoverNonFatal(t *testing.T) {
+	t.Parallel()
 	log := New(&bytes.Buffer{})
 	defer func() {
 		if p := recover(); p == nil {
@@ -198,6 +204,7 @@
 }
 
 func TestRuntimePanic(t *testing.T) {
+	t.Parallel()
 	defer func() {
 		if p := recover(); p == nil {
 			t.Errorf("Panic not thrown")
diff --git a/ui/metrics/time_test.go b/ui/metrics/time_test.go
index d73080a..16d6a20 100644
--- a/ui/metrics/time_test.go
+++ b/ui/metrics/time_test.go
@@ -22,6 +22,7 @@
 )
 
 func TestEnd(t *testing.T) {
+	t.Parallel()
 	startTime := time.Date(2020, time.July, 13, 13, 0, 0, 0, time.UTC)
 	dur := time.Nanosecond * 10
 	initialNow := _now
diff --git a/ui/status/critical_path_test.go b/ui/status/critical_path_test.go
index 965e0ad..e44298b 100644
--- a/ui/status/critical_path_test.go
+++ b/ui/status/critical_path_test.go
@@ -51,6 +51,7 @@
 }
 
 func TestCriticalPath(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name     string
 		msgs     func(*testCriticalPath)
diff --git a/ui/status/kati_test.go b/ui/status/kati_test.go
index f2cb813..24a38b3 100644
--- a/ui/status/kati_test.go
+++ b/ui/status/kati_test.go
@@ -43,6 +43,7 @@
 func (l *lastOutput) Flush() {}
 
 func TestKatiNormalCase(t *testing.T) {
+	t.Parallel()
 	status := &Status{}
 	output := &lastOutput{}
 	status.AddOutput(output)
@@ -110,6 +111,7 @@
 }
 
 func TestKatiExtraIncludes(t *testing.T) {
+	t.Parallel()
 	status := &Status{}
 	output := &lastOutput{}
 	status.AddOutput(output)
@@ -156,6 +158,7 @@
 }
 
 func TestKatiFailOnError(t *testing.T) {
+	t.Parallel()
 	status := &Status{}
 	output := &lastOutput{}
 	status.AddOutput(output)
diff --git a/ui/status/ninja_test.go b/ui/status/ninja_test.go
index c400c97..232be55 100644
--- a/ui/status/ninja_test.go
+++ b/ui/status/ninja_test.go
@@ -26,6 +26,7 @@
 
 // Tests that closing the ninja reader when nothing has opened the other end of the fifo is fast.
 func TestNinjaReader_Close(t *testing.T) {
+	t.Parallel()
 	tempDir, err := ioutil.TempDir("", "ninja_test")
 	if err != nil {
 		t.Fatal(err)
diff --git a/ui/status/status_test.go b/ui/status/status_test.go
index 9494582..2a90c7b 100644
--- a/ui/status/status_test.go
+++ b/ui/status/status_test.go
@@ -53,6 +53,7 @@
 }
 
 func TestBasicUse(t *testing.T) {
+	t.Parallel()
 	status := &Status{}
 	counts := &counterOutput{}
 	status.AddOutput(counts)
@@ -101,6 +102,7 @@
 
 // For when a tool claims to have 2 actions, but finishes after one.
 func TestFinishEarly(t *testing.T) {
+	t.Parallel()
 	status := &Status{}
 	counts := &counterOutput{}
 	status.AddOutput(counts)
@@ -129,6 +131,7 @@
 
 // For when a tool claims to have 1 action, but starts two.
 func TestExtraActions(t *testing.T) {
+	t.Parallel()
 	status := &Status{}
 	counts := &counterOutput{}
 	status.AddOutput(counts)
@@ -149,6 +152,7 @@
 
 // When a tool calls Finish() with a running Action
 func TestRunningWhenFinished(t *testing.T) {
+	t.Parallel()
 	status := &Status{}
 	counts := &counterOutput{}
 	status.AddOutput(counts)
diff --git a/ui/terminal/status_test.go b/ui/terminal/status_test.go
index aa69dff..da10912 100644
--- a/ui/terminal/status_test.go
+++ b/ui/terminal/status_test.go
@@ -25,6 +25,7 @@
 )
 
 func TestStatusOutput(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name   string
 		calls  func(stat status.StatusOutput)
@@ -266,6 +267,7 @@
 }
 
 func TestSmartStatusOutputWidthChange(t *testing.T) {
+	t.Parallel()
 	os.Setenv(tableHeightEnVar, "")
 
 	smart := &fakeSmartTerminal{termWidth: 40}
diff --git a/ui/terminal/util_test.go b/ui/terminal/util_test.go
index 82bde7c..b01b133 100644
--- a/ui/terminal/util_test.go
+++ b/ui/terminal/util_test.go
@@ -19,6 +19,7 @@
 )
 
 func TestStripAnsiEscapes(t *testing.T) {
+	t.Parallel()
 	testcases := []struct {
 		input  string
 		output string
diff --git a/xml/xml_test.go b/xml/xml_test.go
index abcb108..d9a6cee 100644
--- a/xml/xml_test.go
+++ b/xml/xml_test.go
@@ -78,6 +78,7 @@
 
 // Minimal test
 func TestPrebuiltEtcXml(t *testing.T) {
+	t.Parallel()
 	ctx := testXml(t, `
 		prebuilt_etc_xml {
 			name: "foo.xml",
diff --git a/zip/zip_test.go b/zip/zip_test.go
index 302a749..9e1ef90 100644
--- a/zip/zip_test.go
+++ b/zip/zip_test.go
@@ -102,6 +102,7 @@
 }
 
 func TestZip(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name               string
 		args               *FileArgsBuilder
@@ -530,6 +531,7 @@
 }
 
 func TestReadRespFile(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name, in string
 		out      []string
@@ -602,6 +604,7 @@
 }
 
 func TestSrcJar(t *testing.T) {
+	t.Parallel()
 	mockFs := pathtools.MockFs(map[string][]byte{
 		"wrong_package.java":       []byte("package foo;"),
 		"foo/correct_package.java": []byte("package foo;"),