Merge "Find LLNDK dumps in prebuilts/abi-dumps/vndk" into main
diff --git a/aconfig/codegen/cc_aconfig_library_test.go b/aconfig/codegen/cc_aconfig_library_test.go
index ef92cc8..05449bc 100644
--- a/aconfig/codegen/cc_aconfig_library_test.go
+++ b/aconfig/codegen/cc_aconfig_library_test.go
@@ -163,7 +163,6 @@
 	entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0]
 
 	makeVar := entry.EntryMap["LOCAL_ACONFIG_FILES"]
-	android.AssertIntEquals(t, "len(LOCAL_ACONFIG_FILES)", 1, len(makeVar))
 	android.EnsureListContainsSuffix(t, makeVar, "my_aconfig_declarations_foo/intermediate.pb")
 }
 
diff --git a/aconfig/codegen/java_aconfig_library_test.go b/aconfig/codegen/java_aconfig_library_test.go
index 7361d44..85d2675 100644
--- a/aconfig/codegen/java_aconfig_library_test.go
+++ b/aconfig/codegen/java_aconfig_library_test.go
@@ -60,7 +60,6 @@
 	entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0]
 
 	makeVar := entry.EntryMap["LOCAL_ACONFIG_FILES"]
-	android.AssertIntEquals(t, "len(LOCAL_ACONFIG_FILES)", 1, len(makeVar))
 	android.EnsureListContainsSuffix(t, makeVar, "android_common/aconfig_merged.pb")
 }
 
diff --git a/android/Android.bp b/android/Android.bp
index ad07fda..e73f355 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -37,6 +37,7 @@
         "api_levels.go",
         "arch.go",
         "arch_list.go",
+        "arch_module_context.go",
         "base_module_context.go",
         "buildinfo_prop.go",
         "config.go",
diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go
index 68fff58..be9beb1 100644
--- a/android/aconfig_providers.go
+++ b/android/aconfig_providers.go
@@ -15,6 +15,10 @@
 package android
 
 import (
+	"fmt"
+	"io"
+	"reflect"
+
 	"github.com/google/blueprint"
 )
 
@@ -45,6 +49,8 @@
 
 var AconfigTransitiveDeclarationsInfoProvider = blueprint.NewProvider[AconfigTransitiveDeclarationsInfo]()
 
+// CollectDependencyAconfigFiles is used by some module types to provide finer dependency graphing than
+// we can do in ModuleBase.
 func CollectDependencyAconfigFiles(ctx ModuleContext, mergedAconfigFiles *map[string]Paths) {
 	if *mergedAconfigFiles == nil {
 		*mergedAconfigFiles = make(map[string]Paths)
@@ -54,7 +60,14 @@
 			(*mergedAconfigFiles)[dep.Container] = append((*mergedAconfigFiles)[dep.Container], dep.IntermediateCacheOutputPath)
 			return
 		}
-		if dep, _ := OtherModuleProvider(ctx, module, AconfigTransitiveDeclarationsInfoProvider); len(dep.AconfigFiles) > 0 {
+		if dep, ok := OtherModuleProvider(ctx, module, aconfigPropagatingProviderKey); ok {
+			for container, v := range dep.AconfigFiles {
+				(*mergedAconfigFiles)[container] = append((*mergedAconfigFiles)[container], v...)
+			}
+		}
+		// We process these last, so that they determine the final value, eliminating any duplicates that we picked up
+		// from UpdateAndroidBuildActions.
+		if dep, ok := OtherModuleProvider(ctx, module, AconfigTransitiveDeclarationsInfoProvider); ok {
 			for container, v := range dep.AconfigFiles {
 				(*mergedAconfigFiles)[container] = append((*mergedAconfigFiles)[container], v...)
 			}
@@ -62,7 +75,7 @@
 	})
 
 	for container, aconfigFiles := range *mergedAconfigFiles {
-		(*mergedAconfigFiles)[container] = mergeAconfigFiles(ctx, container, aconfigFiles)
+		(*mergedAconfigFiles)[container] = mergeAconfigFiles(ctx, container, aconfigFiles, false)
 	}
 
 	SetProvider(ctx, AconfigTransitiveDeclarationsInfoProvider, AconfigTransitiveDeclarationsInfo{
@@ -70,7 +83,94 @@
 	})
 }
 
-func mergeAconfigFiles(ctx ModuleContext, container string, inputs Paths) Paths {
+func SetAconfigFileMkEntries(m *ModuleBase, entries *AndroidMkEntries, aconfigFiles map[string]Paths) {
+	setAconfigFileMkEntries(m, entries, aconfigFiles)
+}
+
+type aconfigPropagatingDeclarationsInfo struct {
+	AconfigFiles map[string]Paths
+}
+
+var aconfigPropagatingProviderKey = blueprint.NewProvider[aconfigPropagatingDeclarationsInfo]()
+
+func aconfigUpdateAndroidBuildActions(ctx ModuleContext) {
+	mergedAconfigFiles := make(map[string]Paths)
+	ctx.VisitDirectDepsIgnoreBlueprint(func(module Module) {
+		// If any of our dependencies have aconfig declarations (directly or propagated), then merge those and provide them.
+		if dep, ok := OtherModuleProvider(ctx, module, AconfigDeclarationsProviderKey); ok {
+			mergedAconfigFiles[dep.Container] = append(mergedAconfigFiles[dep.Container], dep.IntermediateCacheOutputPath)
+		}
+		if dep, ok := OtherModuleProvider(ctx, module, aconfigPropagatingProviderKey); ok {
+			for container, v := range dep.AconfigFiles {
+				mergedAconfigFiles[container] = append(mergedAconfigFiles[container], v...)
+			}
+		}
+		if dep, ok := OtherModuleProvider(ctx, module, AconfigTransitiveDeclarationsInfoProvider); ok {
+			for container, v := range dep.AconfigFiles {
+				mergedAconfigFiles[container] = append(mergedAconfigFiles[container], v...)
+			}
+		}
+	})
+	// We only need to set the provider if we have aconfig files.
+	if len(mergedAconfigFiles) > 0 {
+		for container, aconfigFiles := range mergedAconfigFiles {
+			mergedAconfigFiles[container] = mergeAconfigFiles(ctx, container, aconfigFiles, true)
+		}
+
+		SetProvider(ctx, aconfigPropagatingProviderKey, aconfigPropagatingDeclarationsInfo{
+			AconfigFiles: mergedAconfigFiles,
+		})
+	}
+}
+
+func aconfigUpdateAndroidMkData(ctx fillInEntriesContext, mod Module, data *AndroidMkData) {
+	info, ok := SingletonModuleProvider(ctx, mod, aconfigPropagatingProviderKey)
+	// If there is no aconfigPropagatingProvider, or there are no AconfigFiles, then we are done.
+	if !ok || len(info.AconfigFiles) == 0 {
+		return
+	}
+	data.Extra = append(data.Extra, func(w io.Writer, outputFile Path) {
+		AndroidMkEmitAssignList(w, "LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles).Strings())
+	})
+	// If there is a Custom writer, it needs to support this provider.
+	if data.Custom != nil {
+		switch reflect.TypeOf(mod).String() {
+		case "*aidl.aidlApi": // writes non-custom before adding .phony
+		case "*android_sdk.sdkRepoHost": // doesn't go through base_rules
+		case "*apex.apexBundle": // aconfig_file properties written
+		case "*bpf.bpf": // properties written (both for module and objs)
+		case "*genrule.Module": // writes non-custom before adding .phony
+		case "*java.SystemModules": // doesn't go through base_rules
+		case "*phony.phony": // properties written
+		case "*phony.PhonyRule": // writes phony deps and acts like `.PHONY`
+		case "*sysprop.syspropLibrary": // properties written
+		default:
+			panic(fmt.Errorf("custom make rules do not handle aconfig files for %q (%q) module %q", ctx.ModuleType(mod), reflect.TypeOf(mod), mod))
+		}
+	}
+}
+
+func aconfigUpdateAndroidMkEntries(ctx fillInEntriesContext, mod Module, entries *[]AndroidMkEntries) {
+	// If there are no entries, then we can ignore this module, even if it has aconfig files.
+	if len(*entries) == 0 {
+		return
+	}
+	info, ok := SingletonModuleProvider(ctx, mod, aconfigPropagatingProviderKey)
+	if !ok || len(info.AconfigFiles) == 0 {
+		return
+	}
+	// All of the files in the module potentially depend on the aconfig flag values.
+	for idx, _ := range *entries {
+		(*entries)[idx].ExtraEntries = append((*entries)[idx].ExtraEntries,
+			func(ctx AndroidMkExtraEntriesContext, entries *AndroidMkEntries) {
+				setAconfigFileMkEntries(mod.base(), entries, info.AconfigFiles)
+			},
+		)
+
+	}
+}
+
+func mergeAconfigFiles(ctx ModuleContext, container string, inputs Paths, generateRule bool) Paths {
 	inputs = LastUniquePaths(inputs)
 	if len(inputs) == 1 {
 		return Paths{inputs[0]}
@@ -78,22 +178,28 @@
 
 	output := PathForModuleOut(ctx, container, "aconfig_merged.pb")
 
-	ctx.Build(pctx, BuildParams{
-		Rule:        mergeAconfigFilesRule,
-		Description: "merge aconfig files",
-		Inputs:      inputs,
-		Output:      output,
-		Args: map[string]string{
-			"flags": JoinWithPrefix(inputs.Strings(), "--cache "),
-		},
-	})
+	if generateRule {
+		ctx.Build(pctx, BuildParams{
+			Rule:        mergeAconfigFilesRule,
+			Description: "merge aconfig files",
+			Inputs:      inputs,
+			Output:      output,
+			Args: map[string]string{
+				"flags": JoinWithPrefix(inputs.Strings(), "--cache "),
+			},
+		})
+	}
 
 	return Paths{output}
 }
 
-func SetAconfigFileMkEntries(m *ModuleBase, entries *AndroidMkEntries, aconfigFiles map[string]Paths) {
+func setAconfigFileMkEntries(m *ModuleBase, entries *AndroidMkEntries, aconfigFiles map[string]Paths) {
+	entries.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(m, aconfigFiles))
+}
+
+func getAconfigFilePaths(m *ModuleBase, aconfigFiles map[string]Paths) (paths Paths) {
 	// TODO(b/311155208): The default container here should be system.
-	container := ""
+	container := "system"
 
 	if m.SocSpecific() {
 		container = "vendor"
@@ -103,5 +209,18 @@
 		container = "system_ext"
 	}
 
-	entries.SetPaths("LOCAL_ACONFIG_FILES", aconfigFiles[container])
+	paths = append(paths, aconfigFiles[container]...)
+	if container == "system" {
+		// TODO(b/311155208): Once the default container is system, we can drop this.
+		paths = append(paths, aconfigFiles[""]...)
+	}
+	if container != "system" {
+		if len(aconfigFiles[container]) == 0 && len(aconfigFiles[""]) > 0 {
+			// TODO(b/308625757): Either we guessed the container wrong, or the flag is misdeclared.
+			// For now, just include the system (aka "") container if we get here.
+			//fmt.Printf("container_mismatch: module=%v container=%v files=%v\n", m, container, aconfigFiles)
+		}
+		paths = append(paths, aconfigFiles[""]...)
+	}
+	return
 }
diff --git a/android/androidmk.go b/android/androidmk.go
index 235d7c0..07f7c58 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -859,6 +859,7 @@
 	}
 
 	data.fillInData(ctx, mod)
+	aconfigUpdateAndroidMkData(ctx, mod.(Module), &data)
 
 	prefix := ""
 	if amod.ArchSpecific() {
@@ -943,6 +944,7 @@
 	}
 
 	entriesList := provider.AndroidMkEntries()
+	aconfigUpdateAndroidMkEntries(ctx, mod.(Module), &entriesList)
 
 	// Any new or special cases here need review to verify correct propagation of license information.
 	for _, entries := range entriesList {
diff --git a/android/apex.go b/android/apex.go
index c1e7a5c..4d36a93 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -147,6 +147,13 @@
 
 var ApexTestForInfoProvider = blueprint.NewMutatorProvider[ApexTestForInfo]("apex_test_for")
 
+// ApexBundleInfo contains information about the dependencies of an apex
+type ApexBundleInfo struct {
+	Contents *ApexContents
+}
+
+var ApexBundleInfoProvider = blueprint.NewMutatorProvider[ApexBundleInfo]("apex_info")
+
 // DepIsInSameApex defines an interface that should be used to determine whether a given dependency
 // should be considered as part of the same APEX as the current module or not. Note: this was
 // extracted from ApexModule to make it easier to define custom subsets of the ApexModule interface
diff --git a/android/arch_list.go b/android/arch_list.go
index 801ac49..f4409a9 100644
--- a/android/arch_list.go
+++ b/android/arch_list.go
@@ -34,11 +34,11 @@
 		"broadwell",
 		"goldmont",
 		"goldmont-plus",
-		// Target arch is goldmont, but without xsaves support.
+		// Target arch is goldmont, but without supporting SHA and XSAVES.
 		// This ensures efficient execution on a broad range of Intel/AMD CPUs used
-		// in Chromebooks, including those lacking xsaves support.
+		// in Chromebooks, including those lacking SHA or XSAVES support.
 		// (e.g. Kaby Lake, Gemini Lake, Alder Lake and AMD Zen series)
-		"goldmont-without-xsaves",
+		"goldmont-without-sha-xsaves",
 		"haswell",
 		"icelake",
 		"ivybridge",
@@ -57,7 +57,7 @@
 		"broadwell",
 		"goldmont",
 		"goldmont-plus",
-		"goldmont-without-xsaves",
+		"goldmont-without-sha-xsaves",
 		"haswell",
 		"icelake",
 		"ivybridge",
@@ -203,7 +203,7 @@
 			"popcnt",
 			"movbe",
 		},
-		"goldmont-without-xsaves": {
+		"goldmont-without-sha-xsaves": {
 			"ssse3",
 			"sse4",
 			"sse4_1",
@@ -373,7 +373,7 @@
 			"aes_ni",
 			"popcnt",
 		},
-		"goldmont-without-xsaves": {
+		"goldmont-without-sha-xsaves": {
 			"ssse3",
 			"sse4",
 			"sse4_1",
diff --git a/android/arch_module_context.go b/android/arch_module_context.go
new file mode 100644
index 0000000..3cf4b41
--- /dev/null
+++ b/android/arch_module_context.go
@@ -0,0 +1,83 @@
+// Copyright 2024 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+// ArchModuleContext can be embedded in other contexts to provide information about the module set by
+// the archMutator.
+type ArchModuleContext interface {
+	Target() Target
+	TargetPrimary() bool
+
+	// The additional arch specific targets (e.g. 32/64 bit) that this module variant is
+	// responsible for creating.
+	MultiTargets() []Target
+	Arch() Arch
+	Os() OsType
+	Host() bool
+	Device() bool
+	Darwin() bool
+	Windows() bool
+	PrimaryArch() bool
+}
+
+type archModuleContext struct {
+	// TODO: these should eventually go through a (possibly cached) provider like any other configuration instead
+	//  of being special cased.
+	os            OsType
+	target        Target
+	targetPrimary bool
+	multiTargets  []Target
+	primaryArch   bool
+}
+
+func (a *archModuleContext) Target() Target {
+	return a.target
+}
+
+func (a *archModuleContext) TargetPrimary() bool {
+	return a.targetPrimary
+}
+
+func (a *archModuleContext) MultiTargets() []Target {
+	return a.multiTargets
+}
+
+func (a *archModuleContext) Arch() Arch {
+	return a.target.Arch
+}
+
+func (a *archModuleContext) Os() OsType {
+	return a.os
+}
+
+func (a *archModuleContext) Host() bool {
+	return a.os.Class == Host
+}
+
+func (a *archModuleContext) Device() bool {
+	return a.os.Class == Device
+}
+
+func (a *archModuleContext) Darwin() bool {
+	return a.os == Darwin
+}
+
+func (a *archModuleContext) Windows() bool {
+	return a.os == Windows
+}
+
+func (b *archModuleContext) PrimaryArch() bool {
+	return b.primaryArch
+}
diff --git a/android/base_module_context.go b/android/base_module_context.go
index 0cf5d77..b9c1153 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -26,6 +26,7 @@
 // instead of a blueprint.Module, plus some extra methods that return Android-specific information
 // about the current module.
 type BaseModuleContext interface {
+	ArchModuleContext
 	EarlyModuleContext
 
 	blueprintBaseModuleContext() blueprint.BaseModuleContext
@@ -213,29 +214,12 @@
 	// getMissingDependencies returns the list of missing dependencies.
 	// Calling this function prevents adding new dependencies.
 	getMissingDependencies() []string
-
-	Target() Target
-	TargetPrimary() bool
-
-	// The additional arch specific targets (e.g. 32/64 bit) that this module variant is
-	// responsible for creating.
-	MultiTargets() []Target
-	Arch() Arch
-	Os() OsType
-	Host() bool
-	Device() bool
-	Darwin() bool
-	Windows() bool
-	PrimaryArch() bool
 }
 
 type baseModuleContext struct {
 	bp blueprint.BaseModuleContext
 	earlyModuleContext
-	os            OsType
-	target        Target
-	multiTargets  []Target
-	targetPrimary bool
+	archModuleContext
 
 	walkPath []Module
 	tagPath  []blueprint.DependencyTag
@@ -580,46 +564,3 @@
 	}
 	return sb.String()
 }
-
-func (b *baseModuleContext) Target() Target {
-	return b.target
-}
-
-func (b *baseModuleContext) TargetPrimary() bool {
-	return b.targetPrimary
-}
-
-func (b *baseModuleContext) MultiTargets() []Target {
-	return b.multiTargets
-}
-
-func (b *baseModuleContext) Arch() Arch {
-	return b.target.Arch
-}
-
-func (b *baseModuleContext) Os() OsType {
-	return b.os
-}
-
-func (b *baseModuleContext) Host() bool {
-	return b.os.Class == Host
-}
-
-func (b *baseModuleContext) Device() bool {
-	return b.os.Class == Device
-}
-
-func (b *baseModuleContext) Darwin() bool {
-	return b.os == Darwin
-}
-
-func (b *baseModuleContext) Windows() bool {
-	return b.os == Windows
-}
-
-func (b *baseModuleContext) PrimaryArch() bool {
-	if len(b.config.Targets[b.target.Os]) <= 1 {
-		return true
-	}
-	return b.target.Arch.ArchType == b.config.Targets[b.target.Os][0].Arch.ArchType
-}
diff --git a/android/config.go b/android/config.go
index eb1e647..d94a86f 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1309,6 +1309,10 @@
 	return String(c.productVariables.VendorApiLevel)
 }
 
+func (c *config) VendorApiLevelFrozen() bool {
+	return c.productVariables.GetBuildFlagBool("RELEASE_BOARD_API_LEVEL_FROZEN")
+}
+
 func (c *deviceConfig) Arches() []Arch {
 	var arches []Arch
 	for _, target := range c.config.Targets[Android] {
@@ -1970,6 +1974,10 @@
 	return val, ok
 }
 
+func (c *config) UseResourceProcessorByDefault() bool {
+	return c.productVariables.GetBuildFlagBool("RELEASE_USE_RESOURCE_PROCESSOR_BY_DEFAULT")
+}
+
 var (
 	mainlineApexContributionBuildFlags = []string{
 		"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES",
diff --git a/android/defaults_test.go b/android/defaults_test.go
index a7542ab..0ad0fb8 100644
--- a/android/defaults_test.go
+++ b/android/defaults_test.go
@@ -16,10 +16,13 @@
 
 import (
 	"testing"
+
+	"github.com/google/blueprint"
 )
 
 type defaultsTestProperties struct {
-	Foo []string
+	Foo       []string
+	Path_prop []string `android:"path"`
 }
 
 type defaultsTestModule struct {
@@ -130,3 +133,40 @@
 	// TODO: missing transitive defaults is currently not handled
 	_ = missingTransitiveDefaults
 }
+
+func TestDefaultsPathProperties(t *testing.T) {
+	bp := `
+		defaults {
+			name: "defaults",
+			path_prop: [":gen"],
+		}
+
+		test {
+			name: "foo",
+			defaults: ["defaults"],
+		}
+
+		test {
+			name: "gen",
+		}
+	`
+
+	result := GroupFixturePreparers(
+		prepareForDefaultsTest,
+		FixtureWithRootAndroidBp(bp),
+	).RunTest(t)
+
+	collectDeps := func(m Module) []string {
+		var deps []string
+		result.VisitDirectDeps(m, func(dep blueprint.Module) {
+			deps = append(deps, result.ModuleName(dep))
+		})
+		return deps
+	}
+
+	foo := result.Module("foo", "")
+	defaults := result.Module("defaults", "")
+
+	AssertStringListContains(t, "foo should depend on gen", collectDeps(foo), "gen")
+	AssertStringListDoesNotContain(t, "defaults should not depend on gen", collectDeps(defaults), "gen")
+}
diff --git a/android/module.go b/android/module.go
index 1abc6aa..5c7bbbf 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1641,14 +1641,31 @@
 func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext {
 	return baseModuleContext{
 		bp:                 ctx,
+		archModuleContext:  m.archModuleContextFactory(ctx),
 		earlyModuleContext: m.earlyModuleContextFactory(ctx),
-		os:                 m.commonProperties.CompileOS,
-		target:             m.commonProperties.CompileTarget,
-		targetPrimary:      m.commonProperties.CompilePrimary,
-		multiTargets:       m.commonProperties.CompileMultiTargets,
 	}
 }
 
+func (m *ModuleBase) archModuleContextFactory(ctx blueprint.IncomingTransitionContext) archModuleContext {
+	config := ctx.Config().(Config)
+	target := m.Target()
+	primaryArch := false
+	if len(config.Targets[target.Os]) <= 1 {
+		primaryArch = true
+	} else {
+		primaryArch = target.Arch.ArchType == config.Targets[target.Os][0].Arch.ArchType
+	}
+
+	return archModuleContext{
+		os:            m.commonProperties.CompileOS,
+		target:        m.commonProperties.CompileTarget,
+		targetPrimary: m.commonProperties.CompilePrimary,
+		multiTargets:  m.commonProperties.CompileMultiTargets,
+		primaryArch:   primaryArch,
+	}
+
+}
+
 func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
 	ctx := &moduleContext{
 		module:            m.module,
@@ -1760,6 +1777,11 @@
 			return
 		}
 
+		aconfigUpdateAndroidBuildActions(ctx)
+		if ctx.Failed() {
+			return
+		}
+
 		// Create the set of tagged dist files after calling GenerateAndroidBuildActions
 		// as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
 		// output paths being set which must be done before or during
diff --git a/android/mutator.go b/android/mutator.go
index 5b76d20..22e9160 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -365,15 +365,21 @@
 }
 
 type IncomingTransitionContext interface {
+	ArchModuleContext
+
 	// Module returns the target of the dependency edge for which the transition
 	// is being computed
 	Module() Module
 
 	// Config returns the configuration for the build.
 	Config() Config
+
+	DeviceConfig() DeviceConfig
 }
 
 type OutgoingTransitionContext interface {
+	ArchModuleContext
+
 	// Module returns the target of the dependency edge for which the transition
 	// is being computed
 	Module() Module
@@ -381,9 +387,14 @@
 	// DepTag() Returns the dependency tag through which this dependency is
 	// reached
 	DepTag() blueprint.DependencyTag
+
+	// Config returns the configuration for the build.
+	Config() Config
+
+	DeviceConfig() DeviceConfig
 }
 
-// Transition mutators implement a top-down mechanism where a module tells its
+// TransitionMutator implements a top-down mechanism where a module tells its
 // direct dependencies what variation they should be built in but the dependency
 // has the final say.
 //
@@ -448,18 +459,18 @@
 	// called on.
 	Split(ctx BaseModuleContext) []string
 
-	// Called on a module to determine which variation it wants from its direct
-	// dependencies. The dependency itself can override this decision. This method
-	// should not mutate the module itself.
+	// OutgoingTransition is called on a module to determine which variation it wants
+	// from its direct dependencies. The dependency itself can override this decision.
+	// This method should not mutate the module itself.
 	OutgoingTransition(ctx OutgoingTransitionContext, sourceVariation string) string
 
-	// Called on a module to determine which variation it should be in based on
-	// the variation modules that depend on it want. This gives the module a final
-	// say about its own variations. This method should not mutate the module
+	// IncomingTransition is called on a module to determine which variation it should
+	// be in based on the variation modules that depend on it want. This gives the module
+	// a final say about its own variations. This method should not mutate the module
 	// itself.
 	IncomingTransition(ctx IncomingTransitionContext, incomingVariation string) string
 
-	// Called after a module was split into multiple variations on each variation.
+	// Mutate is called after a module was split into multiple variations on each variation.
 	// It should not split the module any further but adding new dependencies is
 	// fine. Unlike all the other methods on TransitionMutator, this method is
 	// allowed to mutate the module.
@@ -481,6 +492,7 @@
 }
 
 type outgoingTransitionContextImpl struct {
+	archModuleContext
 	bp blueprint.OutgoingTransitionContext
 }
 
@@ -492,15 +504,28 @@
 	return c.bp.DepTag()
 }
 
-func (a *androidTransitionMutator) OutgoingTransition(ctx blueprint.OutgoingTransitionContext, sourceVariation string) string {
-	if _, ok := ctx.Module().(Module); ok {
-		return a.mutator.OutgoingTransition(&outgoingTransitionContextImpl{bp: ctx}, sourceVariation)
+func (c *outgoingTransitionContextImpl) Config() Config {
+	return c.bp.Config().(Config)
+}
+
+func (c *outgoingTransitionContextImpl) DeviceConfig() DeviceConfig {
+	return DeviceConfig{c.bp.Config().(Config).deviceConfig}
+}
+
+func (a *androidTransitionMutator) OutgoingTransition(bpctx blueprint.OutgoingTransitionContext, sourceVariation string) string {
+	if m, ok := bpctx.Module().(Module); ok {
+		ctx := &outgoingTransitionContextImpl{
+			archModuleContext: m.base().archModuleContextFactory(bpctx),
+			bp:                bpctx,
+		}
+		return a.mutator.OutgoingTransition(ctx, sourceVariation)
 	} else {
 		return ""
 	}
 }
 
 type incomingTransitionContextImpl struct {
+	archModuleContext
 	bp blueprint.IncomingTransitionContext
 }
 
@@ -512,9 +537,17 @@
 	return c.bp.Config().(Config)
 }
 
-func (a *androidTransitionMutator) IncomingTransition(ctx blueprint.IncomingTransitionContext, incomingVariation string) string {
-	if _, ok := ctx.Module().(Module); ok {
-		return a.mutator.IncomingTransition(&incomingTransitionContextImpl{bp: ctx}, incomingVariation)
+func (c *incomingTransitionContextImpl) DeviceConfig() DeviceConfig {
+	return DeviceConfig{c.bp.Config().(Config).deviceConfig}
+}
+
+func (a *androidTransitionMutator) IncomingTransition(bpctx blueprint.IncomingTransitionContext, incomingVariation string) string {
+	if m, ok := bpctx.Module().(Module); ok {
+		ctx := &incomingTransitionContextImpl{
+			archModuleContext: m.base().archModuleContextFactory(bpctx),
+			bp:                bpctx,
+		}
+		return a.mutator.IncomingTransition(ctx, incomingVariation)
 	} else {
 		return ""
 	}
diff --git a/android/path_properties.go b/android/path_properties.go
index fdc4d91..bbfaa8c 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -33,6 +33,11 @@
 // The pathDepsMutator automatically adds dependencies on any module that is listed with the
 // ":module" module reference syntax in a property that is tagged with `android:"path"`.
 func pathDepsMutator(ctx BottomUpMutatorContext) {
+	if _, ok := ctx.Module().(DefaultsModule); ok {
+		// Defaults modules shouldn't have dependencies added for path properties, they have already been
+		// squashed into the real modules.
+		return
+	}
 	props := ctx.Module().base().GetProperties()
 	addPathDepsForProps(ctx, props)
 }
diff --git a/android/paths_test.go b/android/paths_test.go
index bf46c34..93b9b9a 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -268,8 +268,10 @@
 			name: "host binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     hostTarget.Os,
-					target: hostTarget,
+					archModuleContext: archModuleContext{
+						os:     hostTarget.Os,
+						target: hostTarget,
+					},
 				},
 			},
 			in:           []string{"bin", "my_test"},
@@ -281,8 +283,10 @@
 			name: "system binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 			},
 			in:           []string{"bin", "my_test"},
@@ -293,8 +297,10 @@
 			name: "vendor binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: socSpecificModule,
 					},
@@ -308,8 +314,10 @@
 			name: "odm binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: deviceSpecificModule,
 					},
@@ -323,8 +331,10 @@
 			name: "product binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: productSpecificModule,
 					},
@@ -338,8 +348,10 @@
 			name: "system_ext binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: systemExtSpecificModule,
 					},
@@ -353,8 +365,10 @@
 			name: "root binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inRoot: true,
 			},
@@ -366,8 +380,10 @@
 			name: "recovery binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inRecovery: true,
 			},
@@ -379,8 +395,10 @@
 			name: "recovery root binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inRecovery: true,
 				inRoot:     true,
@@ -394,8 +412,10 @@
 			name: "ramdisk binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inRamdisk: true,
 			},
@@ -407,8 +427,10 @@
 			name: "ramdisk root binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inRamdisk: true,
 				inRoot:    true,
@@ -421,8 +443,10 @@
 			name: "vendor_ramdisk binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inVendorRamdisk: true,
 			},
@@ -434,8 +458,10 @@
 			name: "vendor_ramdisk root binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inVendorRamdisk: true,
 				inRoot:          true,
@@ -448,8 +474,10 @@
 			name: "debug_ramdisk binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inDebugRamdisk: true,
 			},
@@ -461,8 +489,10 @@
 			name: "system native test binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inData: true,
 			},
@@ -474,8 +504,10 @@
 			name: "vendor native test binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: socSpecificModule,
 					},
@@ -490,8 +522,10 @@
 			name: "odm native test binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: deviceSpecificModule,
 					},
@@ -506,8 +540,10 @@
 			name: "product native test binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: productSpecificModule,
 					},
@@ -523,8 +559,10 @@
 			name: "system_ext native test binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: systemExtSpecificModule,
 					},
@@ -540,8 +578,10 @@
 			name: "sanitized system binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inSanitizerDir: true,
 			},
@@ -553,8 +593,10 @@
 			name: "sanitized vendor binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: socSpecificModule,
 					},
@@ -569,8 +611,10 @@
 			name: "sanitized odm binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: deviceSpecificModule,
 					},
@@ -585,8 +629,10 @@
 			name: "sanitized product binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: productSpecificModule,
 					},
@@ -602,8 +648,10 @@
 			name: "sanitized system_ext binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: systemExtSpecificModule,
 					},
@@ -619,8 +667,10 @@
 			name: "sanitized system native test binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inData:         true,
 				inSanitizerDir: true,
@@ -633,8 +683,10 @@
 			name: "sanitized vendor native test binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: socSpecificModule,
 					},
@@ -650,8 +702,10 @@
 			name: "sanitized odm native test binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: deviceSpecificModule,
 					},
@@ -667,8 +721,10 @@
 			name: "sanitized product native test binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: productSpecificModule,
 					},
@@ -684,8 +740,10 @@
 			name: "sanitized system_ext native test binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 					earlyModuleContext: earlyModuleContext{
 						kind: systemExtSpecificModule,
 					},
@@ -700,8 +758,10 @@
 			name: "device testcases",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inTestcases: true,
 			},
@@ -712,8 +772,10 @@
 			name: "host testcases",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     hostTarget.Os,
-					target: hostTarget,
+					archModuleContext: archModuleContext{
+						os:     hostTarget.Os,
+						target: hostTarget,
+					},
 				},
 				inTestcases: true,
 			},
@@ -724,8 +786,10 @@
 			name: "forced host testcases",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inTestcases: true,
 				forceOS:     &Linux,
@@ -771,8 +835,10 @@
 			name: "ramdisk binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inRamdisk: true,
 				inRoot:    true,
@@ -786,8 +852,10 @@
 			name: "vendor_ramdisk binary",
 			ctx: &testModuleInstallPathContext{
 				baseModuleContext: baseModuleContext{
-					os:     deviceTarget.Os,
-					target: deviceTarget,
+					archModuleContext: archModuleContext{
+						os:     deviceTarget.Os,
+						target: deviceTarget,
+					},
 				},
 				inVendorRamdisk: true,
 				inRoot:          true,
@@ -821,8 +889,10 @@
 
 	ctx := &testModuleInstallPathContext{
 		baseModuleContext: baseModuleContext{
-			os:     deviceTarget.Os,
-			target: deviceTarget,
+			archModuleContext: archModuleContext{
+				os:     deviceTarget.Os,
+				target: deviceTarget,
+			},
 		},
 	}
 	ctx.baseModuleContext.config = testConfig
@@ -1491,8 +1561,10 @@
 
 	ctx := &testModuleInstallPathContext{
 		baseModuleContext: baseModuleContext{
-			os:     deviceTarget.Os,
-			target: deviceTarget,
+			archModuleContext: archModuleContext{
+				os:     deviceTarget.Os,
+				target: deviceTarget,
+			},
 		},
 	}
 	ctx.baseModuleContext.config = testConfig
diff --git a/android/team_proto/Android.bp b/android/team_proto/Android.bp
index 061e77e..7e2a4c1 100644
--- a/android/team_proto/Android.bp
+++ b/android/team_proto/Android.bp
@@ -27,3 +27,17 @@
         "team.pb.go",
     ],
 }
+
+python_library_host {
+    name: "teams-proto-py",
+    pkg_path: "teams",
+    srcs: [
+        "team.proto",
+    ],
+    libs: [
+        "libprotobuf-python",
+    ],
+    proto: {
+        canonical_path_from_root: false,
+    },
+}
diff --git a/android/testing.go b/android/testing.go
index f88049c..7b4411e 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -1121,6 +1121,7 @@
 	}
 
 	entriesList := p.AndroidMkEntries()
+	aconfigUpdateAndroidMkEntries(ctx, mod.(Module), &entriesList)
 	for i, _ := range entriesList {
 		entriesList[i].fillInEntries(ctx, mod)
 	}
@@ -1136,6 +1137,7 @@
 	}
 	data := p.AndroidMk()
 	data.fillInData(ctx, mod)
+	aconfigUpdateAndroidMkData(ctx, mod.(Module), &data)
 	return data
 }
 
diff --git a/apex/androidmk.go b/apex/androidmk.go
index bc68ad3..619be8d 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -124,6 +124,10 @@
 		pathForSymbol := filepath.Join("$(PRODUCT_OUT)", "apex", apexBundleName, fi.installDir)
 		modulePath := pathForSymbol
 		fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", modulePath)
+		// AconfigUpdateAndroidMkData may have added elements to Extra.  Process them here.
+		for _, extra := range apexAndroidMkData.Extra {
+			extra(w, fi.builtFile)
+		}
 
 		// For non-flattend APEXes, the merged notice file is attached to the APEX itself.
 		// We don't need to have notice file for the individual modules in it. Otherwise,
@@ -229,6 +233,7 @@
 
 func (a *apexBundle) androidMkForType() android.AndroidMkData {
 	return android.AndroidMkData{
+		// While we do not provide a value for `Extra`, AconfigUpdateAndroidMkData may add some, which we must honor.
 		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
 			moduleNames := []string{}
 			if a.installable() {
@@ -269,6 +274,10 @@
 
 			android.AndroidMkEmitAssignList(w, "LOCAL_OVERRIDES_MODULES", a.overridableProperties.Overrides)
 			a.writeRequiredModules(w, moduleNames)
+			// AconfigUpdateAndroidMkData may have added elements to Extra.  Process them here.
+			for _, extra := range data.Extra {
+				extra(w, a.outputFile)
+			}
 
 			fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
 			fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).BUNDLE :=", a.bundleModuleFile.String())
diff --git a/apex/apex.go b/apex/apex.go
index 5b0def0..276ac80 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -929,12 +929,6 @@
 
 var DCLAInfoProvider = blueprint.NewMutatorProvider[DCLAInfo]("apex_info")
 
-type ApexBundleInfo struct {
-	Contents *android.ApexContents
-}
-
-var ApexBundleInfoProvider = blueprint.NewMutatorProvider[ApexBundleInfo]("apex_info")
-
 var _ ApexInfoMutator = (*apexBundle)(nil)
 
 func (a *apexBundle) ApexVariationName() string {
@@ -1035,7 +1029,7 @@
 
 	// The membership information is saved for later access
 	apexContents := android.NewApexContents(contents)
-	android.SetProvider(mctx, ApexBundleInfoProvider, ApexBundleInfo{
+	android.SetProvider(mctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{
 		Contents: apexContents,
 	})
 
@@ -1243,7 +1237,7 @@
 	if _, ok := mctx.Module().(android.ApexModule); ok {
 		var contents []*android.ApexContents
 		for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
-			abInfo, _ := android.OtherModuleProvider(mctx, testFor, ApexBundleInfoProvider)
+			abInfo, _ := android.OtherModuleProvider(mctx, testFor, android.ApexBundleInfoProvider)
 			contents = append(contents, abInfo.Contents)
 		}
 		android.SetProvider(mctx, android.ApexTestForInfoProvider, android.ApexTestForInfo{
@@ -1418,7 +1412,7 @@
 var _ cc.Coverage = (*apexBundle)(nil)
 
 // Implements cc.Coverage
-func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
+func (a *apexBundle) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool {
 	return ctx.DeviceConfig().NativeCoverageEnabled()
 }
 
@@ -2192,7 +2186,7 @@
 			af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
 			af.transitiveDep = true
 
-			abInfo, _ := android.ModuleProvider(ctx, ApexBundleInfoProvider)
+			abInfo, _ := android.ModuleProvider(ctx, android.ApexBundleInfoProvider)
 			if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.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.
@@ -2658,7 +2652,7 @@
 		return
 	}
 
-	abInfo, _ := android.ModuleProvider(ctx, ApexBundleInfoProvider)
+	abInfo, _ := android.ModuleProvider(ctx, android.ApexBundleInfoProvider)
 
 	a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
 		if ccm, ok := to.(*cc.Module); ok {
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index f1e71b0..778c20a 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -316,6 +316,7 @@
 		java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
 			`art-bootclasspath-fragment`,
 			`com.android.art.key`,
+			`dex2oatd`,
 		})
 
 		// Make sure that the source bootclasspath_fragment copies its dex files to the predefined
@@ -387,6 +388,7 @@
 		java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
 			`art-bootclasspath-fragment`,
 			`com.android.art.key`,
+			`dex2oatd`,
 			`prebuilt_com.android.art`,
 		})
 
@@ -650,6 +652,7 @@
 	})
 
 	java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{
+		`dex2oatd`,
 		`myapex.key`,
 		`mybootclasspathfragment`,
 	})
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index 161941d..2bd3159 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -155,7 +155,7 @@
 	info, _ := android.SingletonModuleProvider(result, pbcp, java.MonolithicHiddenAPIInfoProvider)
 
 	for _, category := range java.HiddenAPIFlagFileCategories {
-		name := category.PropertyName
+		name := category.PropertyName()
 		message := fmt.Sprintf("category %s", name)
 		filename := strings.ReplaceAll(name, "_", "-")
 		expected := []string{fmt.Sprintf("%s.txt", filename), fmt.Sprintf("bar-%s.txt", filename)}
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 1ec38eb..551942d 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -201,6 +201,10 @@
 	if !p.hasExportedDeps() {
 		return
 	}
+	// If this prebuilt apex has not been selected, return
+	if p.IsHideFromMake() {
+		return
+	}
 	// Use apex_name to determine the api domain of this prebuilt apex
 	apexName := p.ApexVariationName()
 	di, err := android.FindDeapexerProviderForModule(ctx)
@@ -438,7 +442,7 @@
 
 	// Create contents for the prebuilt_apex and store it away for later use.
 	apexContents := android.NewApexContents(contents)
-	android.SetProvider(mctx, ApexBundleInfoProvider, ApexBundleInfo{
+	android.SetProvider(mctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{
 		Contents: apexContents,
 	})
 
diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go
index 01629c9..6b2c397 100644
--- a/apex/systemserver_classpath_fragment_test.go
+++ b/apex/systemserver_classpath_fragment_test.go
@@ -106,6 +106,7 @@
 	})
 
 	java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex", []string{
+		`dex2oatd`,
 		`myapex.key`,
 		`mysystemserverclasspathfragment`,
 	})
@@ -162,6 +163,7 @@
 	})
 
 	java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{
+		`dex2oatd`,
 		`myapex.key`,
 		`mysystemserverclasspathfragment`,
 	})
@@ -219,6 +221,8 @@
 }
 
 func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
+	// TODO(spandandas): Fix the rules for profile guided dexpreopt of deapexed prebuilt jars
+	t.Skip()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithSystemserverclasspathFragment,
 		prepareForTestWithMyapex,
@@ -377,6 +381,8 @@
 }
 
 func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) {
+	// TODO(spandandas): Fix the rules for profile guided dexpreopt of deapexed prebuilt jars
+	t.Skip()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithSystemserverclasspathFragment,
 		prepareForTestWithMyapex,
diff --git a/bpf/bpf.go b/bpf/bpf.go
index 32d62b5..e1b512f 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -231,6 +231,10 @@
 				fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base())
 				fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
 				fmt.Fprintln(w, localModulePath)
+				// AconfigUpdateAndroidMkData may have added elements to Extra.  Process them here.
+				for _, extra := range data.Extra {
+					extra(w, nil)
+				}
 				fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
 				fmt.Fprintln(w)
 			}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index fe542b0..c39668c 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -83,8 +83,9 @@
 		// causing multiple ART APEXes (com.android.art and com.android.art.debug)
 		// to be installed. And this is breaking some older devices (like marlin)
 		// where system.img is small.
-		Required: c.Properties.AndroidMkRuntimeLibs,
-		Include:  "$(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk",
+		Required:     c.Properties.AndroidMkRuntimeLibs,
+		OverrideName: c.BaseModuleName(),
+		Include:      "$(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk",
 
 		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
 			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
diff --git a/cc/cc.go b/cc/cc.go
index c07e358..449d38f 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -68,16 +68,14 @@
 
 		ctx.TopDown("fuzz_deps", fuzzMutatorDeps)
 
-		ctx.BottomUp("coverage", coverageMutator).Parallel()
+		ctx.Transition("coverage", &coverageTransitionMutator{})
 
 		ctx.TopDown("afdo_deps", afdoDepsMutator)
 		ctx.BottomUp("afdo", afdoMutator).Parallel()
 
-		ctx.TopDown("orderfile_deps", orderfileDepsMutator)
-		ctx.BottomUp("orderfile", orderfileMutator).Parallel()
+		ctx.Transition("orderfile", &orderfileTransitionMutator{})
 
-		ctx.TopDown("lto_deps", ltoDepsMutator)
-		ctx.BottomUp("lto", ltoMutator).Parallel()
+		ctx.Transition("lto", &ltoTransitionMutator{})
 
 		ctx.BottomUp("check_linktype", checkLinkTypeMutator).Parallel()
 		ctx.TopDown("double_loadable", checkDoubleLoadableLibraries).Parallel()
@@ -1608,9 +1606,10 @@
 
 func (ctx *moduleContextImpl) sdkVersion() string {
 	if ctx.ctx.Device() {
-		if ctx.useVndk() {
+		config := ctx.ctx.Config()
+		if !config.IsVndkDeprecated() && ctx.useVndk() {
 			vndkVer := ctx.mod.VndkVersion()
-			if inList(vndkVer, ctx.ctx.Config().PlatformVersionActiveCodenames()) {
+			if inList(vndkVer, config.PlatformVersionActiveCodenames()) {
 				return "current"
 			}
 			return vndkVer
@@ -1628,6 +1627,17 @@
 	if ver == "apex_inherit" || ver == "" {
 		ver = ctx.sdkVersion()
 	}
+
+	if ctx.ctx.Device() {
+		config := ctx.ctx.Config()
+		if config.IsVndkDeprecated() && ctx.inVendor() {
+			// If building for vendor with final API, then use the latest _stable_ API as "current".
+			if config.VendorApiLevelFrozen() && (ver == "" || ver == "current") {
+				ver = config.PlatformSdkVersion().String()
+			}
+		}
+	}
+
 	// For crt objects, the meaning of min_sdk_version is very different from other types of
 	// module. For them, min_sdk_version defines the oldest version that the build system will
 	// create versioned variants for. For example, if min_sdk_version is 16, then sdk variant of
@@ -1744,7 +1754,7 @@
 }
 
 func (ctx *moduleContextImpl) baseModuleName() string {
-	return ctx.mod.ModuleBase.BaseModuleName()
+	return ctx.mod.BaseModuleName()
 }
 
 func (ctx *moduleContextImpl) getVndkExtendsModuleName() string {
@@ -4173,6 +4183,18 @@
 	return ""
 }
 
+type sourceModuleName interface {
+	sourceModuleName() string
+}
+
+func (c *Module) BaseModuleName() string {
+	if smn, ok := c.linker.(sourceModuleName); ok && smn.sourceModuleName() != "" {
+		// if the prebuilt module sets a source_module_name in Android.bp, use that
+		return smn.sourceModuleName()
+	}
+	return c.ModuleBase.BaseModuleName()
+}
+
 var Bool = proptools.Bool
 var BoolDefault = proptools.BoolDefault
 var BoolPtr = proptools.BoolPtr
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 321bd38..6cc500b 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -43,6 +43,7 @@
 	android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
 		variables.VendorApiLevel = StringPtr("202404")
 		variables.DeviceVndkVersion = StringPtr("current")
+		variables.KeepVndk = BoolPtr(true)
 		variables.Platform_vndk_version = StringPtr("29")
 	}),
 )
@@ -4843,3 +4844,43 @@
 	testDepWithVariant("vendor")
 	testDepWithVariant("product")
 }
+
+func TestVendorSdkVersionWithoutVndk(t *testing.T) {
+	t.Parallel()
+
+	bp := `
+		cc_library {
+			name: "libfoo",
+			srcs: ["libfoo.cc"],
+			vendor_available: true,
+		}
+
+		cc_library {
+			name: "libbar",
+			srcs: ["libbar.cc"],
+			vendor_available: true,
+			min_sdk_version: "29",
+		}
+	`
+
+	ctx := prepareForCcTestWithoutVndk.RunTestWithBp(t, bp)
+	testSdkVersionFlag := func(module, version string) {
+		flags := ctx.ModuleForTests(module, "android_vendor_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+		android.AssertStringDoesContain(t, "min sdk version", flags, "-target aarch64-linux-android"+version)
+	}
+
+	testSdkVersionFlag("libfoo", "10000")
+	testSdkVersionFlag("libbar", "29")
+
+	ctx = android.GroupFixturePreparers(
+		prepareForCcTestWithoutVndk,
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+			if variables.BuildFlags == nil {
+				variables.BuildFlags = make(map[string]string)
+			}
+			variables.BuildFlags["RELEASE_BOARD_API_LEVEL_FROZEN"] = "true"
+		}),
+	).RunTestWithBp(t, bp)
+	testSdkVersionFlag("libfoo", "30")
+	testSdkVersionFlag("libbar", "29")
+}
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index 3d6890c..603bc6d 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -28,13 +28,20 @@
 
 	armCflags = []string{
 		"-fomit-frame-pointer",
+		// Revert this after b/322359235 is fixed
+		"-mllvm", "-enable-shrink-wrap=false",
 	}
 
-	armCppflags = []string{}
+	armCppflags = []string{
+		// Revert this after b/322359235 is fixed
+		"-mllvm", "-enable-shrink-wrap=false",
+  }
 
 	armLdflags = []string{
 		"-Wl,--hash-style=gnu",
 		"-Wl,-m,armelf",
+		// Revert this after b/322359235 is fixed
+		"-Wl,-mllvm", "-Wl,-enable-shrink-wrap=false",
 	}
 
 	armLldflags = armLdflags
diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go
index ff0a3b7..b97d511 100644
--- a/cc/config/x86_64_device.go
+++ b/cc/config/x86_64_device.go
@@ -49,8 +49,9 @@
 		"goldmont-plus": []string{
 			"-march=goldmont-plus",
 		},
-		"goldmont-without-xsaves": []string{
+		"goldmont-without-sha-xsaves": []string{
 			"-march=goldmont",
+			"-mno-sha",
 			"-mno-xsaves",
 		},
 		"haswell": []string{
diff --git a/cc/config/x86_device.go b/cc/config/x86_device.go
index 08be869..2faa670 100644
--- a/cc/config/x86_device.go
+++ b/cc/config/x86_device.go
@@ -56,8 +56,9 @@
 		"goldmont-plus": []string{
 			"-march=goldmont-plus",
 		},
-		"goldmont-without-xsaves": []string{
+		"goldmont-without-sha-xsaves": []string{
 			"-march=goldmont",
+			"-mno-sha",
 			"-mno-xsaves",
 		},
 		"haswell": []string{
diff --git a/cc/coverage.go b/cc/coverage.go
index cbd8a6f..43f5e07 100644
--- a/cc/coverage.go
+++ b/cc/coverage.go
@@ -22,6 +22,29 @@
 	"android/soong/android"
 )
 
+var (
+ 	clangCoverageHostLdFlags = []string{
+ 		"-Wl,--no-as-needed",
+ 		"-Wl,--wrap,open",
+ 	}
+ 	clangContinuousCoverageFlags = []string{
+ 		"-mllvm",
+ 		"-runtime-counter-relocation",
+ 	}
+ 	clangCoverageCFlags = []string{
+ 		"-Wno-frame-larger-than=",
+ 	}
+ 	clangCoverageCommonFlags = []string{
+ 		"-fcoverage-mapping",
+ 		"-Wno-pass-failed",
+ 		"-D__ANDROID_CLANG_COVERAGE__",
+ 	}
+ 	clangCoverageHWASanFlags = []string{
+ 		"-mllvm",
+ 		"-hwasan-globals=0",
+ 	}
+)
+
 const profileInstrFlag = "-fprofile-instr-generate=/data/misc/trace/clang-%p-%m.profraw"
 
 type CoverageProperties struct {
@@ -102,19 +125,19 @@
 			// flags that the module may use.
 			flags.Local.CFlags = append(flags.Local.CFlags, "-Wno-frame-larger-than=", "-O0")
 		} else if clangCoverage {
-			flags.Local.CommonFlags = append(flags.Local.CommonFlags, profileInstrFlag,
-				"-fcoverage-mapping", "-Wno-pass-failed", "-D__ANDROID_CLANG_COVERAGE__")
+			flags.Local.CommonFlags = append(flags.Local.CommonFlags, profileInstrFlag)
+			flags.Local.CommonFlags = append(flags.Local.CommonFlags, clangCoverageCommonFlags...)
 			// Override -Wframe-larger-than.  We can expect frame size increase after
 			// coverage instrumentation.
-			flags.Local.CFlags = append(flags.Local.CFlags, "-Wno-frame-larger-than=")
+			flags.Local.CFlags = append(flags.Local.CFlags, clangCoverageCFlags...)
 			if EnableContinuousCoverage(ctx) {
-				flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-mllvm", "-runtime-counter-relocation")
+				flags.Local.CommonFlags = append(flags.Local.CommonFlags, clangContinuousCoverageFlags...)
 			}
 
 			// http://b/248022906, http://b/247941801  enabling coverage and hwasan-globals
 			// instrumentation together causes duplicate-symbol errors for __llvm_profile_filename.
 			if c, ok := ctx.Module().(*Module); ok && c.sanitize.isSanitizerEnabled(Hwasan) {
-				flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-mllvm", "-hwasan-globals=0")
+				flags.Local.CommonFlags = append(flags.Local.CommonFlags, clangCoverageHWASanFlags...)
 			}
 		}
 	}
@@ -223,7 +246,7 @@
 
 type UseCoverage interface {
 	android.Module
-	IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool
+	IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool
 }
 
 // Coverage is an interface for non-CC modules to implement to be mutated for coverage
@@ -235,43 +258,86 @@
 	EnableCoverageIfNeeded()
 }
 
-func coverageMutator(mctx android.BottomUpMutatorContext) {
-	if c, ok := mctx.Module().(*Module); ok && c.coverage != nil {
-		needCoverageVariant := c.coverage.Properties.NeedCoverageVariant
-		needCoverageBuild := c.coverage.Properties.NeedCoverageBuild
-		if needCoverageVariant {
-			m := mctx.CreateVariations("", "cov")
+type coverageTransitionMutator struct{}
 
-			// Setup the non-coverage version and set HideFromMake and
-			// PreventInstall to true.
-			m[0].(*Module).coverage.Properties.CoverageEnabled = false
-			m[0].(*Module).coverage.Properties.IsCoverageVariant = false
-			m[0].(*Module).Properties.HideFromMake = true
-			m[0].(*Module).Properties.PreventInstall = true
+var _ android.TransitionMutator = (*coverageTransitionMutator)(nil)
 
-			// The coverage-enabled version inherits HideFromMake,
-			// PreventInstall from the original module.
-			m[1].(*Module).coverage.Properties.CoverageEnabled = needCoverageBuild
-			m[1].(*Module).coverage.Properties.IsCoverageVariant = true
+func (c coverageTransitionMutator) Split(ctx android.BaseModuleContext) []string {
+	if c, ok := ctx.Module().(*Module); ok && c.coverage != nil {
+		if c.coverage.Properties.NeedCoverageVariant {
+			return []string{"", "cov"}
 		}
-	} else if cov, ok := mctx.Module().(Coverage); ok && cov.IsNativeCoverageNeeded(mctx) {
+	} else if cov, ok := ctx.Module().(Coverage); ok && cov.IsNativeCoverageNeeded(ctx) {
 		// APEX and Rust modules fall here
 
 		// Note: variant "" is also created because an APEX can be depended on by another
 		// module which are split into "" and "cov" variants. e.g. when cc_test refers
 		// to an APEX via 'data' property.
-		m := mctx.CreateVariations("", "cov")
-		m[0].(Coverage).MarkAsCoverageVariant(false)
-		m[0].(Coverage).SetPreventInstall()
-		m[0].(Coverage).HideFromMake()
-
-		m[1].(Coverage).MarkAsCoverageVariant(true)
-		m[1].(Coverage).EnableCoverageIfNeeded()
-	} else if cov, ok := mctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(mctx) {
+		return []string{"", "cov"}
+	} else if cov, ok := ctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(ctx) {
 		// Module itself doesn't have to have "cov" variant, but it should use "cov" variants of
 		// deps.
-		mctx.CreateVariations("cov")
-		mctx.AliasVariation("cov")
+		return []string{"cov"}
+	}
+
+	return []string{""}
+}
+
+func (c coverageTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
+	return sourceVariation
+}
+
+func (c coverageTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
+	if c, ok := ctx.Module().(*Module); ok && c.coverage != nil {
+		if !c.coverage.Properties.NeedCoverageVariant {
+			return ""
+		}
+	} else if cov, ok := ctx.Module().(Coverage); ok {
+		if !cov.IsNativeCoverageNeeded(ctx) {
+			return ""
+		}
+	} else if cov, ok := ctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(ctx) {
+		// Module only has a "cov" variation, so all incoming variations should use "cov".
+		return "cov"
+	} else {
+		return ""
+	}
+
+	return incomingVariation
+}
+
+func (c coverageTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
+	if c, ok := ctx.Module().(*Module); ok && c.coverage != nil {
+		if variation == "" && c.coverage.Properties.NeedCoverageVariant {
+			// Setup the non-coverage version and set HideFromMake and
+			// PreventInstall to true.
+			c.coverage.Properties.CoverageEnabled = false
+			c.coverage.Properties.IsCoverageVariant = false
+			c.Properties.HideFromMake = true
+			c.Properties.PreventInstall = true
+		} else if variation == "cov" {
+			// The coverage-enabled version inherits HideFromMake,
+			// PreventInstall from the original module.
+			c.coverage.Properties.CoverageEnabled = c.coverage.Properties.NeedCoverageBuild
+			c.coverage.Properties.IsCoverageVariant = true
+		}
+	} else if cov, ok := ctx.Module().(Coverage); ok && cov.IsNativeCoverageNeeded(ctx) {
+		// APEX and Rust modules fall here
+
+		// Note: variant "" is also created because an APEX can be depended on by another
+		// module which are split into "" and "cov" variants. e.g. when cc_test refers
+		// to an APEX via 'data' property.
+		if variation == "" {
+			cov.MarkAsCoverageVariant(false)
+			cov.SetPreventInstall()
+			cov.HideFromMake()
+		} else if variation == "cov" {
+			cov.MarkAsCoverageVariant(true)
+			cov.EnableCoverageIfNeeded()
+		}
+	} else if cov, ok := ctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(ctx) {
+		// Module itself doesn't have to have "cov" variant, but it should use "cov" variants of
+		// deps.
 	}
 }
 
diff --git a/cc/lto.go b/cc/lto.go
index 8b0880c..b2b4570 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -15,9 +15,12 @@
 package cc
 
 import (
-	"android/soong/android"
+	"fmt"
 
+	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
+
+	"android/soong/android"
 )
 
 // LTO (link-time optimization) allows the compiler to optimize and generate
@@ -49,11 +52,6 @@
 	LtoEnabled bool `blueprint:"mutated"`
 	LtoDefault 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.
-	LtoDep   bool `blueprint:"mutated"`
-	NoLtoDep bool `blueprint:"mutated"`
-
 	// Use -fwhole-program-vtables cflag.
 	Whole_program_vtables *bool
 }
@@ -176,86 +174,83 @@
 	return lto != nil && proptools.Bool(lto.Properties.Lto.Never)
 }
 
-// Propagate lto requirements down from binaries
-func ltoDepsMutator(mctx android.TopDownMutatorContext) {
-	if m, ok := mctx.Module().(*Module); ok {
-		if m.lto == nil || m.lto.Properties.LtoEnabled == m.lto.Properties.LtoDefault {
-			return
-		}
-
-		mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
-			tag := mctx.OtherModuleDependencyTag(dep)
-			libTag, isLibTag := tag.(libraryDependencyTag)
-
-			// Do not recurse down non-static dependencies
-			if isLibTag {
-				if !libTag.static() {
-					return false
-				}
-			} else {
-				if tag != objDepTag && tag != reuseObjTag {
-					return false
-				}
-			}
-
-			if dep, ok := dep.(*Module); ok {
-				if m.lto.Properties.LtoEnabled {
-					dep.lto.Properties.LtoDep = true
-				} else {
-					dep.lto.Properties.NoLtoDep = true
-				}
-			}
-
-			// Recursively walk static dependencies
-			return true
-		})
+func ltoPropagateViaDepTag(tag blueprint.DependencyTag) bool {
+	libTag, isLibTag := tag.(libraryDependencyTag)
+	// Do not recurse down non-static dependencies
+	if isLibTag {
+		return libTag.static()
+	} else {
+		return tag == objDepTag || tag == reuseObjTag || tag == staticVariantTag
 	}
 }
 
-// Create lto variants for modules that need them
-func ltoMutator(mctx android.BottomUpMutatorContext) {
-	if m, ok := mctx.Module().(*Module); ok && m.lto != nil {
-		// Create variations for LTO types required as static
-		// dependencies
-		variationNames := []string{""}
-		if m.lto.Properties.LtoDep {
-			variationNames = append(variationNames, "lto-thin")
-		}
-		if m.lto.Properties.NoLtoDep {
-			variationNames = append(variationNames, "lto-none")
+// ltoTransitionMutator creates LTO variants of cc modules.  Variant "" is the default variant, which may
+// or may not have LTO enabled depending on the config and the module's type and properties.  "lto-thin" or
+// "lto-none" variants are created when a module needs to compile in the non-default state for that module.
+type ltoTransitionMutator struct{}
+
+const LTO_NONE_VARIATION = "lto-none"
+const LTO_THIN_VARIATION = "lto-thin"
+
+func (l *ltoTransitionMutator) Split(ctx android.BaseModuleContext) []string {
+	return []string{""}
+}
+
+func (l *ltoTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
+	if m, ok := ctx.Module().(*Module); ok && m.lto != nil {
+		if !ltoPropagateViaDepTag(ctx.DepTag()) {
+			return ""
 		}
 
-		if !m.lto.Properties.LtoEnabled {
-			mctx.SetDependencyVariation("lto-none")
+		if sourceVariation != "" {
+			return sourceVariation
 		}
+
+		// Always request an explicit variation, IncomingTransition will rewrite it back to the default variation
+		// if necessary.
 		if m.lto.Properties.LtoEnabled {
-			mctx.SetDependencyVariation("lto-thin")
+			return LTO_THIN_VARIATION
+		} else {
+			return LTO_NONE_VARIATION
 		}
+	}
+	return ""
+}
 
-		if len(variationNames) > 1 {
-			modules := mctx.CreateVariations(variationNames...)
-			for i, name := range variationNames {
-				variation := modules[i].(*Module)
-				// Default module which will be
-				// installed. Variation set above according to
-				// explicit LTO properties
-				if name == "" {
-					continue
-				}
-
-				// LTO properties for dependencies
-				if name == "lto-thin" {
-					variation.lto.Properties.LtoEnabled = true
-				}
-				if name == "lto-none" {
-					variation.lto.Properties.LtoEnabled = false
-				}
-				variation.Properties.PreventInstall = true
-				variation.Properties.HideFromMake = true
-				variation.lto.Properties.LtoDefault = m.lto.Properties.LtoDefault
-				variation.lto.Properties.LtoDep = false
-				variation.lto.Properties.NoLtoDep = false
-			}
+func (l *ltoTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
+	if m, ok := ctx.Module().(*Module); ok && m.lto != nil {
+		if m.lto.Never() {
+			return ""
 		}
+		// Rewrite explicit variations back to the default variation if the default variation matches.
+		if incomingVariation == LTO_THIN_VARIATION && m.lto.Properties.LtoDefault {
+			return ""
+		} else if incomingVariation == LTO_NONE_VARIATION && !m.lto.Properties.LtoDefault {
+			return ""
+		}
+		return incomingVariation
+	}
+	return ""
+}
+
+func (l *ltoTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
+	// Default module which will be installed. Variation set above according to explicit LTO properties.
+	if variation == "" {
+		return
+	}
+
+	if m, ok := ctx.Module().(*Module); ok && m.lto != nil {
+		// Non-default variation, set the LTO properties to match the variation.
+		switch variation {
+		case LTO_THIN_VARIATION:
+			m.lto.Properties.LtoEnabled = true
+		case LTO_NONE_VARIATION:
+			m.lto.Properties.LtoEnabled = false
+		default:
+			panic(fmt.Errorf("unknown variation %s", variation))
+		}
+		// Non-default variations are never installed.
+		m.Properties.PreventInstall = true
+		m.Properties.HideFromMake = true
 	}
 }
diff --git a/cc/lto_test.go b/cc/lto_test.go
index 7b7fe8c..e4b5a3a 100644
--- a/cc/lto_test.go
+++ b/cc/lto_test.go
@@ -146,8 +146,9 @@
 		t.Errorf("'root' missing dependency on the default variant of 'foo'")
 	}
 
-	if !hasDep(result, libRootLtoNever, libFoo.Module()) {
-		t.Errorf("'root_no_lto' missing dependency on the default variant of 'foo'")
+	libFooNoLto := result.ModuleForTests("foo", "android_arm64_armv8-a_static_lto-none")
+	if !hasDep(result, libRootLtoNever, libFooNoLto.Module()) {
+		t.Errorf("'root_no_lto' missing dependency on the lto_none variant of 'foo'")
 	}
 
 	libFooCFlags := libFoo.Rule("cc").Args["cFlags"]
diff --git a/cc/makevars.go b/cc/makevars.go
index 6c3f551..70fdd57 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -123,6 +123,13 @@
 	ctx.Strict("SOONG_MODULES_USING_WNO_ERROR", makeStringOfKeys(ctx, modulesUsingWnoErrorKey))
 	ctx.Strict("SOONG_MODULES_MISSING_PGO_PROFILE_FILE", makeStringOfKeys(ctx, modulesMissingProfileFileKey))
 
+ 	ctx.Strict("CLANG_COVERAGE_CONFIG_CFLAGS", strings.Join(clangCoverageCFlags, " "))
+ 	ctx.Strict("CLANG_COVERAGE_CONFIG_COMMFLAGS", strings.Join(clangCoverageCommonFlags, " "))
+ 	ctx.Strict("CLANG_COVERAGE_HOST_LDFLAGS", strings.Join(clangCoverageHostLdFlags, " "))
+ 	ctx.Strict("CLANG_COVERAGE_INSTR_PROFILE", profileInstrFlag)
+ 	ctx.Strict("CLANG_COVERAGE_CONTINUOUS_FLAGS", strings.Join(clangContinuousCoverageFlags, " "))
+ 	ctx.Strict("CLANG_COVERAGE_HWASAN_FLAGS", strings.Join(clangCoverageHWASanFlags, " "))
+
 	ctx.Strict("ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS", strings.Join(asanCflags, " "))
 	ctx.Strict("ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS", strings.Join(asanLdflags, " "))
 
diff --git a/cc/object_test.go b/cc/object_test.go
index e6a3fdd..c0d1331 100644
--- a/cc/object_test.go
+++ b/cc/object_test.go
@@ -22,7 +22,7 @@
 )
 
 func TestMinSdkVersionsOfCrtObjects(t *testing.T) {
-	ctx := testCc(t, `
+	bp := `
 		cc_object {
 			name: "crt_foo",
 			srcs: ["foo.c"],
@@ -30,8 +30,8 @@
 			stl: "none",
 			min_sdk_version: "28",
 			vendor_available: true,
-		}`)
-
+		}
+	`
 	variants := []struct {
 		variant string
 		num     string
@@ -43,11 +43,17 @@
 		{"android_arm64_armv8-a_sdk_current", "10000"},
 		{"android_vendor.29_arm64_armv8-a", "29"},
 	}
+
+	ctx := prepareForCcTest.RunTestWithBp(t, bp)
 	for _, v := range variants {
 		cflags := ctx.ModuleForTests("crt_foo", v.variant).Rule("cc").Args["cFlags"]
 		expected := "-target aarch64-linux-android" + v.num + " "
 		android.AssertStringDoesContain(t, "cflag", cflags, expected)
 	}
+	ctx = prepareForCcTestWithoutVndk.RunTestWithBp(t, bp)
+	android.AssertStringDoesContain(t, "cflag",
+		ctx.ModuleForTests("crt_foo", "android_vendor_arm64_armv8-a").Rule("cc").Args["cFlags"],
+		"-target aarch64-linux-android10000 ")
 }
 
 func TestUseCrtObjectOfCorrectVersion(t *testing.T) {
diff --git a/cc/orderfile.go b/cc/orderfile.go
index 9192e81..38b8905 100644
--- a/cc/orderfile.go
+++ b/cc/orderfile.go
@@ -20,6 +20,8 @@
 import (
 	"fmt"
 
+	"github.com/google/blueprint"
+
 	"android/soong/android"
 )
 
@@ -190,66 +192,61 @@
 	return flags
 }
 
-// Propagate profile orderfile flags down from binaries and shared libraries
-// We do not allow propagation for load flags because the orderfile is specific
-// to the module (binary / shared library)
-func orderfileDepsMutator(mctx android.TopDownMutatorContext) {
-	if m, ok := mctx.Module().(*Module); ok {
-		if !m.orderfile.orderfileLinkEnabled() {
-			return
-		}
-		mctx.WalkDeps(func(dep android.
-			Module, parent android.Module) bool {
-			tag := mctx.OtherModuleDependencyTag(dep)
-			libTag, isLibTag := tag.(libraryDependencyTag)
-
-			// Do not recurse down non-static dependencies
-			if isLibTag {
-				if !libTag.static() {
-					return false
-				}
-			} else {
-				if tag != objDepTag && tag != reuseObjTag {
-					return false
-				}
-			}
-
-			if dep, ok := dep.(*Module); ok {
-				if m.orderfile.Properties.OrderfileInstrLink {
-					dep.orderfile.Properties.OrderfileInstrLink = true
-				}
-			}
-
-			return true
-		})
+func orderfilePropagateViaDepTag(tag blueprint.DependencyTag) bool {
+	libTag, isLibTag := tag.(libraryDependencyTag)
+	// Do not recurse down non-static dependencies
+	if isLibTag {
+		return libTag.static()
+	} else {
+		return tag == objDepTag || tag == reuseObjTag || tag == staticVariantTag
 	}
 }
 
-// Create orderfile variants for modules that need them
-func orderfileMutator(mctx android.BottomUpMutatorContext) {
-	if m, ok := mctx.Module().(*Module); ok && m.orderfile != nil {
-		if !m.static() && m.orderfile.orderfileEnabled() {
-			mctx.SetDependencyVariation("orderfile")
-			return
+// orderfileTransitionMutator creates orderfile variants of cc modules.
+type orderfileTransitionMutator struct{}
+
+const ORDERFILE_VARIATION = "orderfile"
+
+func (o *orderfileTransitionMutator) Split(ctx android.BaseModuleContext) []string {
+	return []string{""}
+}
+
+func (o *orderfileTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
+	if m, ok := ctx.Module().(*Module); ok && m.orderfile != nil {
+		if !orderfilePropagateViaDepTag(ctx.DepTag()) {
+			return ""
 		}
 
-		variationNames := []string{""}
-		if m.orderfile.Properties.OrderfileInstrLink {
-			variationNames = append(variationNames, "orderfile")
+		if sourceVariation != "" {
+			return sourceVariation
 		}
 
-		if len(variationNames) > 1 {
-			modules := mctx.CreateVariations(variationNames...)
-			for i, name := range variationNames {
-				if name == "" {
-					continue
-				}
-				variation := modules[i].(*Module)
-				variation.Properties.PreventInstall = true
-				variation.Properties.HideFromMake = true
-				variation.orderfile.Properties.ShouldProfileModule = true
-				variation.orderfile.Properties.OrderfileLoad = false
-			}
+		// Propagate profile orderfile flags down from binaries and shared libraries
+		if m.orderfile.orderfileLinkEnabled() {
+			return ORDERFILE_VARIATION
 		}
 	}
+	return ""
+}
+
+func (o *orderfileTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
+	if m, ok := ctx.Module().(*Module); ok && m.orderfile != nil {
+		return incomingVariation
+	}
+	return ""
+}
+
+func (o *orderfileTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
+	if variation == "" {
+		return
+	}
+
+	if m, ok := ctx.Module().(*Module); ok && m.orderfile != nil {
+		m.Properties.PreventInstall = true
+		m.Properties.HideFromMake = true
+		m.orderfile.Properties.ShouldProfileModule = true
+		// We do not allow propagation for load flags because the orderfile is specific
+		// to the module (binary / shared library)
+		m.orderfile.Properties.OrderfileLoad = false
+	}
 }
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index e721c53..8f4b7df 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -17,6 +17,8 @@
 import (
 	"path/filepath"
 
+	"github.com/google/blueprint/proptools"
+
 	"android/soong/android"
 )
 
@@ -36,9 +38,15 @@
 type prebuiltLinkerInterface interface {
 	Name(string) string
 	prebuilt() *android.Prebuilt
+	sourceModuleName() string
 }
 
 type prebuiltLinkerProperties struct {
+	// Name of the source soong module that gets shadowed by this prebuilt
+	// If unspecified, follows the naming convention that the source module of
+	// the prebuilt is Name() without "prebuilt_" prefix
+	Source_module_name *string
+
 	// a prebuilt library or binary. Can reference a genrule module that generates an executable file.
 	Srcs []string `android:"path,arch_variant"`
 
@@ -337,7 +345,11 @@
 }
 
 type prebuiltObjectProperties struct {
-	Srcs []string `android:"path,arch_variant"`
+	// Name of the source soong module that gets shadowed by this prebuilt
+	// If unspecified, follows the naming convention that the source module of
+	// the prebuilt is Name() without "prebuilt_" prefix
+	Source_module_name *string
+	Srcs               []string `android:"path,arch_variant"`
 }
 
 type prebuiltObjectLinker struct {
@@ -351,6 +363,10 @@
 	return &p.Prebuilt
 }
 
+func (p *prebuiltObjectLinker) sourceModuleName() string {
+	return proptools.String(p.properties.Source_module_name)
+}
+
 var _ prebuiltLinkerInterface = (*prebuiltObjectLinker)(nil)
 
 func (p *prebuiltObjectLinker) link(ctx ModuleContext,
@@ -520,3 +536,7 @@
 	}
 	return sanitized.None.Srcs
 }
+
+func (p *prebuiltLinker) sourceModuleName() string {
+	return proptools.String(p.properties.Source_module_name)
+}
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index 8b4174b..95fb7ed 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -15,6 +15,7 @@
 package cc
 
 import (
+	"fmt"
 	"runtime"
 	"testing"
 
@@ -509,3 +510,100 @@
 }`
 	testCcError(t, `Android.bp:4:6: module "bintest" variant "android_arm64_armv8-a": srcs: multiple prebuilt source files`, bp)
 }
+
+func TestMultiplePrebuilts(t *testing.T) {
+	bp := `
+		// an rdep
+		cc_library {
+			name: "libfoo",
+			shared_libs: ["libbar"],
+		}
+
+		// multiple variations of dep
+		// source
+		cc_library {
+			name: "libbar",
+		}
+		// prebuilt "v1"
+		cc_prebuilt_library_shared {
+			name: "libbar",
+			srcs: ["libbar.so"],
+		}
+		// prebuilt "v2"
+		cc_prebuilt_library_shared {
+			name: "libbar.v2",
+			stem: "libbar",
+			source_module_name: "libbar",
+			srcs: ["libbar.so"],
+		}
+
+		// selectors
+		apex_contributions {
+			name: "myapex_contributions",
+			contents: ["%v"],
+		}
+		all_apex_contributions {name: "all_apex_contributions"}
+	`
+	hasDep := func(ctx *android.TestContext, m android.Module, wantDep android.Module) bool {
+		t.Helper()
+		var found bool
+		ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
+			if dep == wantDep {
+				found = true
+			}
+		})
+		return found
+	}
+
+	testCases := []struct {
+		desc                   string
+		selectedDependencyName string
+		expectedDependencyName string
+	}{
+		{
+			desc:                   "Source library is selected using apex_contributions",
+			selectedDependencyName: "libbar",
+			expectedDependencyName: "libbar",
+		},
+		{
+			desc:                   "Prebuilt library v1 is selected using apex_contributions",
+			selectedDependencyName: "prebuilt_libbar",
+			expectedDependencyName: "prebuilt_libbar",
+		},
+		{
+			desc:                   "Prebuilt library v2 is selected using apex_contributions",
+			selectedDependencyName: "prebuilt_libbar.v2",
+			expectedDependencyName: "prebuilt_libbar.v2",
+		},
+	}
+
+	for _, tc := range testCases {
+		preparer := android.GroupFixturePreparers(
+			android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+				android.RegisterApexContributionsBuildComponents(ctx)
+			}),
+			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+				variables.BuildFlags = map[string]string{
+					"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions",
+				}
+			}),
+		)
+		ctx := testPrebuilt(t, fmt.Sprintf(bp, tc.selectedDependencyName), map[string][]byte{
+			"libbar.so": nil,
+			"crtx.o":    nil,
+		}, preparer)
+		libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
+		expectedDependency := ctx.ModuleForTests(tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module()
+		android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName), true, hasDep(ctx, libfoo, expectedDependency))
+
+		// check installation rules
+		// the selected soong module should be exported to make
+		libbar := ctx.ModuleForTests(tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module()
+		android.AssertBoolEquals(t, fmt.Sprintf("dependency %s should be exported to make\n", expectedDependency), true, !libbar.IsHideFromMake())
+
+		// check LOCAL_MODULE of the selected module name
+		// the prebuilt should have the same LOCAL_MODULE when exported to make
+		entries := android.AndroidMkEntriesForTest(t, ctx, libbar)[0]
+		android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "libbar", entries.EntryMap["LOCAL_MODULE"][0])
+	}
+}
diff --git a/cmd/pom2bp/pom2bp.go b/cmd/pom2bp/pom2bp.go
index 3fb4454..6d1caf9 100644
--- a/cmd/pom2bp/pom2bp.go
+++ b/cmd/pom2bp/pom2bp.go
@@ -651,7 +651,7 @@
         {{- end}}
     ],
     {{- end}}
-    java_version: "1.7",
+    java_version: "1.8",
 }
 `))
 
diff --git a/cmd/pom2mk/pom2mk.go b/cmd/pom2mk/pom2mk.go
index b347155..5ca770e 100644
--- a/cmd/pom2mk/pom2mk.go
+++ b/cmd/pom2mk/pom2mk.go
@@ -262,7 +262,7 @@
   {{.MkName}}-nodeps{{end}}{{range .MkAarDeps}}  \
   {{.}}{{end}}
 LOCAL_JAR_EXCLUDE_FILES := none
-LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 LOCAL_USE_AAPT2 := true
 include $(BUILD_STATIC_JAVA_LIBRARY)
 `))
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 7b207d6..2f6476c 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -512,6 +512,6 @@
 
 var _ cc.UseCoverage = (*filesystem)(nil)
 
-func (*filesystem) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
+func (*filesystem) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool {
 	return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
 }
diff --git a/genrule/allowlists.go b/genrule/allowlists.go
index 3383650..60b1366 100644
--- a/genrule/allowlists.go
+++ b/genrule/allowlists.go
@@ -15,12 +15,6 @@
 package genrule
 
 var (
-	DepfileAllowList = []string{
-		// go/keep-sorted start
-		"depfile_allowed_for_test",
-		// go/keep-sorted end
-	}
-
 	SandboxingDenyModuleList = []string{
 		// go/keep-sorted start
 		"aidl_camera_build_version",
diff --git a/genrule/genrule.go b/genrule/genrule.go
index fbda074..6f66088 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -124,14 +124,10 @@
 	//  $(locations <label>): the paths to the tools, tool_files, inputs or outputs with name <label>. Use $(locations) if <label> refers to a rule that outputs two or more files.
 	//  $(in): one or more input files.
 	//  $(out): a single output file.
-	//  $(depfile): a file to which dependencies will be written, if the depfile property is set to true.
 	//  $(genDir): the sandbox directory for this tool; contains $(out).
 	//  $$: a literal $
 	Cmd *string
 
-	// Enable reading a file containing dependencies in gcc format after the command completes
-	Depfile *bool
-
 	// name of the modules (if any) that produces the host executable.   Leave empty for
 	// prebuilts or scripts that do not need a module to build them.
 	Tools []string
@@ -194,10 +190,8 @@
 type generateTask struct {
 	in          android.Paths
 	out         android.WritablePaths
-	depFile     android.WritablePath
 	copyTo      android.WritablePaths // For gensrcs to set on gensrcsMerge rule.
 	genDir      android.WritablePath
-	extraTools  android.Paths // dependencies on tools used by the generator
 	extraInputs map[string][]string
 
 	cmd string
@@ -448,8 +442,6 @@
 			addLocationLabel(out.Rel(), outputLocation{out})
 		}
 
-		referencedDepfile := false
-
 		rawCommand, err := android.Expand(task.cmd, func(name string) (string, error) {
 			// report the error directly without returning an error to android.Expand to catch multiple errors in a
 			// single run
@@ -481,12 +473,6 @@
 					sandboxOuts = append(sandboxOuts, cmd.PathForOutput(out))
 				}
 				return strings.Join(proptools.ShellEscapeList(sandboxOuts), " "), nil
-			case "depfile":
-				referencedDepfile = true
-				if !Bool(g.properties.Depfile) {
-					return reportError("$(depfile) used without depfile property")
-				}
-				return "__SBOX_DEPFILE__", nil
 			case "genDir":
 				return proptools.ShellEscape(cmd.PathForOutput(task.genDir)), nil
 			default:
@@ -526,10 +512,6 @@
 			return
 		}
 
-		if Bool(g.properties.Depfile) && !referencedDepfile {
-			ctx.PropertyErrorf("cmd", "specified depfile=true but did not include a reference to '${depfile}' in cmd")
-			return
-		}
 		g.rawCommands = append(g.rawCommands, rawCommand)
 
 		cmd.Text(rawCommand)
@@ -538,11 +520,7 @@
 		cmd.ImplicitOutputs(task.out)
 		cmd.Implicits(task.in)
 		cmd.ImplicitTools(tools)
-		cmd.ImplicitTools(task.extraTools)
 		cmd.ImplicitPackagedTools(packagedTools)
-		if Bool(g.properties.Depfile) {
-			cmd.ImplicitDepFile(task.depFile)
-		}
 
 		// Create the rule to run the genrule command inside sbox.
 		rule.Build(name, desc)
@@ -583,19 +561,6 @@
 }
 
 func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	// Allowlist genrule to use depfile until we have a solution to remove it.
-	// TODO(b/307824623): Remove depfile property
-	if Bool(g.properties.Depfile) {
-		sandboxingAllowlistSets := getSandboxingAllowlistSets(ctx)
-		if ctx.DeviceConfig().GenruleSandboxing() && !sandboxingAllowlistSets.depfileAllowSet[g.Name()] {
-			ctx.PropertyErrorf(
-				"depfile",
-				"Deprecated because with genrule sandboxing, dependencies must be known before the action is run "+
-					"in order to add them to the sandbox. "+
-					"Please specify the dependencies explicitly so that there is no need to use depfile.")
-		}
-	}
-
 	g.generateCommonBuildActions(ctx)
 
 	// For <= 6 outputs, just embed those directly in the users. Right now, that covers >90% of
@@ -721,7 +686,6 @@
 		for i, shard := range shards {
 			var commands []string
 			var outFiles android.WritablePaths
-			var commandDepFiles []string
 			var copyTo android.WritablePaths
 
 			// When sharding is enabled (i.e. len(shards) > 1), the sbox rules for each
@@ -761,12 +725,6 @@
 						return in.String(), nil
 					case "out":
 						return rule.Command().PathForOutput(outFile), nil
-					case "depfile":
-						// Generate a depfile for each output file.  Store the list for
-						// later in order to combine them all into a single depfile.
-						depFile := rule.Command().PathForOutput(outFile.ReplaceExtension(ctx, "d"))
-						commandDepFiles = append(commandDepFiles, depFile)
-						return depFile, nil
 					default:
 						return "$(" + name + ")", nil
 					}
@@ -781,30 +739,14 @@
 			}
 			fullCommand := strings.Join(commands, " && ")
 
-			var outputDepfile android.WritablePath
-			var extraTools android.Paths
-			if len(commandDepFiles) > 0 {
-				// Each command wrote to a depfile, but ninja can only handle one
-				// depfile per rule.  Use the dep_fixer tool at the end of the
-				// command to combine all the depfiles into a single output depfile.
-				outputDepfile = android.PathForModuleGen(ctx, genSubDir, "gensrcs.d")
-				depFixerTool := ctx.Config().HostToolPath(ctx, "dep_fixer")
-				fullCommand += fmt.Sprintf(" && %s -o $(depfile) %s",
-					rule.Command().PathForTool(depFixerTool),
-					strings.Join(commandDepFiles, " "))
-				extraTools = append(extraTools, depFixerTool)
-			}
-
 			generateTasks = append(generateTasks, generateTask{
-				in:         shard,
-				out:        outFiles,
-				depFile:    outputDepfile,
-				copyTo:     copyTo,
-				genDir:     genDir,
-				cmd:        fullCommand,
-				shard:      i,
-				shards:     len(shards),
-				extraTools: extraTools,
+				in:     shard,
+				out:    outFiles,
+				copyTo: copyTo,
+				genDir: genDir,
+				cmd:    fullCommand,
+				shard:  i,
+				shards: len(shards),
 				extraInputs: map[string][]string{
 					"data": properties.Data,
 				},
@@ -843,20 +785,14 @@
 
 	taskGenerator := func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) []generateTask {
 		outs := make(android.WritablePaths, len(properties.Out))
-		var depFile android.WritablePath
 		for i, out := range properties.Out {
-			outPath := android.PathForModuleGen(ctx, out)
-			if i == 0 {
-				depFile = outPath.ReplaceExtension(ctx, "d")
-			}
-			outs[i] = outPath
+			outs[i] = android.PathForModuleGen(ctx, out)
 		}
 		return []generateTask{{
-			in:      srcFiles,
-			out:     outs,
-			depFile: depFile,
-			genDir:  android.PathForModuleGen(ctx),
-			cmd:     rawCommand,
+			in:     srcFiles,
+			out:    outs,
+			genDir: android.PathForModuleGen(ctx),
+			cmd:    rawCommand,
 		}}
 	}
 
@@ -907,22 +843,18 @@
 type sandboxingAllowlistSets struct {
 	sandboxingDenyModuleSet map[string]bool
 	sandboxingDenyPathSet   map[string]bool
-	depfileAllowSet         map[string]bool
 }
 
 func getSandboxingAllowlistSets(ctx android.PathContext) *sandboxingAllowlistSets {
 	return ctx.Config().Once(sandboxingAllowlistKey, func() interface{} {
 		sandboxingDenyModuleSet := map[string]bool{}
 		sandboxingDenyPathSet := map[string]bool{}
-		depfileAllowSet := map[string]bool{}
 
-		android.AddToStringSet(sandboxingDenyModuleSet, append(DepfileAllowList, SandboxingDenyModuleList...))
+		android.AddToStringSet(sandboxingDenyModuleSet, SandboxingDenyModuleList)
 		android.AddToStringSet(sandboxingDenyPathSet, SandboxingDenyPathList)
-		android.AddToStringSet(depfileAllowSet, DepfileAllowList)
 		return &sandboxingAllowlistSets{
 			sandboxingDenyModuleSet: sandboxingDenyModuleSet,
 			sandboxingDenyPathSet:   sandboxingDenyPathSet,
-			depfileAllowSet:         depfileAllowSet,
 		}
 	}).(*sandboxingAllowlistSets)
 }
diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go
index fa0ee17..2dc6a79 100644
--- a/genrule/genrule_test.go
+++ b/genrule/genrule_test.go
@@ -287,16 +287,6 @@
 			expect: "echo foo > __SBOX_SANDBOX_DIR__/out/out2",
 		},
 		{
-			name:       "depfile",
-			moduleName: "depfile_allowed_for_test",
-			prop: `
-				out: ["out"],
-				depfile: true,
-				cmd: "echo foo > $(out) && touch $(depfile)",
-			`,
-			expect: "echo foo > __SBOX_SANDBOX_DIR__/out/out && touch __SBOX_DEPFILE__",
-		},
-		{
 			name: "gendir",
 			prop: `
 				out: ["out"],
@@ -392,24 +382,6 @@
 			err: `unknown variable '$(foo)'`,
 		},
 		{
-			name: "error depfile",
-			prop: `
-				out: ["out"],
-				cmd: "echo foo > $(out) && touch $(depfile)",
-			`,
-			err: "$(depfile) used without depfile property",
-		},
-		{
-			name:       "error no depfile",
-			moduleName: "depfile_allowed_for_test",
-			prop: `
-				out: ["out"],
-				depfile: true,
-				cmd: "echo foo > $(out)",
-			`,
-			err: "specified depfile=true but did not include a reference to '${depfile}' in cmd",
-		},
-		{
 			name: "error no out",
 			prop: `
 				cmd: "echo foo > $(out)",
@@ -695,60 +667,6 @@
 	}
 }
 
-func TestGenruleAllowlistingDepfile(t *testing.T) {
-	tests := []struct {
-		name       string
-		prop       string
-		err        string
-		moduleName string
-	}{
-		{
-			name: `error when module is not allowlisted`,
-			prop: `
-				depfile: true,
-				cmd: "cat $(in) > $(out) && cat $(depfile)",
-			`,
-			err: "depfile: Deprecated because with genrule sandboxing, dependencies must be known before the action is run in order to add them to the sandbox",
-		},
-		{
-			name: `no error when module is allowlisted`,
-			prop: `
-				depfile: true,
-				cmd: "cat $(in) > $(out) && cat $(depfile)",
-			`,
-			moduleName: `depfile_allowed_for_test`,
-		},
-	}
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			moduleName := "foo"
-			if test.moduleName != "" {
-				moduleName = test.moduleName
-			}
-			bp := fmt.Sprintf(`
-			gensrcs {
-			   name: "%s",
-			   srcs: ["data.txt"],
-			   %s
-			}`, moduleName, test.prop)
-
-			var expectedErrors []string
-			if test.err != "" {
-				expectedErrors = append(expectedErrors, test.err)
-			}
-			android.GroupFixturePreparers(
-				prepareForGenRuleTest,
-				android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
-					variables.GenruleSandboxing = proptools.BoolPtr(true)
-				}),
-			).
-				ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(expectedErrors)).
-				RunTestWithBp(t, bp)
-		})
-
-	}
-}
-
 func TestGenruleDefaults(t *testing.T) {
 	bp := `
 				genrule_defaults {
diff --git a/java/aar.go b/java/aar.go
index b162ef6..f61fc83 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -159,8 +159,8 @@
 	}
 }
 
-func (a *aapt) useResourceProcessorBusyBox() bool {
-	return BoolDefault(a.aaptProperties.Use_resource_processor, false)
+func (a *aapt) useResourceProcessorBusyBox(ctx android.BaseModuleContext) bool {
+	return BoolDefault(a.aaptProperties.Use_resource_processor, ctx.Config().UseResourceProcessorByDefault())
 }
 
 func (a *aapt) filterProduct() string {
@@ -414,7 +414,7 @@
 		linkFlags = append(linkFlags, "--static-lib")
 	}
 
-	if a.isLibrary && a.useResourceProcessorBusyBox() {
+	if a.isLibrary && a.useResourceProcessorBusyBox(ctx) {
 		// When building an android_library using ResourceProcessorBusyBox the resources are merged into
 		// package-res.apk with --merge-only, but --no-static-lib-packages is not used so that R.txt only
 		// contains resources from this library.
@@ -453,7 +453,7 @@
 	// of transitiveStaticLibs.
 	transitiveStaticLibs := android.ReversePaths(staticDeps.resPackages())
 
-	if a.isLibrary && a.useResourceProcessorBusyBox() {
+	if a.isLibrary && a.useResourceProcessorBusyBox(ctx) {
 		// When building an android_library with ResourceProcessorBusyBox enabled treat static library dependencies
 		// as imports.  The resources from dependencies will not be merged into this module's package-res.apk, and
 		// instead modules depending on this module will reference package-res.apk from all transitive static
@@ -515,7 +515,7 @@
 		})
 	}
 
-	if !a.useResourceProcessorBusyBox() {
+	if !a.useResourceProcessorBusyBox(ctx) {
 		// the subdir "android" is required to be filtered by package names
 		srcJar = android.PathForModuleGen(ctx, "android", "R.srcjar")
 	}
@@ -542,7 +542,7 @@
 		a.assetPackage = android.OptionalPathForPath(assets)
 	}
 
-	if a.useResourceProcessorBusyBox() {
+	if a.useResourceProcessorBusyBox(ctx) {
 		rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
 		resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary, a.aaptProperties.Aaptflags)
 		aapt2ExtractExtraPackages(ctx, extraPackages, rJar)
@@ -577,7 +577,7 @@
 			rJar:                a.rJar,
 			assets:              a.assetPackage,
 
-			usedResourceProcessor: a.useResourceProcessorBusyBox(),
+			usedResourceProcessor: a.useResourceProcessorBusyBox(ctx),
 		}).
 		Transitive(staticResourcesNodesDepSet).Build()
 	a.rroDirsDepSet = android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL).
@@ -823,7 +823,7 @@
 
 	ctx.CheckbuildFile(a.aapt.proguardOptionsFile)
 	ctx.CheckbuildFile(a.aapt.exportPackage)
-	if a.useResourceProcessorBusyBox() {
+	if a.useResourceProcessorBusyBox(ctx) {
 		ctx.CheckbuildFile(a.aapt.rJar)
 	} else {
 		ctx.CheckbuildFile(a.aapt.aaptSrcJar)
@@ -849,7 +849,7 @@
 	var extraSrcJars android.Paths
 	var extraCombinedJars android.Paths
 	var extraClasspathJars android.Paths
-	if a.useResourceProcessorBusyBox() {
+	if a.useResourceProcessorBusyBox(ctx) {
 		// When building a library with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox for this
 		// library and each of the transitive static android_library dependencies has already created an
 		// R.class file for the appropriate package.  Add all of those R.class files to the classpath.
@@ -889,7 +889,7 @@
 }
 
 func (a *aapt) IDEInfo(dpInfo *android.IdeInfo) {
-	if a.useResourceProcessorBusyBox() {
+	if a.rJar != nil {
 		dpInfo.Jars = append(dpInfo.Jars, a.rJar.String())
 	}
 }
diff --git a/java/androidmk.go b/java/androidmk.go
index cc0efe9..c86dcf4 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -587,7 +587,7 @@
 		outputFile = android.OptionalPathForPath(dstubs.apiFile)
 	}
 	if !outputFile.Valid() {
-		outputFile = android.OptionalPathForPath(dstubs.apiVersionsXml)
+		outputFile = android.OptionalPathForPath(dstubs.everythingArtifacts.apiVersionsXml)
 	}
 	return []android.AndroidMkEntries{android.AndroidMkEntries{
 		Class:      "JAVA_LIBRARIES",
@@ -598,14 +598,14 @@
 				if dstubs.Javadoc.stubsSrcJar != nil {
 					entries.SetPath("LOCAL_DROIDDOC_STUBS_SRCJAR", dstubs.Javadoc.stubsSrcJar)
 				}
-				if dstubs.apiVersionsXml != nil {
-					entries.SetPath("LOCAL_DROIDDOC_API_VERSIONS_XML", dstubs.apiVersionsXml)
+				if dstubs.everythingArtifacts.apiVersionsXml != nil {
+					entries.SetPath("LOCAL_DROIDDOC_API_VERSIONS_XML", dstubs.everythingArtifacts.apiVersionsXml)
 				}
-				if dstubs.annotationsZip != nil {
-					entries.SetPath("LOCAL_DROIDDOC_ANNOTATIONS_ZIP", dstubs.annotationsZip)
+				if dstubs.everythingArtifacts.annotationsZip != nil {
+					entries.SetPath("LOCAL_DROIDDOC_ANNOTATIONS_ZIP", dstubs.everythingArtifacts.annotationsZip)
 				}
-				if dstubs.metadataZip != nil {
-					entries.SetPath("LOCAL_DROIDDOC_METADATA_ZIP", dstubs.metadataZip)
+				if dstubs.everythingArtifacts.metadataZip != nil {
+					entries.SetPath("LOCAL_DROIDDOC_METADATA_ZIP", dstubs.everythingArtifacts.metadataZip)
 				}
 			},
 		},
diff --git a/java/app.go b/java/app.go
index cb05807..0c56d81 100755
--- a/java/app.go
+++ b/java/app.go
@@ -431,7 +431,7 @@
 		return false
 	}
 
-	return shouldUncompressDex(ctx, &a.dexpreopter)
+	return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
 }
 
 func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
@@ -588,7 +588,7 @@
 		var extraSrcJars android.Paths
 		var extraClasspathJars android.Paths
 		var extraCombinedJars android.Paths
-		if a.useResourceProcessorBusyBox() {
+		if a.useResourceProcessorBusyBox(ctx) {
 			// When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
 			// created R.class files that provide IDs for resources in busybox/R.jar.  Pass that file in the
 			// classpath when compiling everything else, and add it to the final classes jar.
@@ -1108,7 +1108,7 @@
 	return Bool(a.appProperties.Privileged)
 }
 
-func (a *AndroidApp) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
+func (a *AndroidApp) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool {
 	return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
 }
 
diff --git a/java/app_import.go b/java/app_import.go
index 5f20fdd..12ead0a 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -246,7 +246,7 @@
 		return ctx.Config().UncompressPrivAppDex()
 	}
 
-	return shouldUncompressDex(ctx, &a.dexpreopter)
+	return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
 }
 
 func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -324,7 +324,7 @@
 		a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk)
 	}
 
-	a.dexpreopter.dexpreopt(ctx, jnisUncompressed)
+	a.dexpreopter.dexpreopt(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), jnisUncompressed)
 	if a.dexpreopter.uncompressedDex {
 		dexUncompressed := android.PathForModuleOut(ctx, "dex-uncompressed", ctx.ModuleName()+".apk")
 		ctx.Build(pctx, android.BuildParams{
diff --git a/java/base.go b/java/base.go
index 1ac3d30..e52cedd 100644
--- a/java/base.go
+++ b/java/base.go
@@ -1626,7 +1626,7 @@
 			j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
 
 			// Dexpreopting
-			j.dexpreopt(ctx, dexOutputFile)
+			j.dexpreopt(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), dexOutputFile)
 
 			outputFile = dexOutputFile
 		} else {
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index c89c643..2c13d99 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -949,7 +949,7 @@
 					builder.CopyToSnapshot(p, dest)
 					dests = append(dests, dest)
 				}
-				hiddenAPISet.AddProperty(category.PropertyName, dests)
+				hiddenAPISet.AddProperty(category.PropertyName(), dests)
 			}
 		}
 	}
diff --git a/java/bootclasspath_fragment_test.go b/java/bootclasspath_fragment_test.go
index 95cd4a9..8bc0a7e 100644
--- a/java/bootclasspath_fragment_test.go
+++ b/java/bootclasspath_fragment_test.go
@@ -467,10 +467,10 @@
 	android.AssertArrayString(t, "single packages", []string{"newlibrary.mine"}, info.SinglePackages)
 	for _, c := range HiddenAPIFlagFileCategories {
 		expectedMaxTargetQPaths := []string(nil)
-		if c.PropertyName == "max_target_q" {
+		if c.PropertyName() == "max_target_q" {
 			expectedMaxTargetQPaths = []string{"my-new-max-target-q.txt"}
 		}
-		android.AssertPathsRelativeToTopEquals(t, c.PropertyName, expectedMaxTargetQPaths, info.FlagFilesByCategory[c])
+		android.AssertPathsRelativeToTopEquals(t, c.PropertyName(), expectedMaxTargetQPaths, info.FlagFilesByCategory[c])
 	}
 
 	// Make sure that the signature-patterns.csv is passed all the appropriate package properties
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index bd3cce4..4c0a0a1 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -29,7 +29,7 @@
 	IsInstallable() bool
 
 	// True if dexpreopt is disabled for the java module.
-	dexpreoptDisabled(ctx android.BaseModuleContext) bool
+	dexpreoptDisabled(ctx android.BaseModuleContext, libraryName string) bool
 
 	// If the java module is to be installed into an APEX, this list contains information about the
 	// dexpreopt outputs to be installed on devices. Note that these dexpreopt outputs are installed
@@ -182,15 +182,9 @@
 	return apexInfo.ForPrebuiltApex
 }
 
-func moduleName(ctx android.BaseModuleContext) string {
-	// Remove the "prebuilt_" prefix if the module is from a prebuilt because the prefix is not
-	// expected by dexpreopter.
-	return android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName())
-}
-
 // Returns whether dexpreopt is applicable to the module.
 // When it returns true, neither profile nor dexpreopt artifacts will be generated.
-func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool {
+func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext, libName string) bool {
 	if !ctx.Device() {
 		return true
 	}
@@ -213,11 +207,20 @@
 		return true
 	}
 
+	if _, isApex := android.ModuleProvider(ctx, android.ApexBundleInfoProvider); isApex {
+		// dexpreopt rules for system server jars can be generated in the ModuleCtx of prebuilt apexes
+		return false
+	}
+
 	global := dexpreopt.GetGlobalConfig(ctx)
 
-	isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx))
-	if isApexVariant(ctx) {
-		// Don't preopt APEX variant module unless the module is an APEX system server jar.
+	// Use the libName argument to determine if the library being dexpreopt'd is a system server jar
+	// ctx.ModuleName() is not safe. In case of prebuilt apexes, the dexpreopt rules of system server jars
+	// are created in the ctx object of the top-level prebuilt apex.
+	isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(libName)
+
+	if _, isApex := android.ModuleProvider(ctx, android.ApexBundleInfoProvider); isApex || isApexVariant(ctx) {
+		// dexpreopt rules for system server jars can be generated in the ModuleCtx of prebuilt apexes
 		if !isApexSystemServerJar {
 			return true
 		}
@@ -234,14 +237,20 @@
 }
 
 func dexpreoptToolDepsMutator(ctx android.BottomUpMutatorContext) {
-	if d, ok := ctx.Module().(DexpreopterInterface); !ok || d.dexpreoptDisabled(ctx) || !dexpreopt.IsDex2oatNeeded(ctx) {
+	if _, isApex := android.ModuleProvider(ctx, android.ApexBundleInfoProvider); isApex && dexpreopt.IsDex2oatNeeded(ctx) {
+		// prebuilt apexes can genererate rules to dexpreopt deapexed jars
+		// Add a dex2oat dep aggressively on _every_ apex module
+		dexpreopt.RegisterToolDeps(ctx)
+		return
+	}
+	if d, ok := ctx.Module().(DexpreopterInterface); !ok || d.dexpreoptDisabled(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName())) || !dexpreopt.IsDex2oatNeeded(ctx) {
 		return
 	}
 	dexpreopt.RegisterToolDeps(ctx)
 }
 
-func (d *dexpreopter) odexOnSystemOther(ctx android.ModuleContext, installPath android.InstallPath) bool {
-	return dexpreopt.OdexOnSystemOtherByName(moduleName(ctx), android.InstallPathToOnDevicePath(ctx, installPath), dexpreopt.GetGlobalConfig(ctx))
+func (d *dexpreopter) odexOnSystemOther(ctx android.ModuleContext, libName string, installPath android.InstallPath) bool {
+	return dexpreopt.OdexOnSystemOtherByName(libName, android.InstallPathToOnDevicePath(ctx, installPath), dexpreopt.GetGlobalConfig(ctx))
 }
 
 // Returns the install path of the dex jar of a module.
@@ -252,13 +261,13 @@
 // This function is on a best-effort basis. It cannot handle the case where an APEX jar is not a
 // system server jar, which is fine because we currently only preopt system server jars for APEXes.
 func (d *dexpreopter) getInstallPath(
-	ctx android.ModuleContext, defaultInstallPath android.InstallPath) android.InstallPath {
+	ctx android.ModuleContext, libName string, defaultInstallPath android.InstallPath) android.InstallPath {
 	global := dexpreopt.GetGlobalConfig(ctx)
-	if global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx)) {
-		dexLocation := dexpreopt.GetSystemServerDexLocation(ctx, global, moduleName(ctx))
+	if global.AllApexSystemServerJars(ctx).ContainsJar(libName) {
+		dexLocation := dexpreopt.GetSystemServerDexLocation(ctx, global, libName)
 		return android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexLocation, "/"))
 	}
-	if !d.dexpreoptDisabled(ctx) && isApexVariant(ctx) &&
+	if !d.dexpreoptDisabled(ctx, libName) && isApexVariant(ctx) &&
 		filepath.Base(defaultInstallPath.PartitionDir()) != "apex" {
 		ctx.ModuleErrorf("unable to get the install path of the dex jar for dexpreopt")
 	}
@@ -273,10 +282,10 @@
 	d.installPath = android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexpreopt.GetSystemServerDexLocation(ctx, dc, libraryName), "/"))
 	// generate the rules for creating the .odex and .vdex files for this system server jar
 	dexJarFile := di.PrebuiltExportPath(ApexRootRelativePathToJavaLib(libraryName))
-	d.dexpreopt(ctx, dexJarFile)
+	d.dexpreopt(ctx, libraryName, dexJarFile)
 }
 
-func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.WritablePath) {
+func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, libName string, dexJarFile android.WritablePath) {
 	global := dexpreopt.GetGlobalConfig(ctx)
 
 	// TODO(b/148690468): The check on d.installPath is to bail out in cases where
@@ -289,7 +298,7 @@
 
 	dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath)
 
-	providesUsesLib := moduleName(ctx)
+	providesUsesLib := libName
 	if ulib, ok := ctx.Module().(ProvidesUsesLib); ok {
 		name := ulib.ProvidesUsesLib()
 		if name != nil {
@@ -299,11 +308,11 @@
 
 	// If it is test, make config files regardless of its dexpreopt setting.
 	// The config files are required for apps defined in make which depend on the lib.
-	if d.isTest && d.dexpreoptDisabled(ctx) {
+	if d.isTest && d.dexpreoptDisabled(ctx, libName) {
 		return
 	}
 
-	isSystemServerJar := global.AllSystemServerJars(ctx).ContainsJar(moduleName(ctx))
+	isSystemServerJar := global.AllSystemServerJars(ctx).ContainsJar(libName)
 
 	bootImage := defaultBootImageConfig(ctx)
 	// When `global.PreoptWithUpdatableBcp` is true, `bcpForDexpreopt` below includes the mainline
@@ -322,7 +331,7 @@
 				targets = append(targets, target)
 			}
 		}
-		if isSystemServerJar && moduleName(ctx) != "com.android.location.provider" {
+		if isSystemServerJar && libName != "com.android.location.provider" {
 			// If the module is a system server jar, only preopt for the primary arch because the jar can
 			// only be loaded by system server. "com.android.location.provider" is a special case because
 			// it's also used by apps as a shared library.
@@ -358,7 +367,7 @@
 			profileIsTextListing = true
 		} else if global.ProfileDir != "" {
 			profileClassListing = android.ExistentPathForSource(ctx,
-				global.ProfileDir, moduleName(ctx)+".prof")
+				global.ProfileDir, libName+".prof")
 		}
 	}
 
@@ -370,9 +379,9 @@
 
 	// Full dexpreopt config, used to create dexpreopt build rules.
 	dexpreoptConfig := &dexpreopt.ModuleConfig{
-		Name:            moduleName(ctx),
+		Name:            libName,
 		DexLocation:     dexLocation,
-		BuildPath:       android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, moduleName(ctx)+".jar").OutputPath,
+		BuildPath:       android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, libName+".jar").OutputPath,
 		DexPath:         dexJarFile,
 		ManifestPath:    android.OptionalPathForPath(d.manifestFile),
 		UncompressedDex: d.uncompressedDex,
@@ -405,7 +414,7 @@
 	d.configPath = android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, "dexpreopt.config")
 	dexpreopt.WriteModuleConfig(ctx, dexpreoptConfig, d.configPath)
 
-	if d.dexpreoptDisabled(ctx) {
+	if d.dexpreoptDisabled(ctx, libName) {
 		return
 	}
 
@@ -476,7 +485,7 @@
 				// The installs will be handled by Make as sub-modules of the java library.
 				d.builtInstalledForApex = append(d.builtInstalledForApex, dexpreopterInstall{
 					name:                arch + "-" + installBase,
-					moduleName:          dexJarStem,
+					moduleName:          libName,
 					outputPathOnHost:    install.From,
 					installDirOnDevice:  installPath,
 					installFileOnDevice: installBase,
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 7a61034..cfbf2b4 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -182,6 +182,17 @@
 
 func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
 	if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
+		if ctx.Config().BuildFromTextStub() {
+			ctx.ModuleErrorf("Generating stubs from api signature files is not available " +
+				"with WITHOUT_CHECK_API=true, as sync between the source Java files and the " +
+				"api signature files is not guaranteed.\n" +
+				"In order to utilize WITHOUT_CHECK_API, generate stubs from the source Java " +
+				"files with BUILD_FROM_SOURCE_STUB=true.\n" +
+				"However, the usage of WITHOUT_CHECK_API is not preferred as the incremental " +
+				"build is slower when generating stubs from the source Java files.\n" +
+				"Consider updating the api signature files and generating the stubs from " +
+				"them instead.")
+		}
 		return false
 	} else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
 		return true
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 0626313..6ef2afe 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -65,15 +65,22 @@
 	ctx.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
 }
 
+type stubsArtifacts struct {
+	nullabilityWarningsFile android.WritablePath
+	annotationsZip          android.WritablePath
+	apiVersionsXml          android.WritablePath
+	metadataZip             android.WritablePath
+	metadataDir             android.WritablePath
+}
+
 // Droidstubs
 type Droidstubs struct {
 	Javadoc
 	embeddableInModuleAndImport
 
-	properties              DroidstubsProperties
-	apiFile                 android.Path
-	removedApiFile          android.Path
-	nullabilityWarningsFile android.WritablePath
+	properties     DroidstubsProperties
+	apiFile        android.Path
+	removedApiFile android.Path
 
 	checkCurrentApiTimestamp      android.WritablePath
 	updateCurrentApiTimestamp     android.WritablePath
@@ -83,22 +90,14 @@
 
 	checkNullabilityWarningsTimestamp android.WritablePath
 
-	annotationsZip android.WritablePath
-	apiVersionsXml android.WritablePath
-
-	metadataZip android.WritablePath
-	metadataDir android.WritablePath
+	everythingArtifacts stubsArtifacts
+	exportableArtifacts stubsArtifacts
 
 	// Single aconfig "cache file" merged from this module and all dependencies.
 	mergedAconfigFiles map[string]android.Paths
 
-	exportableApiFile                 android.WritablePath
-	exportableRemovedApiFile          android.WritablePath
-	exportableNullabilityWarningsFile android.WritablePath
-	exportableAnnotationsZip          android.WritablePath
-	exportableApiVersionsXml          android.WritablePath
-	exportableMetadataZip             android.WritablePath
-	exportableMetadataDir             android.WritablePath
+	exportableApiFile        android.WritablePath
+	exportableRemovedApiFile android.WritablePath
 }
 
 type DroidstubsProperties struct {
@@ -192,34 +191,22 @@
 
 // Used by xsd_config
 type ApiFilePath interface {
-	ApiFilePath() android.Path
+	ApiFilePath(StubsType) (android.Path, error)
 }
 
 type ApiStubsSrcProvider interface {
-	StubsSrcJar() android.Path
-}
-
-type ExportableApiStubsSrcProvider interface {
-	ExportableStubsSrcJar() android.Path
+	StubsSrcJar(StubsType) (android.Path, error)
 }
 
 // Provider of information about API stubs, used by java_sdk_library.
 type ApiStubsProvider interface {
-	AnnotationsZip() android.Path
+	AnnotationsZip(StubsType) (android.Path, error)
 	ApiFilePath
-	RemovedApiFilePath() android.Path
+	RemovedApiFilePath(StubsType) (android.Path, error)
 
 	ApiStubsSrcProvider
 }
 
-type ExportableApiStubsProvider interface {
-	ExportableAnnotationsZip() android.Path
-	ExportableApiFilePath() android.Path
-	ExportableRemovedApiFilePath() android.Path
-
-	ExportableApiStubsSrcProvider
-}
-
 type currentApiTimestampProvider interface {
 	CurrentApiTimestamp() android.Path
 }
@@ -323,112 +310,86 @@
 	}
 	switch prefixRemovedTag {
 	case "":
-		return d.StubsSrcJarWithStubsType(stubsType)
+		stubsSrcJar, err := d.StubsSrcJar(stubsType)
+		return android.Paths{stubsSrcJar}, err
 	case ".docs.zip":
-		return d.DocZipWithStubsType(stubsType)
+		docZip, err := d.DocZip(stubsType)
+		return android.Paths{docZip}, err
 	case ".api.txt", android.DefaultDistTag:
 		// This is the default dist path for dist properties that have no tag property.
-		return d.ApiFilePathWithStubsType(stubsType)
+		apiFilePath, err := d.ApiFilePath(stubsType)
+		return android.Paths{apiFilePath}, err
 	case ".removed-api.txt":
-		return d.RemovedApiFilePathWithStubsType(stubsType)
+		removedApiFilePath, err := d.RemovedApiFilePath(stubsType)
+		return android.Paths{removedApiFilePath}, err
 	case ".annotations.zip":
-		return d.AnnotationsZipWithStubsType(stubsType)
+		annotationsZip, err := d.AnnotationsZip(stubsType)
+		return android.Paths{annotationsZip}, err
 	case ".api_versions.xml":
-		return d.ApiVersionsXmlFilePathWithStubsType(stubsType)
+		apiVersionsXmlFilePath, err := d.ApiVersionsXmlFilePath(stubsType)
+		return android.Paths{apiVersionsXmlFilePath}, err
 	default:
 		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
 	}
 }
 
-func (d *Droidstubs) AnnotationsZip() android.Path {
-	return d.annotationsZip
-}
-
-func (d *Droidstubs) ExportableAnnotationsZip() android.Path {
-	return d.exportableAnnotationsZip
-}
-
-func (d *Droidstubs) AnnotationsZipWithStubsType(stubsType StubsType) (android.Paths, error) {
+func (d *Droidstubs) AnnotationsZip(stubsType StubsType) (android.Path, error) {
 	switch stubsType {
 	case Everything:
-		return android.Paths{d.AnnotationsZip()}, nil
+		return d.everythingArtifacts.annotationsZip, nil
 	case Exportable:
-		return android.Paths{d.ExportableAnnotationsZip()}, nil
+		return d.exportableArtifacts.annotationsZip, nil
 	default:
 		return nil, fmt.Errorf("annotations zip not supported for the stub type %s", stubsType.String())
 	}
 }
 
-func (d *Droidstubs) ApiFilePath() android.Path {
-	return d.apiFile
-}
-
-func (d *Droidstubs) ExportableApiFilePath() android.Path {
-	return d.exportableApiFile
-}
-
-func (d *Droidstubs) ApiFilePathWithStubsType(stubsType StubsType) (android.Paths, error) {
+func (d *Droidstubs) ApiFilePath(stubsType StubsType) (android.Path, error) {
 	switch stubsType {
 	case Everything:
-		return android.Paths{d.ApiFilePath()}, nil
+		return d.apiFile, nil
 	case Exportable:
-		return android.Paths{d.ExportableApiFilePath()}, nil
+		return d.exportableApiFile, nil
 	default:
 		return nil, fmt.Errorf("api file path not supported for the stub type %s", stubsType.String())
 	}
 }
 
-func (d *Droidstubs) ApiVersionsXmlFilePathWithStubsType(stubsType StubsType) (android.Paths, error) {
+func (d *Droidstubs) ApiVersionsXmlFilePath(stubsType StubsType) (android.Path, error) {
 	switch stubsType {
 	case Everything:
-		return android.Paths{d.apiVersionsXml}, nil
+		return d.everythingArtifacts.apiVersionsXml, nil
 	default:
 		return nil, fmt.Errorf("api versions xml file path not supported for the stub type %s", stubsType.String())
 	}
 }
 
-func (d *Droidstubs) DocZipWithStubsType(stubsType StubsType) (android.Paths, error) {
+func (d *Droidstubs) DocZip(stubsType StubsType) (android.Path, error) {
 	switch stubsType {
 	case Everything:
-		return android.Paths{d.docZip}, nil
+		return d.docZip, nil
 	default:
 		return nil, fmt.Errorf("docs zip not supported for the stub type %s", stubsType.String())
 	}
 }
 
-func (d *Droidstubs) RemovedApiFilePath() android.Path {
-	return d.removedApiFile
-}
-
-func (d *Droidstubs) ExportableRemovedApiFilePath() android.Path {
-	return d.exportableRemovedApiFile
-}
-
-func (d *Droidstubs) RemovedApiFilePathWithStubsType(stubsType StubsType) (android.Paths, error) {
+func (d *Droidstubs) RemovedApiFilePath(stubsType StubsType) (android.Path, error) {
 	switch stubsType {
 	case Everything:
-		return android.Paths{d.RemovedApiFilePath()}, nil
+		return d.removedApiFile, nil
 	case Exportable:
-		return android.Paths{d.ExportableRemovedApiFilePath()}, nil
+		return d.exportableRemovedApiFile, nil
 	default:
 		return nil, fmt.Errorf("removed api file path not supported for the stub type %s", stubsType.String())
 	}
 }
 
-func (d *Droidstubs) StubsSrcJar() android.Path {
-	return d.stubsSrcJar
-}
-
-func (d *Droidstubs) ExportableStubsSrcJar() android.Path {
-	return d.exportableStubsSrcJar
-}
-
-func (d *Droidstubs) StubsSrcJarWithStubsType(stubsType StubsType) (android.Paths, error) {
+func (d *Droidstubs) StubsSrcJar(stubsType StubsType) (android.Path, error) {
 	switch stubsType {
 	case Everything:
-		return android.Paths{d.StubsSrcJar()}, nil
+		return d.stubsSrcJar, nil
 	case Exportable:
-		return android.Paths{d.ExportableStubsSrcJar()}, nil
+		return d.exportableStubsSrcJar, nil
 	default:
 		return nil, fmt.Errorf("stubs srcjar not supported for the stub type %s", stubsType.String())
 	}
@@ -576,11 +537,11 @@
 	var apiVersions android.Path
 	if proptools.Bool(d.properties.Api_levels_annotations_enabled) {
 		d.apiLevelsGenerationFlags(ctx, cmd, stubsType, apiVersionsXml)
-		apiVersions = d.apiVersionsXml
+		apiVersions = d.everythingArtifacts.apiVersionsXml
 	} else {
 		ctx.VisitDirectDepsWithTag(metalavaAPILevelsModuleTag, func(m android.Module) {
 			if s, ok := m.(*Droidstubs); ok {
-				apiVersions = s.apiVersionsXml
+				apiVersions = s.everythingArtifacts.apiVersionsXml
 			} else {
 				ctx.PropertyErrorf("api_levels_module",
 					"module %q is not a droidstubs module", ctx.OtherModuleName(m))
@@ -839,28 +800,28 @@
 	}
 
 	if params.writeSdkValues {
-		d.metadataDir = android.PathForModuleOut(ctx, Everything.String(), "metadata")
-		d.metadataZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-metadata.zip")
+		d.everythingArtifacts.metadataDir = android.PathForModuleOut(ctx, Everything.String(), "metadata")
+		d.everythingArtifacts.metadataZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-metadata.zip")
 	}
 
 	if Bool(d.properties.Annotations_enabled) {
 		if params.validatingNullability {
-			d.nullabilityWarningsFile = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_nullability_warnings.txt")
+			d.everythingArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_nullability_warnings.txt")
 		}
-		d.annotationsZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_annotations.zip")
+		d.everythingArtifacts.annotationsZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_annotations.zip")
 	}
 	if Bool(d.properties.Api_levels_annotations_enabled) {
-		d.apiVersionsXml = android.PathForModuleOut(ctx, Everything.String(), "api-versions.xml")
+		d.everythingArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, Everything.String(), "api-versions.xml")
 	}
 
 	commonCmdParams := stubsCommandParams{
 		srcJarDir:               srcJarDir,
 		stubsDir:                stubsDir,
 		stubsSrcJar:             d.Javadoc.stubsSrcJar,
-		metadataDir:             d.metadataDir,
-		apiVersionsXml:          d.apiVersionsXml,
-		nullabilityWarningsFile: d.nullabilityWarningsFile,
-		annotationsZip:          d.annotationsZip,
+		metadataDir:             d.everythingArtifacts.metadataDir,
+		apiVersionsXml:          d.everythingArtifacts.apiVersionsXml,
+		nullabilityWarningsFile: d.everythingArtifacts.nullabilityWarningsFile,
+		annotationsZip:          d.everythingArtifacts.annotationsZip,
 		stubConfig:              params,
 	}
 
@@ -883,9 +844,9 @@
 			BuiltTool("soong_zip").
 			Flag("-write_if_changed").
 			Flag("-d").
-			FlagWithOutput("-o ", d.metadataZip).
-			FlagWithArg("-C ", d.metadataDir.String()).
-			FlagWithArg("-D ", d.metadataDir.String())
+			FlagWithOutput("-o ", d.everythingArtifacts.metadataZip).
+			FlagWithArg("-C ", d.everythingArtifacts.metadataDir.String()).
+			FlagWithArg("-D ", d.everythingArtifacts.metadataDir.String())
 	}
 
 	// TODO: We don't really need two separate API files, but this is a reminiscence of how
@@ -1018,23 +979,23 @@
 	d.Javadoc.exportableStubsSrcJar = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
 	optionalCmdParams.stubsSrcJar = d.Javadoc.exportableStubsSrcJar
 	if params.writeSdkValues {
-		d.exportableMetadataZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-metadata.zip")
-		d.exportableMetadataDir = android.PathForModuleOut(ctx, params.stubsType.String(), "metadata")
-		optionalCmdParams.metadataZip = d.exportableMetadataZip
-		optionalCmdParams.metadataDir = d.exportableMetadataDir
+		d.exportableArtifacts.metadataZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-metadata.zip")
+		d.exportableArtifacts.metadataDir = android.PathForModuleOut(ctx, params.stubsType.String(), "metadata")
+		optionalCmdParams.metadataZip = d.exportableArtifacts.metadataZip
+		optionalCmdParams.metadataDir = d.exportableArtifacts.metadataDir
 	}
 
 	if Bool(d.properties.Annotations_enabled) {
 		if params.validatingNullability {
-			d.exportableNullabilityWarningsFile = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_nullability_warnings.txt")
-			optionalCmdParams.nullabilityWarningsFile = d.exportableNullabilityWarningsFile
+			d.exportableArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_nullability_warnings.txt")
+			optionalCmdParams.nullabilityWarningsFile = d.exportableArtifacts.nullabilityWarningsFile
 		}
-		d.exportableAnnotationsZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_annotations.zip")
-		optionalCmdParams.annotationsZip = d.exportableAnnotationsZip
+		d.exportableArtifacts.annotationsZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_annotations.zip")
+		optionalCmdParams.annotationsZip = d.exportableArtifacts.annotationsZip
 	}
 	if Bool(d.properties.Api_levels_annotations_enabled) {
-		d.exportableApiVersionsXml = android.PathForModuleOut(ctx, params.stubsType.String(), "api-versions.xml")
-		optionalCmdParams.apiVersionsXml = d.exportableApiVersionsXml
+		d.exportableArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, params.stubsType.String(), "api-versions.xml")
+		optionalCmdParams.apiVersionsXml = d.exportableArtifacts.apiVersionsXml
 	}
 
 	if params.checkApi || String(d.properties.Api_filename) != "" {
@@ -1194,7 +1155,8 @@
 			`either of the two choices above and try re-building the target.\n`+
 			`If the mismatch between the stubs and the current.txt is intended,\n`+
 			`you can try re-building the target by executing the following command:\n`+
-			`m DISABLE_STUB_VALIDATION=true <your build target>\n`+
+			`m DISABLE_STUB_VALIDATION=true <your build target>.\n`+
+			`Note that DISABLE_STUB_VALIDATION=true does not bypass checkapi.\n`+
 			`******************************\n`, ctx.ModuleName())
 
 		rule.Command().
@@ -1234,7 +1196,7 @@
 	}
 
 	if String(d.properties.Check_nullability_warnings) != "" {
-		if d.nullabilityWarningsFile == nil {
+		if d.everythingArtifacts.nullabilityWarningsFile == nil {
 			ctx.PropertyErrorf("check_nullability_warnings",
 				"Cannot specify check_nullability_warnings unless validating nullability")
 		}
@@ -1251,13 +1213,13 @@
 			`   2. Update the file of expected warnings by running:\n`+
 			`         cp %s %s\n`+
 			`       and submitting the updated file as part of your change.`,
-			d.nullabilityWarningsFile, checkNullabilityWarnings)
+			d.everythingArtifacts.nullabilityWarningsFile, checkNullabilityWarnings)
 
 		rule := android.NewRuleBuilder(pctx, ctx)
 
 		rule.Command().
 			Text("(").
-			Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
+			Text("diff").Input(checkNullabilityWarnings).Input(d.everythingArtifacts.nullabilityWarningsFile).
 			Text("&&").
 			Text("touch").Output(d.checkNullabilityWarningsTimestamp).
 			Text(") || (").
@@ -1351,8 +1313,8 @@
 	}
 }
 
-func (d *PrebuiltStubsSources) StubsSrcJar() android.Path {
-	return d.stubsSrcJar
+func (d *PrebuiltStubsSources) StubsSrcJar(_ StubsType) (android.Path, error) {
+	return d.stubsSrcJar, nil
 }
 
 func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index 3c7cf3a..e4beb5e 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -435,122 +435,118 @@
 	}
 }
 
-type hiddenAPIFlagFileCategory struct {
-	// PropertyName is the name of the property for this category.
-	PropertyName string
+type hiddenAPIFlagFileCategory int
 
-	// propertyValueReader retrieves the value of the property for this category from the set of
-	// properties.
-	propertyValueReader func(properties *HiddenAPIFlagFileProperties) []string
+const (
+	// The flag file category for removed members of the API.
+	//
+	// This is extracted from HiddenAPIFlagFileCategories as it is needed to add the dex signatures
+	// list of removed API members that are generated automatically from the removed.txt files provided
+	// by API stubs.
+	hiddenAPIFlagFileCategoryRemoved hiddenAPIFlagFileCategory = iota
+	hiddenAPIFlagFileCategoryUnsupported
+	hiddenAPIFlagFileCategoryMaxTargetRLowPriority
+	hiddenAPIFlagFileCategoryMaxTargetQ
+	hiddenAPIFlagFileCategoryMaxTargetP
+	hiddenAPIFlagFileCategoryMaxTargetOLowPriority
+	hiddenAPIFlagFileCategoryBlocked
+	hiddenAPIFlagFileCategoryUnsupportedPackages
+)
 
-	// commandMutator adds the appropriate command line options for this category to the supplied
-	// command
-	commandMutator func(command *android.RuleBuilderCommand, path android.Path)
-}
-
-// The flag file category for removed members of the API.
-//
-// This is extracted from HiddenAPIFlagFileCategories as it is needed to add the dex signatures
-// list of removed API members that are generated automatically from the removed.txt files provided
-// by API stubs.
-var hiddenAPIRemovedFlagFileCategory = &hiddenAPIFlagFileCategory{
-	// See HiddenAPIFlagFileProperties.Removed
-	PropertyName: "removed",
-	propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
-		return properties.Hidden_api.Removed
-	},
-	commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
-		command.FlagWithInput("--unsupported ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "removed")
-	},
-}
-
-type hiddenAPIFlagFileCategories []*hiddenAPIFlagFileCategory
-
-func (c hiddenAPIFlagFileCategories) byProperty(name string) *hiddenAPIFlagFileCategory {
-	for _, category := range c {
-		if category.PropertyName == name {
-			return category
-		}
+func (c hiddenAPIFlagFileCategory) PropertyName() string {
+	switch c {
+	case hiddenAPIFlagFileCategoryRemoved:
+		return "removed"
+	case hiddenAPIFlagFileCategoryUnsupported:
+		return "unsupported"
+	case hiddenAPIFlagFileCategoryMaxTargetRLowPriority:
+		return "max_target_r_low_priority"
+	case hiddenAPIFlagFileCategoryMaxTargetQ:
+		return "max_target_q"
+	case hiddenAPIFlagFileCategoryMaxTargetP:
+		return "max_target_p"
+	case hiddenAPIFlagFileCategoryMaxTargetOLowPriority:
+		return "max_target_o_low_priority"
+	case hiddenAPIFlagFileCategoryBlocked:
+		return "blocked"
+	case hiddenAPIFlagFileCategoryUnsupportedPackages:
+		return "unsupported_packages"
+	default:
+		panic(fmt.Sprintf("Unknown hidden api flag file category type: %d", c))
 	}
-	panic(fmt.Errorf("no category exists with property name %q in %v", name, c))
 }
 
+// propertyValueReader retrieves the value of the property for this category from the set of properties.
+func (c hiddenAPIFlagFileCategory) propertyValueReader(properties *HiddenAPIFlagFileProperties) []string {
+	switch c {
+	case hiddenAPIFlagFileCategoryRemoved:
+		return properties.Hidden_api.Removed
+	case hiddenAPIFlagFileCategoryUnsupported:
+		return properties.Hidden_api.Unsupported
+	case hiddenAPIFlagFileCategoryMaxTargetRLowPriority:
+		return properties.Hidden_api.Max_target_r_low_priority
+	case hiddenAPIFlagFileCategoryMaxTargetQ:
+		return properties.Hidden_api.Max_target_q
+	case hiddenAPIFlagFileCategoryMaxTargetP:
+		return properties.Hidden_api.Max_target_p
+	case hiddenAPIFlagFileCategoryMaxTargetOLowPriority:
+		return properties.Hidden_api.Max_target_o_low_priority
+	case hiddenAPIFlagFileCategoryBlocked:
+		return properties.Hidden_api.Blocked
+	case hiddenAPIFlagFileCategoryUnsupportedPackages:
+		return properties.Hidden_api.Unsupported_packages
+	default:
+		panic(fmt.Sprintf("Unknown hidden api flag file category type: %d", c))
+	}
+}
+
+// commandMutator adds the appropriate command line options for this category to the supplied command
+func (c hiddenAPIFlagFileCategory) commandMutator(command *android.RuleBuilderCommand, path android.Path) {
+	switch c {
+	case hiddenAPIFlagFileCategoryRemoved:
+		command.FlagWithInput("--unsupported ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "removed")
+	case hiddenAPIFlagFileCategoryUnsupported:
+		command.FlagWithInput("--unsupported ", path)
+	case hiddenAPIFlagFileCategoryMaxTargetRLowPriority:
+		command.FlagWithInput("--max-target-r ", path).FlagWithArg("--tag ", "lo-prio")
+	case hiddenAPIFlagFileCategoryMaxTargetQ:
+		command.FlagWithInput("--max-target-q ", path)
+	case hiddenAPIFlagFileCategoryMaxTargetP:
+		command.FlagWithInput("--max-target-p ", path)
+	case hiddenAPIFlagFileCategoryMaxTargetOLowPriority:
+		command.FlagWithInput("--max-target-o ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "lo-prio")
+	case hiddenAPIFlagFileCategoryBlocked:
+		command.FlagWithInput("--blocked ", path)
+	case hiddenAPIFlagFileCategoryUnsupportedPackages:
+		command.FlagWithInput("--unsupported ", path).Flag("--packages ")
+	default:
+		panic(fmt.Sprintf("Unknown hidden api flag file category type: %d", c))
+	}
+}
+
+type hiddenAPIFlagFileCategories []hiddenAPIFlagFileCategory
+
 var HiddenAPIFlagFileCategories = hiddenAPIFlagFileCategories{
 	// See HiddenAPIFlagFileProperties.Unsupported
-	{
-		PropertyName: "unsupported",
-		propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
-			return properties.Hidden_api.Unsupported
-		},
-		commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
-			command.FlagWithInput("--unsupported ", path)
-		},
-	},
-	hiddenAPIRemovedFlagFileCategory,
+	hiddenAPIFlagFileCategoryUnsupported,
+	// See HiddenAPIFlagFileProperties.Removed
+	hiddenAPIFlagFileCategoryRemoved,
 	// See HiddenAPIFlagFileProperties.Max_target_r_low_priority
-	{
-		PropertyName: "max_target_r_low_priority",
-		propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
-			return properties.Hidden_api.Max_target_r_low_priority
-		},
-		commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
-			command.FlagWithInput("--max-target-r ", path).FlagWithArg("--tag ", "lo-prio")
-		},
-	},
+	hiddenAPIFlagFileCategoryMaxTargetRLowPriority,
 	// See HiddenAPIFlagFileProperties.Max_target_q
-	{
-		PropertyName: "max_target_q",
-		propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
-			return properties.Hidden_api.Max_target_q
-		},
-		commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
-			command.FlagWithInput("--max-target-q ", path)
-		},
-	},
+	hiddenAPIFlagFileCategoryMaxTargetQ,
 	// See HiddenAPIFlagFileProperties.Max_target_p
-	{
-		PropertyName: "max_target_p",
-		propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
-			return properties.Hidden_api.Max_target_p
-		},
-		commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
-			command.FlagWithInput("--max-target-p ", path)
-		},
-	},
+	hiddenAPIFlagFileCategoryMaxTargetP,
 	// See HiddenAPIFlagFileProperties.Max_target_o_low_priority
-	{
-		PropertyName: "max_target_o_low_priority",
-		propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
-			return properties.Hidden_api.Max_target_o_low_priority
-		},
-		commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
-			command.FlagWithInput("--max-target-o ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "lo-prio")
-		},
-	},
+	hiddenAPIFlagFileCategoryMaxTargetOLowPriority,
 	// See HiddenAPIFlagFileProperties.Blocked
-	{
-		PropertyName: "blocked",
-		propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
-			return properties.Hidden_api.Blocked
-		},
-		commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
-			command.FlagWithInput("--blocked ", path)
-		},
-	},
+	hiddenAPIFlagFileCategoryBlocked,
 	// See HiddenAPIFlagFileProperties.Unsupported_packages
-	{
-		PropertyName: "unsupported_packages",
-		propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
-			return properties.Hidden_api.Unsupported_packages
-		},
-		commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
-			command.FlagWithInput("--unsupported ", path).Flag("--packages ")
-		},
-	},
+	hiddenAPIFlagFileCategoryUnsupportedPackages,
 }
 
 // FlagFilesByCategory maps a hiddenAPIFlagFileCategory to the paths to the files in that category.
-type FlagFilesByCategory map[*hiddenAPIFlagFileCategory]android.Paths
+type FlagFilesByCategory map[hiddenAPIFlagFileCategory]android.Paths
 
 // append the supplied flags files to the corresponding category in this map.
 func (s FlagFilesByCategory) append(other FlagFilesByCategory) {
@@ -1014,7 +1010,7 @@
 	// If available then pass the automatically generated file containing dex signatures of removed
 	// API members to the rule so they can be marked as removed.
 	if generatedRemovedDexSignatures.Valid() {
-		hiddenAPIRemovedFlagFileCategory.commandMutator(command, generatedRemovedDexSignatures.Path())
+		hiddenAPIFlagFileCategoryRemoved.commandMutator(command, generatedRemovedDexSignatures.Path())
 	}
 
 	commitChangeForRestat(rule, tempPath, outputPath)
diff --git a/java/java.go b/java/java.go
index d18d915..d536ca1 100644
--- a/java/java.go
+++ b/java/java.go
@@ -653,7 +653,7 @@
 	return j.properties.Permitted_packages
 }
 
-func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool {
+func shouldUncompressDex(ctx android.ModuleContext, libName string, dexpreopter *dexpreopter) bool {
 	// Store uncompressed (and aligned) any dex files from jars in APEXes.
 	if apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider); !apexInfo.IsForPlatform() {
 		return true
@@ -665,7 +665,7 @@
 	}
 
 	// Store uncompressed dex files that are preopted on /system.
-	if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !dexpreopter.odexOnSystemOther(ctx, dexpreopter.installPath)) {
+	if !dexpreopter.dexpreoptDisabled(ctx, libName) && (ctx.Host() || !dexpreopter.odexOnSystemOther(ctx, libName, dexpreopter.installPath)) {
 		return true
 	}
 	if ctx.Config().UncompressPrivAppDex() &&
@@ -680,7 +680,7 @@
 func setUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter, dexer *dexer) {
 	if dexer.dexProperties.Uncompress_dex == nil {
 		// If the value was not force-set by the user, use reasonable default based on the module.
-		dexer.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, dexpreopter))
+		dexer.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), dexpreopter))
 	}
 }
 
@@ -712,7 +712,7 @@
 	j.checkHeadersOnly(ctx)
 	if ctx.Device() {
 		j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
-			ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
+			ctx, j.Name(), android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
 		j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
 		setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
 		j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
@@ -1084,7 +1084,7 @@
 	return true
 }
 
-func (j *TestHost) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
+func (j *TestHost) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool {
 	return ctx.DeviceConfig().NativeCoverageEnabled()
 }
 
@@ -2274,7 +2274,7 @@
 				installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, ApexRootRelativePathToJavaLib(j.BaseModuleName()))
 				j.dexJarInstallFile = installPath
 
-				j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, installPath)
+				j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), installPath)
 				setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
 				j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
 
@@ -2282,8 +2282,6 @@
 					j.dexpreopter.inputProfilePathOnHost = profilePath
 				}
 
-				j.dexpreopt(ctx, dexOutputPath)
-
 				// Initialize the hiddenapi structure.
 				j.initHiddenAPI(ctx, dexJarFile, outputFile, j.dexProperties.Uncompress_dex)
 			} else {
@@ -2304,7 +2302,7 @@
 			// Dex compilation
 
 			j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
-				ctx, android.PathForModuleInstall(ctx, "framework", jarName))
+				ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), android.PathForModuleInstall(ctx, "framework", jarName))
 			setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
 			j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
 
@@ -2592,8 +2590,8 @@
 	}
 
 	j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
-		ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
-	j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
+		ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
+	j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &j.dexpreopter)
 
 	inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars")
 	dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar")
@@ -2632,7 +2630,7 @@
 
 	j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
 
-	j.dexpreopt(ctx, dexOutputFile)
+	j.dexpreopt(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), dexOutputFile)
 
 	if apexInfo.IsForPlatform() {
 		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
diff --git a/java/lint.go b/java/lint.go
index c3d723b..31e7f35 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -370,6 +370,12 @@
 		return
 	}
 
+	for _, flag := range l.properties.Lint.Flags {
+		if strings.Contains(flag, "--disable") || strings.Contains(flag, "--enable") || strings.Contains(flag, "--check") {
+			ctx.PropertyErrorf("lint.flags", "Don't use --disable, --enable, or --check in the flags field, instead use the dedicated disabled_checks, warning_checks, error_checks, or fatal_checks fields")
+		}
+	}
+
 	if l.minSdkVersion.CompareTo(l.compileSdkVersion) == -1 {
 		l.extraMainlineLintErrors = append(l.extraMainlineLintErrors, updatabilityChecks...)
 		// Skip lint warning checks for NewApi warnings for libcore where they come from source
diff --git a/java/lint_test.go b/java/lint_test.go
index b7e6aad..751b139 100644
--- a/java/lint_test.go
+++ b/java/lint_test.go
@@ -260,3 +260,22 @@
 		}
 	}
 }
+
+func TestCantControlCheckSeverityWithFlags(t *testing.T) {
+	bp := `
+		java_library {
+			name: "foo",
+			srcs: [
+				"a.java",
+			],
+			min_sdk_version: "29",
+			sdk_version: "current",
+			lint: {
+				flags: ["--disabled", "NewApi"],
+			},
+		}
+	`
+	PrepareForTestWithJavaDefaultModules.
+		ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Don't use --disable, --enable, or --check in the flags field, instead use the dedicated disabled_checks, warning_checks, error_checks, or fatal_checks fields")).
+		RunTestWithBp(t, bp)
+}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 29da28d..2bf6644 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -15,6 +15,7 @@
 package java
 
 import (
+	"errors"
 	"fmt"
 	"path"
 	"path/filepath"
@@ -752,75 +753,78 @@
 	}
 }
 
-func (paths *scopePaths) treatDepAsApiStubsProvider(dep android.Module, action func(provider ApiStubsProvider)) error {
+func (paths *scopePaths) treatDepAsApiStubsProvider(dep android.Module, action func(provider ApiStubsProvider) error) error {
 	if apiStubsProvider, ok := dep.(ApiStubsProvider); ok {
-		action(apiStubsProvider)
-		return nil
-	} else {
-		return fmt.Errorf("expected module that implements ApiStubsProvider, e.g. droidstubs")
-	}
-}
-
-func (paths *scopePaths) treatDepAsExportableApiStubsProvider(dep android.Module, action func(provider ExportableApiStubsProvider)) error {
-	if exportableApiStubsProvider, ok := dep.(ExportableApiStubsProvider); ok {
-		action(exportableApiStubsProvider)
+		err := action(apiStubsProvider)
+		if err != nil {
+			return err
+		}
 		return nil
 	} else {
 		return fmt.Errorf("expected module that implements ExportableApiStubsSrcProvider, e.g. droidstubs")
 	}
 }
 
-func (paths *scopePaths) treatDepAsApiStubsSrcProvider(dep android.Module, action func(provider ApiStubsSrcProvider)) error {
+func (paths *scopePaths) treatDepAsApiStubsSrcProvider(dep android.Module, action func(provider ApiStubsSrcProvider) error) error {
 	if apiStubsProvider, ok := dep.(ApiStubsSrcProvider); ok {
-		action(apiStubsProvider)
+		err := action(apiStubsProvider)
+		if err != nil {
+			return err
+		}
 		return nil
 	} else {
 		return fmt.Errorf("expected module that implements ApiStubsSrcProvider, e.g. droidstubs")
 	}
 }
 
-func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider ApiStubsProvider) {
-	paths.annotationsZip = android.OptionalPathForPath(provider.AnnotationsZip())
-	paths.currentApiFilePath = android.OptionalPathForPath(provider.ApiFilePath())
-	paths.removedApiFilePath = android.OptionalPathForPath(provider.RemovedApiFilePath())
-}
+func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider ApiStubsProvider, stubsType StubsType) error {
+	var annotationsZip, currentApiFilePath, removedApiFilePath android.Path
+	annotationsZip, annotationsZipErr := provider.AnnotationsZip(stubsType)
+	currentApiFilePath, currentApiFilePathErr := provider.ApiFilePath(stubsType)
+	removedApiFilePath, removedApiFilePathErr := provider.RemovedApiFilePath(stubsType)
 
-func (paths *scopePaths) extractApiInfoFromExportableApiStubsProvider(provider ExportableApiStubsProvider) {
-	paths.annotationsZip = android.OptionalPathForPath(provider.ExportableAnnotationsZip())
-	paths.currentApiFilePath = android.OptionalPathForPath(provider.ExportableApiFilePath())
-	paths.removedApiFilePath = android.OptionalPathForPath(provider.ExportableRemovedApiFilePath())
+	combinedError := errors.Join(annotationsZipErr, currentApiFilePathErr, removedApiFilePathErr)
+
+	if combinedError == nil {
+		paths.annotationsZip = android.OptionalPathForPath(annotationsZip)
+		paths.currentApiFilePath = android.OptionalPathForPath(currentApiFilePath)
+		paths.removedApiFilePath = android.OptionalPathForPath(removedApiFilePath)
+	}
+	return combinedError
 }
 
 func (paths *scopePaths) extractApiInfoFromDep(ctx android.ModuleContext, dep android.Module) error {
-	return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) {
-		paths.extractApiInfoFromApiStubsProvider(provider)
+	return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) error {
+		return paths.extractApiInfoFromApiStubsProvider(provider, Everything)
 	})
 }
 
-func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsSrcProvider) {
-	paths.stubsSrcJar = android.OptionalPathForPath(provider.StubsSrcJar())
-}
-
-func (paths *scopePaths) extractStubsSourceInfoFromExportableApiStubsProviders(provider ExportableApiStubsSrcProvider) {
-	paths.stubsSrcJar = android.OptionalPathForPath(provider.ExportableStubsSrcJar())
+func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsSrcProvider, stubsType StubsType) error {
+	stubsSrcJar, err := provider.StubsSrcJar(stubsType)
+	if err == nil {
+		paths.stubsSrcJar = android.OptionalPathForPath(stubsSrcJar)
+	}
+	return err
 }
 
 func (paths *scopePaths) extractStubsSourceInfoFromDep(ctx android.ModuleContext, dep android.Module) error {
-	return paths.treatDepAsApiStubsSrcProvider(dep, func(provider ApiStubsSrcProvider) {
-		paths.extractStubsSourceInfoFromApiStubsProviders(provider)
+	return paths.treatDepAsApiStubsSrcProvider(dep, func(provider ApiStubsSrcProvider) error {
+		return paths.extractStubsSourceInfoFromApiStubsProviders(provider, Everything)
 	})
 }
 
 func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(ctx android.ModuleContext, dep android.Module) error {
 	if ctx.Config().ReleaseHiddenApiExportableStubs() {
-		return paths.treatDepAsExportableApiStubsProvider(dep, func(provider ExportableApiStubsProvider) {
-			paths.extractApiInfoFromExportableApiStubsProvider(provider)
-			paths.extractStubsSourceInfoFromExportableApiStubsProviders(provider)
+		return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) error {
+			extractApiInfoErr := paths.extractApiInfoFromApiStubsProvider(provider, Exportable)
+			extractStubsSourceInfoErr := paths.extractStubsSourceInfoFromApiStubsProviders(provider, Exportable)
+			return errors.Join(extractApiInfoErr, extractStubsSourceInfoErr)
 		})
 	}
-	return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) {
-		paths.extractApiInfoFromApiStubsProvider(provider)
-		paths.extractStubsSourceInfoFromApiStubsProviders(provider)
+	return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) error {
+		extractApiInfoErr := paths.extractApiInfoFromApiStubsProvider(provider, Everything)
+		extractStubsSourceInfoErr := paths.extractStubsSourceInfoFromApiStubsProviders(provider, Everything)
+		return errors.Join(extractApiInfoErr, extractStubsSourceInfoErr)
 	})
 }
 
@@ -2875,16 +2879,13 @@
 				module.installFile = installPath
 				module.initHiddenAPI(ctx, dexJarFile, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil)
 
-				module.dexpreopter.installPath = module.dexpreopter.getInstallPath(ctx, installPath)
+				module.dexpreopter.installPath = module.dexpreopter.getInstallPath(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), installPath)
 				module.dexpreopter.isSDKLibrary = true
-				module.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &module.dexpreopter)
+				module.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &module.dexpreopter)
 
 				if profilePath := di.PrebuiltExportPath(dexJarFileApexRootRelative + ".prof"); profilePath != nil {
 					module.dexpreopter.inputProfilePathOnHost = profilePath
 				}
-
-				// Dexpreopting.
-				module.dexpreopt(ctx, dexOutputPath)
 			} else {
 				// This should never happen as a variant for a prebuilt_apex is only created if the
 				// prebuilt_apex has been configured to export the java library dex file.
diff --git a/phony/phony.go b/phony/phony.go
index bb48788..b8dbd00 100644
--- a/phony/phony.go
+++ b/phony/phony.go
@@ -68,6 +68,10 @@
 				fmt.Fprintln(w, "LOCAL_TARGET_REQUIRED_MODULES :=",
 					strings.Join(p.targetRequiredModuleNames, " "))
 			}
+			// AconfigUpdateAndroidMkData may have added elements to Extra.  Process them here.
+			for _, extra := range data.Extra {
+				extra(w, nil)
+			}
 			fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
 		},
 	}
diff --git a/rust/config/x86_64_device.go b/rust/config/x86_64_device.go
index cc16704..49f7c77 100644
--- a/rust/config/x86_64_device.go
+++ b/rust/config/x86_64_device.go
@@ -28,16 +28,16 @@
 	x86_64LinkFlags            = []string{}
 
 	x86_64ArchVariantRustFlags = map[string][]string{
-		"":                        []string{},
-		"broadwell":               []string{"-C target-cpu=broadwell"},
-		"goldmont":                []string{"-C target-cpu=goldmont"},
-		"goldmont-plus":           []string{"-C target-cpu=goldmont-plus"},
-		"goldmont-without-xsaves": []string{"-C target-cpu=goldmont", "-C target-feature=-xsaves"},
-		"haswell":                 []string{"-C target-cpu=haswell"},
-		"ivybridge":               []string{"-C target-cpu=ivybridge"},
-		"sandybridge":             []string{"-C target-cpu=sandybridge"},
-		"silvermont":              []string{"-C target-cpu=silvermont"},
-		"skylake":                 []string{"-C target-cpu=skylake"},
+		"":                            []string{},
+		"broadwell":                   []string{"-C target-cpu=broadwell"},
+		"goldmont":                    []string{"-C target-cpu=goldmont"},
+		"goldmont-plus":               []string{"-C target-cpu=goldmont-plus"},
+		"goldmont-without-sha-xsaves": []string{"-C target-cpu=goldmont", "-C target-feature=-sha,-xsaves"},
+		"haswell":                     []string{"-C target-cpu=haswell"},
+		"ivybridge":                   []string{"-C target-cpu=ivybridge"},
+		"sandybridge":                 []string{"-C target-cpu=sandybridge"},
+		"silvermont":                  []string{"-C target-cpu=silvermont"},
+		"skylake":                     []string{"-C target-cpu=skylake"},
 		//TODO: Add target-cpu=stoneyridge when rustc supports it.
 		"stoneyridge": []string{""},
 		"tremont":     []string{"-C target-cpu=tremont"},
diff --git a/rust/config/x86_device.go b/rust/config/x86_device.go
index e7b575c..2a57e73 100644
--- a/rust/config/x86_device.go
+++ b/rust/config/x86_device.go
@@ -26,17 +26,17 @@
 	x86LinkFlags            = []string{}
 
 	x86ArchVariantRustFlags = map[string][]string{
-		"":                        []string{},
-		"atom":                    []string{"-C target-cpu=atom"},
-		"broadwell":               []string{"-C target-cpu=broadwell"},
-		"goldmont":                []string{"-C target-cpu=goldmont"},
-		"goldmont-plus":           []string{"-C target-cpu=goldmont-plus"},
-		"goldmont-without-xsaves": []string{"-C target-cpu=goldmont", "-C target-feature=-xsaves"},
-		"haswell":                 []string{"-C target-cpu=haswell"},
-		"ivybridge":               []string{"-C target-cpu=ivybridge"},
-		"sandybridge":             []string{"-C target-cpu=sandybridge"},
-		"silvermont":              []string{"-C target-cpu=silvermont"},
-		"skylake":                 []string{"-C target-cpu=skylake"},
+		"":                            []string{},
+		"atom":                        []string{"-C target-cpu=atom"},
+		"broadwell":                   []string{"-C target-cpu=broadwell"},
+		"goldmont":                    []string{"-C target-cpu=goldmont"},
+		"goldmont-plus":               []string{"-C target-cpu=goldmont-plus"},
+		"goldmont-without-sha-xsaves": []string{"-C target-cpu=goldmont", "-C target-feature=-sha,-xsaves"},
+		"haswell":                     []string{"-C target-cpu=haswell"},
+		"ivybridge":                   []string{"-C target-cpu=ivybridge"},
+		"sandybridge":                 []string{"-C target-cpu=sandybridge"},
+		"silvermont":                  []string{"-C target-cpu=silvermont"},
+		"skylake":                     []string{"-C target-cpu=skylake"},
 		//TODO: Add target-cpu=stoneyridge when rustc supports it.
 		"stoneyridge": []string{""},
 		"tremont":     []string{"-C target-cpu=tremont"},
diff --git a/rust/rust.go b/rust/rust.go
index 34ce4c5..245ed2e 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -535,7 +535,7 @@
 
 var _ cc.Coverage = (*Module)(nil)
 
-func (mod *Module) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
+func (mod *Module) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool {
 	return mod.coverage != nil && mod.coverage.Properties.NeedCoverageVariant
 }
 
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index 4a0796b..766f3e7 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -345,6 +345,10 @@
 			fmt.Fprintln(w, "LOCAL_MODULE :=", m.Name())
 			fmt.Fprintf(w, "LOCAL_MODULE_CLASS := FAKE\n")
 			fmt.Fprintf(w, "LOCAL_MODULE_TAGS := optional\n")
+			// AconfigUpdateAndroidMkData may have added elements to Extra.  Process them here.
+			for _, extra := range data.Extra {
+				extra(w, nil)
+			}
 			fmt.Fprintf(w, "include $(BUILD_SYSTEM)/base_rules.mk\n\n")
 			fmt.Fprintf(w, "$(LOCAL_BUILT_MODULE): %s\n", m.checkApiFileTimeStamp.String())
 			fmt.Fprintf(w, "\ttouch $@\n\n")
diff --git a/testing/code_metadata_proto/Android.bp b/testing/code_metadata_proto/Android.bp
index 8fcca19..f07efff 100644
--- a/testing/code_metadata_proto/Android.bp
+++ b/testing/code_metadata_proto/Android.bp
@@ -20,10 +20,24 @@
     name: "soong-testing-code_metadata_proto",
     pkgPath: "android/soong/testing/code_metadata_proto",
     deps: [
-            "golang-protobuf-reflect-protoreflect",
-            "golang-protobuf-runtime-protoimpl",
-        ],
+        "golang-protobuf-reflect-protoreflect",
+        "golang-protobuf-runtime-protoimpl",
+    ],
     srcs: [
         "code_metadata.pb.go",
     ],
 }
+
+python_library_host {
+    name: "code-metadata-proto-py",
+    pkg_path: "code_metadata",
+    srcs: [
+        "code_metadata.proto",
+    ],
+    libs: [
+        "libprotobuf-python",
+    ],
+    proto: {
+        canonical_path_from_root: false,
+    },
+}
diff --git a/testing/test_spec_proto/Android.bp b/testing/test_spec_proto/Android.bp
index 1cac492..d5ad70b 100644
--- a/testing/test_spec_proto/Android.bp
+++ b/testing/test_spec_proto/Android.bp
@@ -20,10 +20,24 @@
     name: "soong-testing-test_spec_proto",
     pkgPath: "android/soong/testing/test_spec_proto",
     deps: [
-            "golang-protobuf-reflect-protoreflect",
-            "golang-protobuf-runtime-protoimpl",
-        ],
+        "golang-protobuf-reflect-protoreflect",
+        "golang-protobuf-runtime-protoimpl",
+    ],
     srcs: [
         "test_spec.pb.go",
     ],
 }
+
+python_library_host {
+    name: "test-spec-proto-py",
+    pkg_path: "test_spec",
+    srcs: [
+        "test_spec.proto",
+    ],
+    libs: [
+        "libprotobuf-python",
+    ],
+    proto: {
+        canonical_path_from_root: false,
+    },
+}