Merge changes from topic "import_make_staging_dir" into main

* changes:
  Add include_make_built_files
  Don't use zip files when creating filesystems
diff --git a/aconfig/codegen/aconfig_declarations_group.go b/aconfig/codegen/aconfig_declarations_group.go
index 203b6be..1c91bee 100644
--- a/aconfig/codegen/aconfig_declarations_group.go
+++ b/aconfig/codegen/aconfig_declarations_group.go
@@ -15,9 +15,10 @@
 package codegen
 
 import (
-	"android/soong/aconfig"
-	"android/soong/android"
 	"fmt"
+	"maps"
+
+	"android/soong/android"
 
 	"github.com/google/blueprint"
 )
@@ -43,6 +44,7 @@
 	aconfigDeclarationNames      []string
 	intermediateCacheOutputPaths android.Paths
 	javaSrcjars                  android.Paths
+	modeInfos                    map[string]android.ModeInfo
 }
 
 type AconfigDeclarationsGroupProperties struct {
@@ -76,9 +78,10 @@
 }
 
 func (adg *AconfigDeclarationsGroup) VisitDeps(ctx android.ModuleContext) {
+	adg.modeInfos = make(map[string]android.ModeInfo)
 	ctx.VisitDirectDeps(func(dep android.Module) {
 		tag := ctx.OtherModuleDependencyTag(dep)
-		if provider, ok := android.OtherModuleProvider(ctx, dep, aconfig.CodegenInfoProvider); ok {
+		if provider, ok := android.OtherModuleProvider(ctx, dep, android.CodegenInfoProvider); ok {
 
 			// aconfig declaration names and cache files are collected for all aconfig library dependencies
 			adg.aconfigDeclarationNames = append(adg.aconfigDeclarationNames, provider.AconfigDeclarations...)
@@ -88,8 +91,14 @@
 			case aconfigDeclarationsGroupTag:
 				// Will retrieve outputs from another language codegen modules when support is added
 				adg.javaSrcjars = append(adg.javaSrcjars, provider.Srcjars...)
+				maps.Copy(adg.modeInfos, provider.ModeInfos)
 			case javaAconfigLibraryTag:
 				adg.javaSrcjars = append(adg.javaSrcjars, provider.Srcjars...)
+				maps.Copy(adg.modeInfos, provider.ModeInfos)
+			case ccAconfigLibraryTag:
+				maps.Copy(adg.modeInfos, provider.ModeInfos)
+			case rustAconfigLibraryTag:
+				maps.Copy(adg.modeInfos, provider.ModeInfos)
 			}
 		}
 	})
@@ -100,10 +109,11 @@
 	adg.aconfigDeclarationNames = android.FirstUniqueStrings(adg.aconfigDeclarationNames)
 	adg.intermediateCacheOutputPaths = android.FirstUniquePaths(adg.intermediateCacheOutputPaths)
 
-	android.SetProvider(ctx, aconfig.CodegenInfoProvider, aconfig.CodegenInfo{
+	android.SetProvider(ctx, android.CodegenInfoProvider, android.CodegenInfo{
 		AconfigDeclarations:          adg.aconfigDeclarationNames,
 		IntermediateCacheOutputPaths: adg.intermediateCacheOutputPaths,
 		Srcjars:                      adg.javaSrcjars,
+		ModeInfos:                    adg.modeInfos,
 	})
 }
 
diff --git a/aconfig/codegen/cc_aconfig_library.go b/aconfig/codegen/cc_aconfig_library.go
index 50cd4de..80e4926 100644
--- a/aconfig/codegen/cc_aconfig_library.go
+++ b/aconfig/codegen/cc_aconfig_library.go
@@ -146,4 +146,12 @@
 			"mode":   mode,
 		},
 	})
+
+	android.SetProvider(ctx, android.CodegenInfoProvider, android.CodegenInfo{
+		ModeInfos: map[string]android.ModeInfo{
+			ctx.ModuleName(): {
+				Container: declarations.Container,
+				Mode:      mode,
+			}},
+	})
 }
diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go
index 3d15ac9..1378dfe 100644
--- a/aconfig/codegen/java_aconfig_library.go
+++ b/aconfig/codegen/java_aconfig_library.go
@@ -17,7 +17,6 @@
 import (
 	"fmt"
 
-	"android/soong/aconfig"
 	"android/soong/android"
 	"android/soong/java"
 
@@ -119,10 +118,15 @@
 		module.AddJarJarRenameRule(declarations.Package+".FakeFeatureFlagsImpl", "")
 	}
 
-	android.SetProvider(ctx, aconfig.CodegenInfoProvider, aconfig.CodegenInfo{
+	android.SetProvider(ctx, android.CodegenInfoProvider, android.CodegenInfo{
 		AconfigDeclarations:          []string{declarationsModules[0].Name()},
 		IntermediateCacheOutputPaths: android.Paths{declarations.IntermediateCacheOutputPath},
 		Srcjars:                      android.Paths{srcJarPath},
+		ModeInfos: map[string]android.ModeInfo{
+			ctx.ModuleName(): {
+				Container: declarations.Container,
+				Mode:      mode,
+			}},
 	})
 
 	return srcJarPath
diff --git a/aconfig/codegen/rust_aconfig_library.go b/aconfig/codegen/rust_aconfig_library.go
index 2ab54b6..3f7495b 100644
--- a/aconfig/codegen/rust_aconfig_library.go
+++ b/aconfig/codegen/rust_aconfig_library.go
@@ -85,6 +85,15 @@
 		},
 	})
 	a.BaseSourceProvider.OutputFiles = android.Paths{generatedSource}
+
+	android.SetProvider(ctx, android.CodegenInfoProvider, android.CodegenInfo{
+		ModeInfos: map[string]android.ModeInfo{
+			ctx.ModuleName(): {
+				Container: declarations.Container,
+				Mode:      mode,
+			}},
+	})
+
 	return generatedSource
 }
 
diff --git a/aconfig/init.go b/aconfig/init.go
index e64429f..4625128 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -20,20 +20,6 @@
 	"github.com/google/blueprint"
 )
 
-type CodegenInfo struct {
-	// AconfigDeclarations is the name of the aconfig_declarations modules that
-	// the codegen module is associated with
-	AconfigDeclarations []string
-
-	// Paths to the cache files of the associated aconfig_declaration modules
-	IntermediateCacheOutputPaths android.Paths
-
-	// Paths to the srcjar files generated from the java_aconfig_library modules
-	Srcjars android.Paths
-}
-
-var CodegenInfoProvider = blueprint.NewProvider[CodegenInfo]()
-
 var (
 	pctx = android.NewPackageContext("android/soong/aconfig")
 
diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go
index 74c1a5e..fcc57e1 100644
--- a/android/aconfig_providers.go
+++ b/android/aconfig_providers.go
@@ -17,6 +17,7 @@
 import (
 	"fmt"
 	"io"
+	"maps"
 	"reflect"
 
 	"github.com/google/blueprint"
@@ -50,6 +51,35 @@
 
 var AconfigTransitiveDeclarationsInfoProvider = blueprint.NewProvider[AconfigTransitiveDeclarationsInfo]()
 
+type ModeInfo struct {
+	Container string
+	Mode      string
+}
+type CodegenInfo struct {
+	// AconfigDeclarations is the name of the aconfig_declarations modules that
+	// the codegen module is associated with
+	AconfigDeclarations []string
+
+	// Paths to the cache files of the associated aconfig_declaration modules
+	IntermediateCacheOutputPaths Paths
+
+	// Paths to the srcjar files generated from the java_aconfig_library modules
+	Srcjars Paths
+
+	ModeInfos map[string]ModeInfo
+}
+
+var CodegenInfoProvider = blueprint.NewProvider[CodegenInfo]()
+
+func propagateModeInfos(ctx ModuleContext, module Module, to, from map[string]ModeInfo) {
+	if len(from) > 0 {
+		depTag := ctx.OtherModuleDependencyTag(module)
+		if tag, ok := depTag.(PropagateAconfigValidationDependencyTag); ok && tag.PropagateAconfigValidation() {
+			maps.Copy(to, from)
+		}
+	}
+}
+
 // 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) {
@@ -90,13 +120,40 @@
 
 type aconfigPropagatingDeclarationsInfo struct {
 	AconfigFiles map[string]Paths
+	ModeInfos    map[string]ModeInfo
 }
 
 var aconfigPropagatingProviderKey = blueprint.NewProvider[aconfigPropagatingDeclarationsInfo]()
 
+func VerifyAconfigBuildMode(ctx ModuleContext, container string, module blueprint.Module, asError bool) {
+	if dep, ok := OtherModuleProvider(ctx, module, aconfigPropagatingProviderKey); ok {
+		for k, v := range dep.ModeInfos {
+			msg := fmt.Sprintf("%s/%s depends on %s/%s/%s across containers\n",
+				module.Name(), container, k, v.Container, v.Mode)
+			if v.Container != container && v.Mode != "exported" && v.Mode != "force-read-only" {
+				if asError {
+					ctx.ModuleErrorf(msg)
+				} else {
+					fmt.Printf("WARNING: " + msg)
+				}
+			} else {
+				if !asError {
+					fmt.Printf("PASSED: " + msg)
+				}
+			}
+		}
+	}
+}
+
 func aconfigUpdateAndroidBuildActions(ctx ModuleContext) {
 	mergedAconfigFiles := make(map[string]Paths)
+	mergedModeInfos := make(map[string]ModeInfo)
+
 	ctx.VisitDirectDepsIgnoreBlueprint(func(module Module) {
+		if aconfig_dep, ok := OtherModuleProvider(ctx, module, CodegenInfoProvider); ok && len(aconfig_dep.ModeInfos) > 0 {
+			maps.Copy(mergedModeInfos, aconfig_dep.ModeInfos)
+		}
+
 		// 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)
@@ -105,6 +162,7 @@
 			for container, v := range dep.AconfigFiles {
 				mergedAconfigFiles[container] = append(mergedAconfigFiles[container], v...)
 			}
+			propagateModeInfos(ctx, module, mergedModeInfos, dep.ModeInfos)
 		}
 		if dep, ok := OtherModuleProvider(ctx, module, AconfigTransitiveDeclarationsInfoProvider); ok {
 			for container, v := range dep.AconfigFiles {
@@ -120,6 +178,7 @@
 
 		SetProvider(ctx, aconfigPropagatingProviderKey, aconfigPropagatingDeclarationsInfo{
 			AconfigFiles: mergedAconfigFiles,
+			ModeInfos:    mergedModeInfos,
 		})
 	}
 }
diff --git a/android/apex.go b/android/apex.go
index 4d36a93..8759905 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -976,3 +976,18 @@
 	// Map from the apex library name (without prebuilt_ prefix) to the dex file path on host
 	LibraryNameToDexJarPathOnHost map[string]Path
 }
+
+var PrebuiltInfoProvider = blueprint.NewProvider[PrebuiltInfo]()
+
+// contents of prebuilt_info.json
+type PrebuiltInfo struct {
+	// Name of the apex, without the prebuilt_ prefix
+	Name string
+
+	Is_prebuilt bool
+
+	// This is relative to root of the workspace.
+	// In case of mainline modules, this file contains the build_id that was used
+	// to generate the mainline module prebuilt.
+	Prebuilt_info_file_path string `json:",omitempty"`
+}
diff --git a/android/base_module_context.go b/android/base_module_context.go
index b9c1153..dd38a4e 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -16,9 +16,11 @@
 
 import (
 	"fmt"
-	"github.com/google/blueprint"
 	"regexp"
 	"strings"
+
+	"github.com/google/blueprint"
+	"github.com/google/blueprint/parser"
 )
 
 // BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
@@ -214,6 +216,10 @@
 	// getMissingDependencies returns the list of missing dependencies.
 	// Calling this function prevents adding new dependencies.
 	getMissingDependencies() []string
+
+	// EvaluateConfiguration makes ModuleContext a valid proptools.ConfigurableEvaluator, so this context
+	// can be used to evaluate the final value of Configurable properties.
+	EvaluateConfiguration(parser.SelectType, string) (string, bool)
 }
 
 type baseModuleContext struct {
@@ -564,3 +570,32 @@
 	}
 	return sb.String()
 }
+
+func (m *baseModuleContext) EvaluateConfiguration(ty parser.SelectType, condition string) (string, bool) {
+	switch ty {
+	case parser.SelectTypeReleaseVariable:
+		if v, ok := m.Config().productVariables.BuildFlags[condition]; ok {
+			return v, true
+		}
+		return "", false
+	case parser.SelectTypeProductVariable:
+		// TODO(b/323382414): Might add these on a case-by-case basis
+		m.ModuleErrorf("TODO(b/323382414): Product variables are not yet supported in selects")
+		return "", false
+	case parser.SelectTypeSoongConfigVariable:
+		parts := strings.Split(condition, ":")
+		namespace := parts[0]
+		variable := parts[1]
+		if n, ok := m.Config().productVariables.VendorVars[namespace]; ok {
+			if v, ok := n[variable]; ok {
+				return v, true
+			}
+		}
+		return "", false
+	case parser.SelectTypeVariant:
+		m.ModuleErrorf("TODO(b/323382414): Variants are not yet supported in selects")
+		return "", false
+	default:
+		panic("Should be unreachable")
+	}
+}
diff --git a/android/config.go b/android/config.go
index 1bb1a22..567ebd8 100644
--- a/android/config.go
+++ b/android/config.go
@@ -18,7 +18,6 @@
 // product variables necessary for soong_build's operation.
 
 import (
-	"android/soong/shared"
 	"encoding/json"
 	"fmt"
 	"os"
@@ -30,6 +29,8 @@
 	"sync"
 	"unicode"
 
+	"android/soong/shared"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/bootstrap"
 	"github.com/google/blueprint/pathtools"
@@ -1938,6 +1939,10 @@
 	return c.config.productVariables.GenerateAidlNdkPlatformBackend
 }
 
+func (c *deviceConfig) AconfigContainerValidation() string {
+	return c.config.productVariables.AconfigContainerValidation
+}
+
 func (c *config) IgnorePrefer32OnDevice() bool {
 	return c.productVariables.IgnorePrefer32OnDevice
 }
diff --git a/android/deptag.go b/android/deptag.go
index a15443b..c7ba4d3 100644
--- a/android/deptag.go
+++ b/android/deptag.go
@@ -43,3 +43,15 @@
 	}
 	return false
 }
+
+type PropagateAconfigValidationDependencyTag interface {
+	PropagateAconfigValidation() bool
+}
+
+type AlwaysPropagateAconfigValidationDependencyTag struct{}
+
+func (p AlwaysPropagateAconfigValidationDependencyTag) PropagateAconfigValidation() bool {
+	return true
+}
+
+var _ PropagateAconfigValidationDependencyTag = AlwaysPropagateAconfigValidationDependencyTag{}
diff --git a/android/module.go b/android/module.go
index b615ff5..000476c 100644
--- a/android/module.go
+++ b/android/module.go
@@ -15,7 +15,6 @@
 package android
 
 import (
-	"android/soong/bazel"
 	"crypto/md5"
 	"encoding/hex"
 	"encoding/json"
@@ -27,6 +26,8 @@
 	"sort"
 	"strings"
 
+	"android/soong/bazel"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 )
@@ -2087,6 +2088,7 @@
 // caused by prebuilt_ prefix, or fully qualified module names.
 type sourceOrOutputDependencyTag struct {
 	blueprint.BaseDependencyTag
+	AlwaysPropagateAconfigValidationDependencyTag
 
 	// The name of the module.
 	moduleName string
diff --git a/android/module_context.go b/android/module_context.go
index 3fc5d01..1cab630 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -21,7 +21,6 @@
 	"strings"
 
 	"github.com/google/blueprint"
-	"github.com/google/blueprint/parser"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -213,10 +212,6 @@
 	// GenerateAndroidBuildActions.  If it is called then the struct will be written out and included in
 	// the module-info.json generated by Make, and Make will not generate its own data for this module.
 	ModuleInfoJSON() *ModuleInfoJSON
-
-	// EvaluateConfiguration makes ModuleContext a valid proptools.ConfigurableEvaluator, so this context
-	// can be used to evaluate the final value of Configurable properties.
-	EvaluateConfiguration(parser.SelectType, string) (string, bool)
 }
 
 type moduleContext struct {
@@ -719,32 +714,3 @@
 func (m *moduleContext) TargetRequiredModuleNames() []string {
 	return m.module.TargetRequiredModuleNames()
 }
-
-func (m *moduleContext) EvaluateConfiguration(ty parser.SelectType, condition string) (string, bool) {
-	switch ty {
-	case parser.SelectTypeReleaseVariable:
-		if v, ok := m.Config().productVariables.BuildFlags[condition]; ok {
-			return v, true
-		}
-		return "", false
-	case parser.SelectTypeProductVariable:
-		// TODO: Might add these on a case-by-case basis
-		m.ModuleErrorf("TODO(b/323382414): Product variables are not yet supported in selects")
-		return "", false
-	case parser.SelectTypeSoongConfigVariable:
-		parts := strings.Split(condition, ":")
-		namespace := parts[0]
-		variable := parts[1]
-		if n, ok := m.Config().productVariables.VendorVars[namespace]; ok {
-			if v, ok := n[variable]; ok {
-				return v, true
-			}
-		}
-		return "", false
-	case parser.SelectTypeVariant:
-		m.ModuleErrorf("TODO(b/323382414): Variants are not yet supported in selects")
-		return "", false
-	default:
-		panic("Should be unreachable")
-	}
-}
diff --git a/android/path_properties.go b/android/path_properties.go
index bbfaa8c..ea92565 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -47,7 +47,7 @@
 	// tagged with `android:"path"`.
 	var pathProperties []string
 	for _, ps := range props {
-		pathProperties = append(pathProperties, pathPropertiesForPropertyStruct(ps)...)
+		pathProperties = append(pathProperties, pathPropertiesForPropertyStruct(ctx, ps)...)
 	}
 
 	// Remove duplicates to avoid multiple dependencies.
@@ -64,7 +64,7 @@
 // pathPropertiesForPropertyStruct uses the indexes of properties that are tagged with
 // android:"path" to extract all their values from a property struct, returning them as a single
 // slice of strings.
-func pathPropertiesForPropertyStruct(ps interface{}) []string {
+func pathPropertiesForPropertyStruct(ctx BottomUpMutatorContext, ps interface{}) []string {
 	v := reflect.ValueOf(ps)
 	if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
 		panic(fmt.Errorf("type %s is not a pointer to a struct", v.Type()))
@@ -106,6 +106,16 @@
 				ret = append(ret, sv.String())
 			case reflect.Slice:
 				ret = append(ret, sv.Interface().([]string)...)
+			case reflect.Struct:
+				intf := sv.Interface()
+				if configurable, ok := intf.(proptools.Configurable[string]); ok {
+					ret = append(ret, proptools.String(configurable.Evaluate(ctx)))
+				} else if configurable, ok := intf.(proptools.Configurable[[]string]); ok {
+					ret = append(ret, proptools.Slice(configurable.Evaluate(ctx))...)
+				} else {
+					panic(fmt.Errorf(`field %s in type %s has tag android:"path" but is not a string or slice of strings, it is a %s`,
+						v.Type().FieldByIndex(i).Name, v.Type(), sv.Type()))
+				}
 			default:
 				panic(fmt.Errorf(`field %s in type %s has tag android:"path" but is not a string or slice of strings, it is a %s`,
 					v.Type().FieldByIndex(i).Name, v.Type(), sv.Type()))
diff --git a/android/selects_test.go b/android/selects_test.go
index dca3789..aa9c521 100644
--- a/android/selects_test.go
+++ b/android/selects_test.go
@@ -80,6 +80,36 @@
 			},
 		},
 		{
+			name: "basic paths",
+			bp: `
+			my_module_type {
+				name: "foo",
+				my_paths: select(soong_config_variable("my_namespace", "my_variable"), {
+					"a": ["foo.txt"],
+					"b": ["bar.txt"],
+					_: ["baz.txt"],
+				}),
+			}
+			`,
+			provider: selectsTestProvider{
+				my_paths: &[]string{"baz.txt"},
+			},
+		},
+		{
+			name: "paths with module references",
+			bp: `
+			my_module_type {
+				name: "foo",
+				my_paths: select(soong_config_variable("my_namespace", "my_variable"), {
+					"a": [":a"],
+					"b": [":b"],
+					_: [":c"],
+				}),
+			}
+			`,
+			expectedError: `"foo" depends on undefined module "c"`,
+		},
+		{
 			name: "Differing types",
 			bp: `
 			my_module_type {
@@ -233,6 +263,7 @@
 	my_bool        *bool
 	my_string      *string
 	my_string_list *[]string
+	my_paths       *[]string
 }
 
 func (p *selectsTestProvider) String() string {
@@ -248,7 +279,8 @@
 	my_bool: %v,
 	my_string: %s,
     my_string_list: %s,
-}`, myBoolStr, myStringStr, p.my_string_list)
+    my_paths: %s,
+}`, myBoolStr, myStringStr, p.my_string_list, p.my_paths)
 }
 
 var selectsTestProviderKey = blueprint.NewProvider[selectsTestProvider]()
@@ -257,6 +289,7 @@
 	My_bool        proptools.Configurable[bool]
 	My_string      proptools.Configurable[string]
 	My_string_list proptools.Configurable[[]string]
+	My_paths       proptools.Configurable[[]string] `android:"path"`
 }
 
 type selectsMockModule struct {
@@ -266,10 +299,11 @@
 }
 
 func (p *selectsMockModule) GenerateAndroidBuildActions(ctx ModuleContext) {
-	SetProvider[selectsTestProvider](ctx, selectsTestProviderKey, selectsTestProvider{
+	SetProvider(ctx, selectsTestProviderKey, selectsTestProvider{
 		my_bool:        p.properties.My_bool.Evaluate(ctx),
 		my_string:      p.properties.My_string.Evaluate(ctx),
 		my_string_list: p.properties.My_string_list.Evaluate(ctx),
+		my_paths:       p.properties.My_paths.Evaluate(ctx),
 	})
 }
 
diff --git a/android/variable.go b/android/variable.go
index be3c80d..73f5bfd 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -500,6 +500,8 @@
 	HiddenapiExportableStubs *bool `json:",omitempty"`
 
 	ExportRuntimeApis *bool `json:",omitempty"`
+
+	AconfigContainerValidation string `json:",omitempty"`
 }
 
 type PartitionQualifiedVariablesType struct {
diff --git a/android/visibility.go b/android/visibility.go
index b387562..79a534f 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -303,7 +303,10 @@
 
 		if pkg == "visibility" {
 			switch name {
-			case "private", "public", "any_partition":
+			case "private", "public":
+			case "any_partition":
+				// any_partition can be used with another visibility fields
+				continue
 			case "legacy_public":
 				ctx.PropertyErrorf(property, "//visibility:legacy_public must not be used")
 				continue
diff --git a/android/visibility_test.go b/android/visibility_test.go
index d4add7d..bb43b1f 100644
--- a/android/visibility_test.go
+++ b/android/visibility_test.go
@@ -1921,6 +1921,26 @@
 		},
 	},
 	{
+		name: "any_partition visibility works with the other visibility",
+		fs: MockFS{
+			"top/Android.bp": []byte(`
+				android_filesystem {
+					name: "foo",
+					deps: ["bar"],
+				}`),
+			"top2/Android.bp": []byte(``),
+			"top/nested/Android.bp": []byte(`
+				package(default_visibility=["//visibility:private"])
+				mock_library {
+					name: "bar",
+					visibility: [
+						"//top2",
+						"//visibility:any_partition"
+					],
+				}`),
+		},
+	},
+	{
 		name: "any_partition visibility doesn't work for non-partitions",
 		fs: MockFS{
 			"top/Android.bp": []byte(`
diff --git a/apex/aconfig_test.go b/apex/aconfig_test.go
new file mode 100644
index 0000000..be98d45
--- /dev/null
+++ b/apex/aconfig_test.go
@@ -0,0 +1,550 @@
+// 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 apex
+
+import (
+	"testing"
+
+	"android/soong/aconfig/codegen"
+	"android/soong/android"
+	"android/soong/cc"
+	"android/soong/genrule"
+	"android/soong/java"
+	"android/soong/rust"
+	"github.com/google/blueprint/proptools"
+)
+
+var withAconfigValidationError = android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+	variables.AconfigContainerValidation = "error"
+	variables.BuildId = proptools.StringPtr("TEST.BUILD_ID")
+})
+
+func TestValidationAcrossContainersExportedPass(t *testing.T) {
+	testCases := []struct {
+		name string
+		bp   string
+	}{
+		{
+			name: "Java lib passes for exported containers cross",
+			bp: apex_default_bp + `
+				apex {
+					name: "myapex",
+					manifest: ":myapex.manifest",
+					androidManifest: ":myapex.androidmanifest",
+					key: "myapex.key",
+					java_libs: [
+						"my_java_library_foo",
+					],
+					updatable: false,
+				}
+				java_library {
+					name: "my_java_library_foo",
+					srcs: ["foo/bar/MyClass.java"],
+					sdk_version: "none",
+					system_modules: "none",
+					static_libs: ["my_java_aconfig_library_foo"],
+					apex_available: [
+						"myapex",
+					],
+				}
+				aconfig_declarations {
+					name: "my_aconfig_declarations_foo",
+					package: "com.example.package",
+					container: "otherapex",
+					srcs: ["foo.aconfig"],
+					exportable: true,
+				}
+				java_aconfig_library {
+					name: "my_java_aconfig_library_foo",
+					aconfig_declarations: "my_aconfig_declarations_foo",
+					mode: "exported",
+					apex_available: [
+						"myapex",
+					],
+				}`,
+		},
+		{
+			name: "Android app passes for exported containers cross",
+			bp: apex_default_bp + `
+				apex {
+					name: "myapex",
+					manifest: ":myapex.manifest",
+					androidManifest: ":myapex.androidmanifest",
+					key: "myapex.key",
+					apps: [
+						"my_android_app_foo",
+					],
+					updatable: false,
+				}
+				android_app {
+					name: "my_android_app_foo",
+					srcs: ["foo/MyClass.java"],
+					sdk_version: "none",
+					system_modules: "none",
+					stl: "none",
+					static_libs: ["my_java_library_bar"],
+					apex_available: [ "myapex" ],
+				}
+				java_library {
+					name: "my_java_library_bar",
+					srcs: ["foo/bar/MyClass.java"],
+					sdk_version: "none",
+					system_modules: "none",
+					static_libs: ["my_java_aconfig_library_bar"],
+					apex_available: [
+						"myapex",
+					],
+				}
+				aconfig_declarations {
+					name: "my_aconfig_declarations_bar",
+					package: "com.example.package",
+					container: "otherapex",
+					srcs: ["bar.aconfig"],
+					exportable: true,
+				}
+				java_aconfig_library {
+					name: "my_java_aconfig_library_bar",
+					aconfig_declarations: "my_aconfig_declarations_bar",
+					mode: "exported",
+					apex_available: [
+						"myapex",
+					],
+				}`,
+		},
+		{
+			name: "Cc lib passes for exported containers cross",
+			bp: apex_default_bp + `
+				apex {
+					name: "myapex",
+					manifest: ":myapex.manifest",
+					androidManifest: ":myapex.androidmanifest",
+					key: "myapex.key",
+					native_shared_libs: [
+						"my_cc_library_bar",
+					],
+					binaries: [
+						"my_cc_binary_baz",
+					],
+					updatable: false,
+				}
+				cc_library {
+					name: "my_cc_library_bar",
+					srcs: ["foo/bar/MyClass.cc"],
+					static_libs: [
+						"my_cc_aconfig_library_bar",
+						"my_cc_aconfig_library_baz",
+					],
+					apex_available: [
+						"myapex",
+					],
+				}
+				cc_binary {
+					name: "my_cc_binary_baz",
+					srcs: ["foo/bar/MyClass.cc"],
+					static_libs: ["my_cc_aconfig_library_baz"],
+					apex_available: [
+						"myapex",
+					],
+				}
+				cc_library {
+					name: "server_configurable_flags",
+					srcs: ["server_configurable_flags.cc"],
+				}
+				aconfig_declarations {
+					name: "my_aconfig_declarations_bar",
+					package: "com.example.package",
+					container: "otherapex",
+					srcs: ["bar.aconfig"],
+					exportable: true,
+				}
+				cc_aconfig_library {
+					name: "my_cc_aconfig_library_bar",
+					aconfig_declarations: "my_aconfig_declarations_bar",
+					apex_available: [
+						"myapex",
+					],
+					mode: "exported",
+				}
+				aconfig_declarations {
+					name: "my_aconfig_declarations_baz",
+					package: "com.example.package",
+					container: "otherapex",
+					srcs: ["baz.aconfig"],
+					exportable: true,
+				}
+				cc_aconfig_library {
+					name: "my_cc_aconfig_library_baz",
+					aconfig_declarations: "my_aconfig_declarations_baz",
+					apex_available: [
+						"myapex",
+					],
+					mode: "exported",
+				}`,
+		},
+	}
+	for _, test := range testCases {
+		t.Run(test.name, func(t *testing.T) {
+			android.GroupFixturePreparers(
+				java.PrepareForTestWithJavaDefaultModules,
+				cc.PrepareForTestWithCcBuildComponents,
+				rust.PrepareForTestWithRustDefaultModules,
+				codegen.PrepareForTestWithAconfigBuildComponents,
+				PrepareForTestWithApexBuildComponents,
+				prepareForTestWithMyapex,
+				withAconfigValidationError,
+			).
+				RunTestWithBp(t, test.bp)
+		})
+	}
+}
+
+func TestValidationAcrossContainersNotExportedFail(t *testing.T) {
+	testCases := []struct {
+		name          string
+		expectedError string
+		bp            string
+	}{
+		{
+			name: "Java lib fails for non-exported containers cross",
+			bp: apex_default_bp + `
+				apex {
+					name: "myapex",
+					manifest: ":myapex.manifest",
+					androidManifest: ":myapex.androidmanifest",
+					key: "myapex.key",
+					java_libs: [
+						"my_java_library_foo",
+					],
+					updatable: false,
+				}
+				java_library {
+					name: "my_java_library_foo",
+					srcs: ["foo/bar/MyClass.java"],
+					sdk_version: "none",
+					system_modules: "none",
+					static_libs: ["my_java_aconfig_library_foo"],
+					apex_available: [
+						"myapex",
+					],
+				}
+				aconfig_declarations {
+					name: "my_aconfig_declarations_foo",
+					package: "com.example.package",
+					container: "otherapex",
+					srcs: ["foo.aconfig"],
+				}
+				java_aconfig_library {
+					name: "my_java_aconfig_library_foo",
+					aconfig_declarations: "my_aconfig_declarations_foo",
+					apex_available: [
+						"myapex",
+					],
+				}`,
+			expectedError: `.*my_java_library_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
+		},
+		{
+			name: "Android app fails for non-exported containers cross",
+			bp: apex_default_bp + `
+				apex {
+					name: "myapex",
+					manifest: ":myapex.manifest",
+					androidManifest: ":myapex.androidmanifest",
+					key: "myapex.key",
+					apps: [
+						"my_android_app_foo",
+					],
+					updatable: false,
+				}
+				android_app {
+					name: "my_android_app_foo",
+					srcs: ["foo/MyClass.java"],
+					sdk_version: "none",
+					system_modules: "none",
+					stl: "none",
+					static_libs: ["my_java_library_foo"],
+					apex_available: [ "myapex" ],
+				}
+				java_library {
+					name: "my_java_library_foo",
+					srcs: ["foo/bar/MyClass.java"],
+					sdk_version: "none",
+					system_modules: "none",
+					static_libs: ["my_java_aconfig_library_foo"],
+					apex_available: [
+						"myapex",
+					],
+				}
+				aconfig_declarations {
+					name: "my_aconfig_declarations_foo",
+					package: "com.example.package",
+					container: "otherapex",
+					srcs: ["bar.aconfig"],
+				}
+				java_aconfig_library {
+					name: "my_java_aconfig_library_foo",
+					aconfig_declarations: "my_aconfig_declarations_foo",
+					apex_available: [
+						"myapex",
+					],
+				}`,
+			expectedError: `.*my_android_app_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
+		},
+		{
+			name: "Cc lib fails for non-exported containers cross",
+			bp: apex_default_bp + `
+				apex {
+					name: "myapex",
+					manifest: ":myapex.manifest",
+					androidManifest: ":myapex.androidmanifest",
+					key: "myapex.key",
+					native_shared_libs: [
+						"my_cc_library_foo",
+					],
+					updatable: false,
+				}
+				cc_library {
+					name: "my_cc_library_foo",
+					srcs: ["foo/bar/MyClass.cc"],
+					shared_libs: [
+						"my_cc_aconfig_library_foo",
+					],
+					apex_available: [
+						"myapex",
+					],
+				}
+				cc_library {
+					name: "server_configurable_flags",
+					srcs: ["server_configurable_flags.cc"],
+				}
+				aconfig_declarations {
+					name: "my_aconfig_declarations_foo",
+					package: "com.example.package",
+					container: "otherapex",
+					srcs: ["foo.aconfig"],
+				}
+				cc_aconfig_library {
+					name: "my_cc_aconfig_library_foo",
+					aconfig_declarations: "my_aconfig_declarations_foo",
+					apex_available: [
+						"myapex",
+					],
+				}`,
+			expectedError: `.*my_cc_library_foo/myapex depends on my_cc_aconfig_library_foo/otherapex/production across containers`,
+		},
+		{
+			name: "Cc binary fails for non-exported containers cross",
+			bp: apex_default_bp + `
+				apex {
+					name: "myapex",
+					manifest: ":myapex.manifest",
+					androidManifest: ":myapex.androidmanifest",
+					key: "myapex.key",
+					binaries: [
+						"my_cc_binary_foo",
+					],
+					updatable: false,
+				}
+				cc_library {
+					name: "my_cc_library_foo",
+					srcs: ["foo/bar/MyClass.cc"],
+					static_libs: [
+						"my_cc_aconfig_library_foo",
+					],
+					apex_available: [
+						"myapex",
+					],
+				}
+				cc_binary {
+					name: "my_cc_binary_foo",
+					srcs: ["foo/bar/MyClass.cc"],
+					static_libs: ["my_cc_library_foo"],
+					apex_available: [
+						"myapex",
+					],
+				}
+				cc_library {
+					name: "server_configurable_flags",
+					srcs: ["server_configurable_flags.cc"],
+				}
+				aconfig_declarations {
+					name: "my_aconfig_declarations_foo",
+					package: "com.example.package",
+					container: "otherapex",
+					srcs: ["foo.aconfig"],
+				}
+				cc_aconfig_library {
+					name: "my_cc_aconfig_library_foo",
+					aconfig_declarations: "my_aconfig_declarations_foo",
+					apex_available: [
+						"myapex",
+					],
+				}`,
+			expectedError: `.*my_cc_binary_foo/myapex depends on my_cc_aconfig_library_foo/otherapex/production across containers`,
+		},
+		{
+			name: "Aconfig validation propagate along sourceOrOutputDependencyTag",
+			bp: apex_default_bp + `
+				apex {
+					name: "myapex",
+					manifest: ":myapex.manifest",
+					androidManifest: ":myapex.androidmanifest",
+					key: "myapex.key",
+					apps: [
+						"my_android_app_foo",
+					],
+					updatable: false,
+				}
+				android_app {
+					name: "my_android_app_foo",
+					srcs: ["foo/MyClass.java"],
+					sdk_version: "none",
+					system_modules: "none",
+					stl: "none",
+					static_libs: ["my_java_library_foo"],
+					apex_available: [ "myapex" ],
+				}
+				java_library {
+					name: "my_java_library_foo",
+					srcs: [":my_genrule_foo"],
+					sdk_version: "none",
+					system_modules: "none",
+					apex_available: [
+						"myapex",
+					],
+				}
+				aconfig_declarations_group {
+						name: "my_aconfig_declarations_group_foo",
+						java_aconfig_libraries: [
+								"my_java_aconfig_library_foo",
+						],
+				}
+				filegroup {
+						name: "my_filegroup_foo_srcjars",
+						srcs: [
+								":my_aconfig_declarations_group_foo{.srcjars}",
+						],
+				}
+				genrule {
+						name: "my_genrule_foo",
+						srcs: [":my_filegroup_foo_srcjars"],
+						cmd: "cp $(in) $(out)",
+						out: ["my_genrule_foo.srcjar"],
+				}
+				aconfig_declarations {
+					name: "my_aconfig_declarations_foo",
+					package: "com.example.package",
+					container: "otherapex",
+					srcs: ["bar.aconfig"],
+				}
+				java_aconfig_library {
+					name: "my_java_aconfig_library_foo",
+					aconfig_declarations: "my_aconfig_declarations_foo",
+					apex_available: [
+						"myapex",
+					],
+				}`,
+			expectedError: `.*my_android_app_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
+		},
+	}
+	for _, test := range testCases {
+		t.Run(test.name, func(t *testing.T) {
+			errorHandler := android.FixtureExpectsNoErrors
+			if test.expectedError != "" {
+				errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError)
+			}
+			android.GroupFixturePreparers(
+				java.PrepareForTestWithJavaDefaultModules,
+				cc.PrepareForTestWithCcBuildComponents,
+				rust.PrepareForTestWithRustDefaultModules,
+				codegen.PrepareForTestWithAconfigBuildComponents,
+				genrule.PrepareForIntegrationTestWithGenrule,
+				PrepareForTestWithApexBuildComponents,
+				prepareForTestWithMyapex,
+				withAconfigValidationError,
+			).
+				ExtendWithErrorHandler(errorHandler).
+				RunTestWithBp(t, test.bp)
+		})
+	}
+}
+
+func TestValidationNotPropagateAcrossShared(t *testing.T) {
+	testCases := []struct {
+		name string
+		bp   string
+	}{
+		{
+			name: "Java shared lib not propagate aconfig validation",
+			bp: apex_default_bp + `
+				apex {
+					name: "myapex",
+					manifest: ":myapex.manifest",
+					androidManifest: ":myapex.androidmanifest",
+					key: "myapex.key",
+					java_libs: [
+						"my_java_library_bar",
+					],
+					updatable: false,
+				}
+				java_library {
+					name: "my_java_library_bar",
+					srcs: ["foo/bar/MyClass.java"],
+					sdk_version: "none",
+					system_modules: "none",
+					libs: ["my_java_library_foo"],
+					apex_available: [
+						"myapex",
+					],
+				}
+				java_library {
+					name: "my_java_library_foo",
+					srcs: ["foo/bar/MyClass.java"],
+					sdk_version: "none",
+					system_modules: "none",
+					static_libs: ["my_java_aconfig_library_foo"],
+					apex_available: [
+						"myapex",
+					],
+				}
+				aconfig_declarations {
+					name: "my_aconfig_declarations_foo",
+					package: "com.example.package",
+					container: "otherapex",
+					srcs: ["foo.aconfig"],
+				}
+				java_aconfig_library {
+					name: "my_java_aconfig_library_foo",
+					aconfig_declarations: "my_aconfig_declarations_foo",
+					apex_available: [
+						"myapex",
+					],
+				}`,
+		},
+	}
+	for _, test := range testCases {
+		t.Run(test.name, func(t *testing.T) {
+			android.GroupFixturePreparers(
+				java.PrepareForTestWithJavaDefaultModules,
+				cc.PrepareForTestWithCcBuildComponents,
+				rust.PrepareForTestWithRustDefaultModules,
+				codegen.PrepareForTestWithAconfigBuildComponents,
+				PrepareForTestWithApexBuildComponents,
+				prepareForTestWithMyapex,
+				withAconfigValidationError,
+			).
+				RunTestWithBp(t, test.bp)
+		})
+	}
+}
diff --git a/apex/apex.go b/apex/apex.go
index c688438..32a3638 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2321,9 +2321,15 @@
 }
 
 func addAconfigFiles(vctx *visitorContext, ctx android.ModuleContext, module blueprint.Module) {
-	dep, _ := android.OtherModuleProvider(ctx, module, android.AconfigTransitiveDeclarationsInfoProvider)
-	if len(dep.AconfigFiles) > 0 && dep.AconfigFiles[ctx.ModuleName()] != nil {
-		vctx.aconfigFiles = append(vctx.aconfigFiles, dep.AconfigFiles[ctx.ModuleName()]...)
+	if dep, ok := android.OtherModuleProvider(ctx, module, android.AconfigTransitiveDeclarationsInfoProvider); ok {
+		if len(dep.AconfigFiles) > 0 && dep.AconfigFiles[ctx.ModuleName()] != nil {
+			vctx.aconfigFiles = append(vctx.aconfigFiles, dep.AconfigFiles[ctx.ModuleName()]...)
+		}
+	}
+
+	validationFlag := ctx.DeviceConfig().AconfigContainerValidation()
+	if validationFlag == "error" || validationFlag == "warning" {
+		android.VerifyAconfigBuildMode(ctx, ctx.ModuleName(), module, validationFlag == "error")
 	}
 }
 
@@ -2428,29 +2434,14 @@
 	a.providePrebuiltInfo(ctx)
 }
 
-var prebuiltInfoProvider = blueprint.NewProvider[prebuiltInfo]()
-
-// contents of prebuilt_info.json
-type prebuiltInfo struct {
-	// Name of the apex, without the prebuilt_ prefix
-	Name string
-
-	Is_prebuilt bool
-
-	// This is relative to root of the workspace.
-	// In case of mainline modules, this file contains the build_id that was used
-	// to generate the mainline module prebuilt.
-	Prebuilt_info_file_path string `json:",omitempty"`
-}
-
 // Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
 // with information about whether source or prebuilt of an apex was used during the build.
 func (a *apexBundle) providePrebuiltInfo(ctx android.ModuleContext) {
-	info := prebuiltInfo{
+	info := android.PrebuiltInfo{
 		Name:        a.Name(),
 		Is_prebuilt: false,
 	}
-	android.SetProvider(ctx, prebuiltInfoProvider, info)
+	android.SetProvider(ctx, android.PrebuiltInfoProvider, info)
 }
 
 // Set a provider containing information about the jars and .prof provided by the apex
diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go
index 8aaddbe..e6ebff2 100644
--- a/apex/apex_singleton.go
+++ b/apex/apex_singleton.go
@@ -149,10 +149,10 @@
 }
 
 func (a *apexPrebuiltInfo) GenerateBuildActions(ctx android.SingletonContext) {
-	prebuiltInfos := []prebuiltInfo{}
+	prebuiltInfos := []android.PrebuiltInfo{}
 
 	ctx.VisitAllModules(func(m android.Module) {
-		prebuiltInfo, exists := android.SingletonModuleProvider(ctx, m, prebuiltInfoProvider)
+		prebuiltInfo, exists := android.SingletonModuleProvider(ctx, m, android.PrebuiltInfoProvider)
 		// Use prebuiltInfoProvider to filter out non apex soong modules.
 		// Use HideFromMake to filter out the unselected variants of a specific apex.
 		if exists && !m.IsHideFromMake() {
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 34dfc46..ea847e1 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -827,15 +827,15 @@
 // Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
 // with information about whether source or prebuilt of an apex was used during the build.
 func (p *prebuiltCommon) providePrebuiltInfo(ctx android.ModuleContext) {
-	info := prebuiltInfo{
-		Name:        p.BaseModuleName(), // BaseModuleName ensures that this will not contain the prebuilt_ prefix.
+	info := android.PrebuiltInfo{
+		Name:        p.BaseModuleName(),
 		Is_prebuilt: true,
 	}
 	// If Prebuilt_info information is available in the soong module definition, add it to prebuilt_info.json.
 	if p.prebuiltCommonProperties.Prebuilt_info != nil {
 		info.Prebuilt_info_file_path = android.PathForModuleSrc(ctx, *p.prebuiltCommonProperties.Prebuilt_info).String()
 	}
-	android.SetProvider(ctx, prebuiltInfoProvider, info)
+	android.SetProvider(ctx, android.PrebuiltInfoProvider, info)
 }
 
 func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
diff --git a/cc/cc.go b/cc/cc.go
index 2770fb2..0fa3457 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -766,6 +766,12 @@
 
 var _ android.InstallNeededDependencyTag = libraryDependencyTag{}
 
+func (d libraryDependencyTag) PropagateAconfigValidation() bool {
+	return d.static()
+}
+
+var _ android.PropagateAconfigValidationDependencyTag = libraryDependencyTag{}
+
 // dependencyTag is used for tagging miscellaneous dependency types that don't fit into
 // libraryDependencyTag.  Each tag object is created globally and reused for multiple
 // dependencies (although since the object contains no references, assigning a tag to a
diff --git a/java/app.go b/java/app.go
index 8209d4c..4f6f1f3 100755
--- a/java/app.go
+++ b/java/app.go
@@ -912,6 +912,13 @@
 	}
 
 	a.buildAppDependencyInfo(ctx)
+
+	providePrebuiltInfo(ctx,
+		prebuiltInfoProps{
+			baseModuleName: a.BaseModuleName(),
+			isPrebuilt:     false,
+		},
+	)
 }
 
 type appDepsInterface interface {
diff --git a/java/app_import.go b/java/app_import.go
index dc84fc2..7387e16 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -150,6 +150,11 @@
 	// If unspecified, follows the naming convention that the source module of
 	// the prebuilt is Name() without "prebuilt_" prefix
 	Source_module_name *string
+
+	// Path to the .prebuilt_info file of the prebuilt app.
+	// In case of mainline modules, the .prebuilt_info file contains the build_id that was used
+	// to generate the prebuilt.
+	Prebuilt_info *string `android:"path"`
 }
 
 func (a *AndroidAppImport) IsInstallable() bool {
@@ -413,6 +418,14 @@
 	}
 	android.CollectDependencyAconfigFiles(ctx, &a.mergedAconfigFiles)
 
+	providePrebuiltInfo(ctx,
+		prebuiltInfoProps{
+			baseModuleName: a.BaseModuleName(),
+			isPrebuilt:     true,
+			prebuiltInfo:   a.properties.Prebuilt_info,
+		},
+	)
+
 	// TODO: androidmk converter jni libs
 }
 
diff --git a/java/app_set.go b/java/app_set.go
index d2d3b06..33d3ade 100644
--- a/java/app_set.go
+++ b/java/app_set.go
@@ -48,6 +48,11 @@
 	// Names of modules to be overridden. Listed modules can only be other apps
 	//	(in Make or Soong).
 	Overrides []string
+
+	// Path to the .prebuilt_info file of the prebuilt app.
+	// In case of mainline modules, the .prebuilt_info file contains the build_id that was used
+	// to generate the prebuilt.
+	Prebuilt_info *string `android:"path"`
 }
 
 type AndroidAppSet struct {
@@ -117,6 +122,27 @@
 	return result
 }
 
+type prebuiltInfoProps struct {
+	baseModuleName string
+	isPrebuilt     bool
+	prebuiltInfo   *string
+}
+
+// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
+// with information about whether source or prebuilt of an apex was used during the build.
+func providePrebuiltInfo(ctx android.ModuleContext, p prebuiltInfoProps) {
+	info := android.PrebuiltInfo{
+		Name:        p.baseModuleName,
+		Is_prebuilt: p.isPrebuilt,
+	}
+	// If Prebuilt_info information is available in the soong module definition, add it to prebuilt_info.json.
+	if p.prebuiltInfo != nil {
+		prebuiltInfoFile := android.PathForModuleSrc(ctx, *p.prebuiltInfo)
+		info.Prebuilt_info_file_path = prebuiltInfoFile.String()
+	}
+	android.SetProvider(ctx, android.PrebuiltInfoProvider, info)
+}
+
 func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	as.packedOutput = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
 	as.primaryOutput = android.PathForModuleOut(ctx, as.BaseModuleName()+".apk")
@@ -157,6 +183,15 @@
 		installDir = android.PathForModuleInstall(ctx, "app", as.BaseModuleName())
 	}
 	ctx.InstallFileWithExtraFilesZip(installDir, as.BaseModuleName()+".apk", as.primaryOutput, as.packedOutput)
+
+	providePrebuiltInfo(ctx,
+		prebuiltInfoProps{
+			baseModuleName: as.BaseModuleName(),
+			isPrebuilt:     true,
+			prebuiltInfo:   as.properties.Prebuilt_info,
+		},
+	)
+
 }
 
 func (as *AndroidAppSet) InstallBypassMake() bool { return true }
diff --git a/java/base.go b/java/base.go
index d8ccec6..69f88be 100644
--- a/java/base.go
+++ b/java/base.go
@@ -26,7 +26,6 @@
 	"github.com/google/blueprint/pathtools"
 	"github.com/google/blueprint/proptools"
 
-	"android/soong/aconfig"
 	"android/soong/android"
 	"android/soong/dexpreopt"
 	"android/soong/java/config"
@@ -2551,7 +2550,7 @@
 				default:
 					return RenameUseExclude, "srcfile"
 				}
-			} else if _, ok := android.OtherModuleProvider(ctx, m, aconfig.CodegenInfoProvider); ok {
+			} else if _, ok := android.OtherModuleProvider(ctx, m, android.CodegenInfoProvider); ok {
 				return RenameUseInclude, "aconfig_declarations_group"
 			} else {
 				switch tag {
diff --git a/java/builder.go b/java/builder.go
index b07a622..5d84d0b 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -120,6 +120,8 @@
 				`--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED ` +
 				`--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED ` +
 				`--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED ` +
+				`--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED ` +
+				`--add-exports=jdk.internal.opt/jdk.internal.opt=ALL-UNNAMED ` +
 				`-jar ${config.JavaKytheExtractorJar} ` +
 				`${config.JavacHeapFlags} ${config.CommonJdkFlags} ` +
 				`$processorpath $processor $javacFlags $bootClasspath $classpath ` +
diff --git a/java/dex.go b/java/dex.go
index 4474c63..b721f58 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -223,6 +223,16 @@
 	if err != nil {
 		ctx.PropertyErrorf("min_sdk_version", "%s", err)
 	}
+	if effectiveVersion.FinalOrFutureInt() >= 35 {
+		// V is 35, but we have not bumped the SDK version yet, so check for both.
+		if ctx.Config().PlatformSdkVersion().FinalInt() >= 35 ||
+			ctx.Config().PlatformSdkCodename() == "VanillaIceCream" {
+			// TODO(b/329465418): Skip this module since it causes issue with app DRM
+			if ctx.ModuleName() != "framework-minus-apex" {
+				flags = append([]string{"-JDcom.android.tools.r8.dexContainerExperiment"}, flags...)
+			}
+		}
+	}
 
 	// If the specified SDK level is 10000, then configure the compiler to use the
 	// current platform SDK level and to compile the build as a platform build.
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 6a66f45..aec40b3 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -21,7 +21,6 @@
 
 	"github.com/google/blueprint/proptools"
 
-	"android/soong/aconfig"
 	"android/soong/android"
 	"android/soong/java/config"
 )
@@ -414,7 +413,7 @@
 		case aconfigDeclarationTag:
 			if dep, ok := android.OtherModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey); ok {
 				deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPath)
-			} else if dep, ok := android.OtherModuleProvider(ctx, module, aconfig.CodegenInfoProvider); ok {
+			} else if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok {
 				deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
 			} else {
 				ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+
diff --git a/java/java.go b/java/java.go
index 6423eeb..e606993 100644
--- a/java/java.go
+++ b/java/java.go
@@ -24,7 +24,6 @@
 	"sort"
 	"strings"
 
-	"android/soong/aconfig"
 	"android/soong/remoteexec"
 	"android/soong/testing"
 
@@ -346,6 +345,12 @@
 	return j.kytheFiles
 }
 
+func (d dependencyTag) PropagateAconfigValidation() bool {
+	return d.static
+}
+
+var _ android.PropagateAconfigValidationDependencyTag = dependencyTag{}
+
 type dependencyTag struct {
 	blueprint.BaseDependencyTag
 	name string
@@ -355,6 +360,8 @@
 
 	// True if the dependency is a toolchain, for example an annotation processor.
 	toolchain bool
+
+	static bool
 }
 
 // installDependencyTag is a dependency tag that is annotated to cause the installed files of the
@@ -400,7 +407,7 @@
 var (
 	dataNativeBinsTag       = dependencyTag{name: "dataNativeBins"}
 	dataDeviceBinsTag       = dependencyTag{name: "dataDeviceBins"}
-	staticLibTag            = dependencyTag{name: "staticlib"}
+	staticLibTag            = dependencyTag{name: "staticlib", static: true}
 	libTag                  = dependencyTag{name: "javalib", runtimeLinked: true}
 	sdkLibTag               = dependencyTag{name: "sdklib", runtimeLinked: true}
 	java9LibTag             = dependencyTag{name: "java9lib", runtimeLinked: true}
@@ -2173,7 +2180,7 @@
 		case aconfigDeclarationTag:
 			if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
 				al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPath)
-			} else if provider, ok := android.OtherModuleProvider(ctx, dep, aconfig.CodegenInfoProvider); ok {
+			} else if provider, ok := android.OtherModuleProvider(ctx, dep, android.CodegenInfoProvider); ok {
 				al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPaths...)
 			} else {
 				ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+
diff --git a/java/system_modules.go b/java/system_modules.go
index 92e31cd..8e2d5d8 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -64,6 +64,7 @@
 			// useful on Android, and (b) it causes errors with later versions of jlink
 			// when the jdk.internal.module is absent from java.base (as it is here).
 			`  --disable-plugin system-modules && ` +
+			`rm -rf ${workDir} && ` +
 			`cp ${config.JrtFsJar} ${outDir}/lib/`,
 		CommandDeps: []string{
 			"${moduleInfoJavaPath}",
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index 82abba4..698aaf2 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -157,12 +157,11 @@
 		syspropDir := android.GenPathWithExt(ctx, "sysprop", syspropFile, "srcrust")
 		outputDir := syspropDir.Join(ctx, "src")
 		libPath := syspropDir.Join(ctx, "src", "lib.rs")
-		parsersPath := syspropDir.Join(ctx, "src", "gen_parsers_and_formatters.rs")
 
 		ctx.Build(pctx, android.BuildParams{
 			Rule:        syspropRust,
 			Description: "sysprop_rust " + syspropFile.Rel(),
-			Outputs:     android.WritablePaths{libPath, parsersPath},
+			Outputs:     android.WritablePaths{libPath},
 			Input:       syspropFile,
 			Implicit:    checkApiFileTimeStamp,
 			Args: map[string]string{
@@ -171,7 +170,7 @@
 			},
 		})
 
-		g.genSrcs = append(g.genSrcs, libPath, parsersPath)
+		g.genSrcs = append(g.genSrcs, libPath)
 	}
 }