Merge "apex: drop metadata gathering for multitree."
diff --git a/aidl_library/aidl_library.go b/aidl_library/aidl_library.go
index 9b5f0a8..8a84e6b 100644
--- a/aidl_library/aidl_library.go
+++ b/aidl_library/aidl_library.go
@@ -22,6 +22,10 @@
 	"github.com/google/blueprint/proptools"
 )
 
+var PrepareForTestWithAidlLibrary = android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+	registerAidlLibraryBuildComponents(ctx)
+})
+
 func init() {
 	registerAidlLibraryBuildComponents(android.InitRegistrationContext)
 }
diff --git a/aidl_library/aidl_library_test.go b/aidl_library/aidl_library_test.go
index 42fa536..d9b410a 100644
--- a/aidl_library/aidl_library_test.go
+++ b/aidl_library/aidl_library_test.go
@@ -19,10 +19,6 @@
 	"testing"
 )
 
-var PrepareForTestWithAidlLibrary = android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
-	registerAidlLibraryBuildComponents(ctx)
-})
-
 func TestAidlLibrary(t *testing.T) {
 	t.Parallel()
 	ctx := android.GroupFixturePreparers(
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 5b7f117..9700f8b 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -85,6 +85,7 @@
 		"development/apps/DevelopmentSettings":        Bp2BuildDefaultTrue,
 		"development/apps/Fallback":                   Bp2BuildDefaultTrue,
 		"development/apps/WidgetPreview":              Bp2BuildDefaultTrue,
+		"development/python-packages/adb":             Bp2BuildDefaultTrueRecursively,
 		"development/samples/BasicGLSurfaceView":      Bp2BuildDefaultTrue,
 		"development/samples/BluetoothChat":           Bp2BuildDefaultTrue,
 		"development/samples/BrokenKeyDerivation":     Bp2BuildDefaultTrue,
@@ -211,6 +212,7 @@
 		"frameworks/av/media/module/minijail":                Bp2BuildDefaultTrueRecursively,
 		"frameworks/av/services/minijail":                    Bp2BuildDefaultTrueRecursively,
 		"frameworks/base/libs/androidfw":                     Bp2BuildDefaultTrue,
+		"frameworks/base/libs/services":                      Bp2BuildDefaultTrue,
 		"frameworks/base/media/tests/MediaDump":              Bp2BuildDefaultTrue,
 		"frameworks/base/proto":                              Bp2BuildDefaultTrue,
 		"frameworks/base/services/tests/servicestests/aidl":  Bp2BuildDefaultTrue,
@@ -570,6 +572,9 @@
 		//external/fec
 		"libfec_rs",
 
+		//frameworks/base/core/java
+		"IDropBoxManagerService_aidl",
+
 		//system/core/libsparse
 		"libsparse",
 
@@ -751,6 +756,10 @@
 		"CaptivePortalLogin",
 
 		"libstagefright_headers",
+
+		// aidl
+		"aidl",
+		"libaidl-common",
 	}
 
 	Bp2buildModuleTypeAlwaysConvertList = []string{
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 5291eca..10cf60a 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -29,6 +29,7 @@
 	"android/soong/bazel/cquery"
 	"android/soong/shared"
 	"android/soong/starlark_fmt"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/metrics"
 
@@ -700,9 +701,6 @@
 		// We don't need to set --host_platforms because it's set in bazelrc files
 		// that the bazel shell script wrapper passes
 
-		// Explicitly disable downloading rules (such as canonical C++ and Java rules) from the network.
-		"--experimental_repository_disable_download",
-
 		// Suppress noise
 		"--ui_event_filters=-INFO",
 		"--noshow_progress",
diff --git a/android/config.go b/android/config.go
index 9e94e05..acadb3f 100644
--- a/android/config.go
+++ b/android/config.go
@@ -183,6 +183,16 @@
 	return String(c.config.productVariables.DeviceMaxPageSizeSupported)
 }
 
+// The release version passed to aconfig, derived from RELEASE_VERSION
+func (c Config) ReleaseVersion() string {
+	return c.config.productVariables.ReleaseVersion
+}
+
+// The flag values files passed to aconfig, derived from RELEASE_VERSION
+func (c Config) ReleaseDeviceConfigValueSets() []string {
+	return c.config.productVariables.ReleaseDeviceConfigValueSets
+}
+
 // A DeviceConfig object represents the configuration for a particular device
 // being built. For now there will only be one of these, but in the future there
 // may be multiple devices being built.
diff --git a/android/variable.go b/android/variable.go
index bf66135..97171e7 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -473,6 +473,9 @@
 	ProductManufacturer string   `json:",omitempty"`
 	ProductBrand        string   `json:",omitempty"`
 	BuildVersionTags    []string `json:",omitempty"`
+
+	ReleaseVersion               string   `json:",omitempty"`
+	ReleaseDeviceConfigValueSets []string `json:",omitempty"`
 }
 
 func boolPtr(v bool) *bool {
diff --git a/apex/apex.go b/apex/apex.go
index 026734e..ff7ee35 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -404,7 +404,7 @@
 	///////////////////////////////////////////////////////////////////////////////////////////
 	// Inputs
 
-	// Keys for apex_paylaod.img
+	// Keys for apex_payload.img
 	publicKeyFile  android.Path
 	privateKeyFile android.Path
 
@@ -2606,8 +2606,45 @@
 	ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
 	vctx.normalizeFileInfo(ctx)
 	if a.privateKeyFile == nil {
-		ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
-		return
+		if ctx.Config().AllowMissingDependencies() {
+			// TODO(b/266099037): a better approach for slim manifests.
+			ctx.AddMissingDependencies([]string{String(a.overridableProperties.Key)})
+			// Create placeholder paths for later stages that expect to see those paths,
+			// though they won't be used.
+			var unusedPath = android.PathForModuleOut(ctx, "nonexistentprivatekey")
+			ctx.Build(pctx, android.BuildParams{
+				Rule:   android.ErrorRule,
+				Output: unusedPath,
+				Args: map[string]string{
+					"error": "Private key not available",
+				},
+			})
+			a.privateKeyFile = unusedPath
+		} else {
+			ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
+			return
+		}
+	}
+
+	if a.publicKeyFile == nil {
+		if ctx.Config().AllowMissingDependencies() {
+			// TODO(b/266099037): a better approach for slim manifests.
+			ctx.AddMissingDependencies([]string{String(a.overridableProperties.Key)})
+			// Create placeholder paths for later stages that expect to see those paths,
+			// though they won't be used.
+			var unusedPath = android.PathForModuleOut(ctx, "nonexistentpublickey")
+			ctx.Build(pctx, android.BuildParams{
+				Rule:   android.ErrorRule,
+				Output: unusedPath,
+				Args: map[string]string{
+					"error": "Public key not available",
+				},
+			})
+			a.publicKeyFile = unusedPath
+		} else {
+			ctx.PropertyErrorf("key", "public_key for %q could not be found", String(a.overridableProperties.Key))
+			return
+		}
 	}
 
 	////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 6ca5afb..c1d80a3 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -1368,6 +1368,8 @@
 		cc_library {
 			name: "mylib",
 			srcs: ["mylib.cpp"],
+			static_libs: ["libstatic"],
+			shared_libs: ["libshared"],
 			runtime_libs: ["libfoo", "libbar"],
 			system_shared_libs: [],
 			stl: "none",
@@ -1392,6 +1394,39 @@
 			apex_available: [ "myapex" ],
 		}
 
+		cc_library {
+			name: "libstatic",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+			apex_available: [ "myapex" ],
+			runtime_libs: ["libstatic_to_runtime"],
+		}
+
+		cc_library {
+			name: "libshared",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+			apex_available: [ "myapex" ],
+			runtime_libs: ["libshared_to_runtime"],
+		}
+
+		cc_library {
+			name: "libstatic_to_runtime",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+			apex_available: [ "myapex" ],
+		}
+
+		cc_library {
+			name: "libshared_to_runtime",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+			apex_available: [ "myapex" ],
+		}
 	`)
 
 	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
@@ -1405,11 +1440,14 @@
 
 	// Ensure that runtime_libs dep in included
 	ensureContains(t, copyCmds, "image.apex/lib64/libbar.so")
+	ensureContains(t, copyCmds, "image.apex/lib64/libshared.so")
+	ensureContains(t, copyCmds, "image.apex/lib64/libshared_to_runtime.so")
+
+	ensureNotContains(t, copyCmds, "image.apex/lib64/libstatic_to_runtime.so")
 
 	apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
 	ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
 	ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.so")
-
 }
 
 var prepareForTestOfRuntimeApexWithHwasan = android.GroupFixturePreparers(
@@ -6541,6 +6579,72 @@
 	}`)
 }
 
+func TestApexAvailable_IndirectStaticDep(t *testing.T) {
+	testApex(t, `
+	apex {
+		name: "myapex",
+		key: "myapex.key",
+		native_shared_libs: ["libfoo"],
+		updatable: false,
+	}
+
+	apex_key {
+		name: "myapex.key",
+		public_key: "testkey.avbpubkey",
+		private_key: "testkey.pem",
+	}
+
+	cc_library {
+		name: "libfoo",
+		stl: "none",
+		static_libs: ["libbar"],
+		system_shared_libs: [],
+		apex_available: ["myapex"],
+	}
+
+	cc_library {
+		name: "libbar",
+		stl: "none",
+		shared_libs: ["libbaz"],
+		system_shared_libs: [],
+		apex_available: ["myapex"],
+	}
+
+	cc_library {
+		name: "libbaz",
+		stl: "none",
+		system_shared_libs: [],
+	}`)
+
+	testApexError(t, `requires "libbar" that doesn't list the APEX under 'apex_available'.`, `
+	apex {
+		name: "myapex",
+		key: "myapex.key",
+		native_shared_libs: ["libfoo"],
+		updatable: false,
+	}
+
+	apex_key {
+		name: "myapex.key",
+		public_key: "testkey.avbpubkey",
+		private_key: "testkey.pem",
+	}
+
+	cc_library {
+		name: "libfoo",
+		stl: "none",
+		static_libs: ["libbar"],
+		system_shared_libs: [],
+		apex_available: ["myapex"],
+	}
+
+	cc_library {
+		name: "libbar",
+		stl: "none",
+		system_shared_libs: [],
+	}`)
+}
+
 func TestApexAvailable_InvalidApexName(t *testing.T) {
 	testApexError(t, "\"otherapex\" is not a valid module name", `
 	apex {
diff --git a/bazel/configurability.go b/bazel/configurability.go
index d042fe8..8f63ec4 100644
--- a/bazel/configurability.go
+++ b/bazel/configurability.go
@@ -31,11 +31,11 @@
 
 	// OsType names in arch.go
 	OsAndroid     = "android"
-	osDarwin      = "darwin"
-	osLinux       = "linux_glibc"
+	OsDarwin      = "darwin"
+	OsLinux       = "linux_glibc"
 	osLinuxMusl   = "linux_musl"
 	osLinuxBionic = "linux_bionic"
-	osWindows     = "windows"
+	OsWindows     = "windows"
 
 	// Targets in arch.go
 	osArchAndroidArm        = "android_arm"
@@ -156,11 +156,11 @@
 	// constraint_value for the @platforms//os:os constraint_setting
 	platformOsMap = map[string]string{
 		OsAndroid:                  "//build/bazel/platforms/os:android",
-		osDarwin:                   "//build/bazel/platforms/os:darwin",
-		osLinux:                    "//build/bazel/platforms/os:linux_glibc",
+		OsDarwin:                   "//build/bazel/platforms/os:darwin",
+		OsLinux:                    "//build/bazel/platforms/os:linux_glibc",
 		osLinuxMusl:                "//build/bazel/platforms/os:linux_musl",
 		osLinuxBionic:              "//build/bazel/platforms/os:linux_bionic",
-		osWindows:                  "//build/bazel/platforms/os:windows",
+		OsWindows:                  "//build/bazel/platforms/os:windows",
 		ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
 	}
 
@@ -192,22 +192,22 @@
 	// in a cyclic dependency.
 	osToArchMap = map[string][]string{
 		OsAndroid:     {archArm, archArm64, archRiscv64, archX86, archX86_64},
-		osLinux:       {archX86, archX86_64},
+		OsLinux:       {archX86, archX86_64},
 		osLinuxMusl:   {archX86, archX86_64},
-		osDarwin:      {archArm64, archX86_64},
+		OsDarwin:      {archArm64, archX86_64},
 		osLinuxBionic: {archArm64, archX86_64},
 		// TODO(cparsons): According to arch.go, this should contain archArm, archArm64, as well.
-		osWindows: {archX86, archX86_64},
+		OsWindows: {archX86, archX86_64},
 	}
 
 	osAndInApexMap = map[string]string{
 		AndroidAndInApex:           "//build/bazel/rules/apex:android-in_apex",
 		AndroidPlatform:            "//build/bazel/rules/apex:system",
-		osDarwin:                   "//build/bazel/platforms/os:darwin",
-		osLinux:                    "//build/bazel/platforms/os:linux_glibc",
+		OsDarwin:                   "//build/bazel/platforms/os:darwin",
+		OsLinux:                    "//build/bazel/platforms/os:linux_glibc",
 		osLinuxMusl:                "//build/bazel/platforms/os:linux_musl",
 		osLinuxBionic:              "//build/bazel/platforms/os:linux_bionic",
-		osWindows:                  "//build/bazel/platforms/os:windows",
+		OsWindows:                  "//build/bazel/platforms/os:windows",
 		ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
 	}
 
diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go
index 89eac8a..6ec3703 100644
--- a/bp2build/cc_binary_conversion_test.go
+++ b/bp2build/cc_binary_conversion_test.go
@@ -644,10 +644,7 @@
 		targets: []testBazelTarget{
 			{"cc_binary", "foo", AttrNameToString{
 				"features": `select({
-        "//build/bazel/platforms/arch:arm": [
-            "arm_isa_arm",
-            "-arm_isa_thumb",
-        ],
+        "//build/bazel/platforms/arch:arm": ["arm_isa_arm"],
         "//conditions:default": [],
     })`,
 				"local_includes": `["."]`,
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 1b681ef..0e8705b 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -18,6 +18,7 @@
 	"fmt"
 	"testing"
 
+	"android/soong/aidl_library"
 	"android/soong/android"
 	"android/soong/cc"
 )
@@ -63,6 +64,7 @@
 	ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
 	ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory)
 	ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
+	ctx.RegisterModuleType("aidl_library", aidl_library.AidlLibraryFactory)
 }
 
 func TestCcLibrarySimple(t *testing.T) {
@@ -3219,10 +3221,7 @@
 `,
 		ExpectedBazelTargets: makeCcLibraryTargets("foo", AttrNameToString{
 			"features": `select({
-        "//build/bazel/platforms/arch:arm": [
-            "arm_isa_arm",
-            "-arm_isa_thumb",
-        ],
+        "//build/bazel/platforms/arch:arm": ["arm_isa_arm"],
         "//conditions:default": [],
     })`,
 			"local_includes": `["."]`,
@@ -3315,6 +3314,51 @@
 	})
 }
 
+func TestCcLibraryWithAidlLibrary(t *testing.T) {
+	runCcLibraryTestCase(t, Bp2buildTestCase{
+		Description:                "cc_library with aidl_library",
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Blueprint: `
+aidl_library {
+    name: "A_aidl",
+    srcs: ["aidl/A.aidl"],
+	hdrs: ["aidl/Header.aidl"],
+	strip_import_prefix: "aidl",
+}
+cc_library {
+	name: "foo",
+	aidl: {
+		libs: ["A_aidl"],
+	},
+	export_include_dirs: ["include"],
+}`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTargetNoRestrictions("aidl_library", "A_aidl", AttrNameToString{
+				"srcs":                `["aidl/A.aidl"]`,
+				"hdrs":                `["aidl/Header.aidl"]`,
+				"strip_import_prefix": `"aidl"`,
+				"tags":                `["apex_available=//apex_available:anyapex"]`,
+			}),
+			MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
+				"deps":            `[":A_aidl"]`,
+				"local_includes":  `["."]`,
+				"export_includes": `["include"]`,
+			}),
+			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+				"implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`,
+				"local_includes":                    `["."]`,
+				"export_includes":                   `["include"]`,
+			}),
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+				"implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`,
+				"local_includes":                    `["."]`,
+				"export_includes":                   `["include"]`,
+			}),
+		},
+	})
+}
+
 func TestCcLibraryWithAidlSrcs(t *testing.T) {
 	runCcLibraryTestCase(t, Bp2buildTestCase{
 		Description:                "cc_library with aidl srcs",
@@ -3343,6 +3387,7 @@
 				"srcs": `["B.aidl"]`,
 			}),
 			MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
+				"local_includes": `["."]`,
 				"deps": `[
         ":A_aidl",
         ":foo_aidl_library",
@@ -3382,7 +3427,8 @@
 }`,
 		ExpectedBazelTargets: []string{
 			MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
-				"deps": `["//path/to/A:A_aidl"]`,
+				"local_includes": `["."]`,
+				"deps":           `["//path/to/A:A_aidl"]`,
 			}),
 			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 				"implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`,
@@ -3397,37 +3443,78 @@
 }
 
 func TestCcLibraryWithExportAidlHeaders(t *testing.T) {
-	runCcLibraryTestCase(t, Bp2buildTestCase{
-		Description:                "cc_library with export aidl headers",
-		ModuleTypeUnderTest:        "cc_library",
-		ModuleTypeUnderTestFactory: cc.LibraryFactory,
-		Blueprint: `
-cc_library {
-    name: "foo",
-    srcs: [
-        "Foo.aidl",
-    ],
-    aidl: {
-        export_aidl_headers: true,
-    }
-}`,
-		ExpectedBazelTargets: []string{
-			MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{
-				"srcs": `["Foo.aidl"]`,
-			}),
-			MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
-				"deps": `[":foo_aidl_library"]`,
-			}),
-			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
-				"whole_archive_deps": `[":foo_cc_aidl_library"]`,
-				"local_includes":     `["."]`,
-			}),
-			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
-				"whole_archive_deps": `[":foo_cc_aidl_library"]`,
-				"local_includes":     `["."]`,
-			}),
+	t.Parallel()
+
+	expectedBazelTargets := []string{
+		MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
+			"local_includes": `["."]`,
+			"deps":           `[":foo_aidl_library"]`,
+		}),
+		MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+			"whole_archive_deps": `[":foo_cc_aidl_library"]`,
+			"local_includes":     `["."]`,
+		}),
+		MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			"whole_archive_deps": `[":foo_cc_aidl_library"]`,
+			"local_includes":     `["."]`,
+		}),
+	}
+	testCases := []struct {
+		description          string
+		bp                   string
+		expectedBazelTargets []string
+	}{
+		{
+			description: "cc_library with aidl srcs and aidl.export_aidl_headers set",
+			bp: `
+			cc_library {
+				name: "foo",
+				srcs: [
+					"Foo.aidl",
+				],
+				aidl: {
+					export_aidl_headers: true,
+				}
+			}`,
+			expectedBazelTargets: append(
+				expectedBazelTargets,
+				MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{
+					"srcs": `["Foo.aidl"]`,
+				})),
 		},
-	})
+		{
+			description: "cc_library with aidl.libs and aidl.export_aidl_headers set",
+			bp: `
+			aidl_library {
+				name: "foo_aidl_library",
+				srcs: ["Foo.aidl"],
+			}
+			cc_library {
+				name: "foo",
+				aidl: {
+					libs: ["foo_aidl_library"],
+					export_aidl_headers: true,
+				}
+			}`,
+			expectedBazelTargets: append(
+				expectedBazelTargets,
+				MakeBazelTargetNoRestrictions("aidl_library", "foo_aidl_library", AttrNameToString{
+					"srcs": `["Foo.aidl"]`,
+					"tags": `["apex_available=//apex_available:anyapex"]`,
+				}),
+			),
+		},
+	}
+
+	for _, testCase := range testCases {
+		runCcLibraryTestCase(t, Bp2buildTestCase{
+			Description:                "cc_library with export aidl headers",
+			ModuleTypeUnderTest:        "cc_library",
+			ModuleTypeUnderTestFactory: cc.LibraryFactory,
+			Blueprint:                  testCase.bp,
+			ExpectedBazelTargets:       testCase.expectedBazelTargets,
+		})
+	}
 }
 
 func TestCcLibraryWithTargetApex(t *testing.T) {
@@ -3642,7 +3729,8 @@
 				"srcs": `["Foo.aidl"]`,
 			}),
 			MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
-				"deps": `[":foo_aidl_library"]`,
+				"local_includes": `["."]`,
+				"deps":           `[":foo_aidl_library"]`,
 				"implementation_deps": `[
         ":baz-static",
         ":bar-static",
@@ -4519,3 +4607,105 @@
 	},
 	)
 }
+
+func TestCcLibraryYaccConversion(t *testing.T) {
+	runCcLibraryTestCase(t, Bp2buildTestCase{
+		Description:                "cc_library is built from .y/.yy files",
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Blueprint: soongCcLibraryPreamble + `cc_library {
+    name: "a",
+    srcs: [
+	"a.cpp",
+	"a.yy",
+    ],
+    shared_libs: ["sharedlib"],
+    static_libs: ["staticlib"],
+    yacc: {
+	    flags: ["someYaccFlag"],
+	    gen_location_hh: true,
+	    gen_position_hh: true,
+	},
+}
+cc_library_static {
+	name: "staticlib",
+	bazel_module: { bp2build_available: false },
+}
+cc_library {
+	name: "sharedlib",
+	bazel_module: { bp2build_available: false },
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("cc_yacc_static_library", "a_yacc", AttrNameToString{
+				"src":                         `"a.yy"`,
+				"implementation_deps":         `[":staticlib"]`,
+				"implementation_dynamic_deps": `[":sharedlib"]`,
+				"flags":                       `["someYaccFlag"]`,
+				"gen_location_hh":             "True",
+				"gen_position_hh":             "True",
+				"local_includes":              `["."]`,
+			}),
+			MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
+				"srcs":                              `["a.cpp"]`,
+				"implementation_deps":               `[":staticlib"]`,
+				"implementation_dynamic_deps":       `[":sharedlib"]`,
+				"implementation_whole_archive_deps": `[":a_yacc"]`,
+				"local_includes":                    `["."]`,
+			}),
+			MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
+				"srcs":                              `["a.cpp"]`,
+				"implementation_deps":               `[":staticlib"]`,
+				"implementation_dynamic_deps":       `[":sharedlib"]`,
+				"implementation_whole_archive_deps": `[":a_yacc"]`,
+				"local_includes":                    `["."]`,
+			}),
+		},
+	})
+}
+
+func TestCcLibraryHostLdLibs(t *testing.T) {
+	runCcLibraryTestCase(t, Bp2buildTestCase{
+		Description:                "cc_binary linker flags for host_ldlibs",
+		ModuleTypeUnderTest:        "cc_binary",
+		ModuleTypeUnderTestFactory: cc.BinaryFactory,
+		Blueprint: soongCcLibraryPreamble + `cc_binary {
+    name: "a",
+    host_supported: true,
+    ldflags: ["-lcommon"],
+    target: {
+	linux: {
+		host_ldlibs: [
+			"-llinux",
+		],
+	},
+	darwin: {
+		ldflags: ["-ldarwinadditional"],
+		host_ldlibs: [
+			"-ldarwin",
+		],
+	},
+	windows: {
+		host_ldlibs: [
+			"-lwindows",
+		],
+	},
+    },
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTargetNoRestrictions("cc_binary", "a", AttrNameToString{
+				"linkopts": `["-lcommon"] + select({
+        "//build/bazel/platforms/os:darwin": [
+            "-ldarwinadditional",
+            "-ldarwin",
+        ],
+        "//build/bazel/platforms/os:linux_glibc": ["-llinux"],
+        "//build/bazel/platforms/os:windows": ["-lwindows"],
+        "//conditions:default": [],
+    })`,
+				"local_includes": `["."]`,
+			}),
+		},
+	})
+}
diff --git a/cc/Android.bp b/cc/Android.bp
index be2cc5a..f49dc1a 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -9,6 +9,7 @@
         "blueprint",
         "blueprint-pathtools",
         "soong",
+        "soong-aidl-library",
         "soong-android",
         "soong-bazel",
         "soong-cc-config",
@@ -22,7 +23,6 @@
     srcs: [
         "afdo.go",
         "fdo_profile.go",
-
         "androidmk.go",
         "api_level.go",
         "bp2build.go",
diff --git a/cc/bp2build.go b/cc/bp2build.go
index cf5f74d..fa98df4 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -38,6 +38,7 @@
 	protoSrcPartition   = "proto"
 	aidlSrcPartition    = "aidl"
 	syspropSrcPartition = "sysprop"
+	yaccSrcPartition    = "yacc"
 
 	stubsSuffix = "_stub_libs_current"
 )
@@ -154,6 +155,7 @@
 		// know the language of these sources until the genrule is executed.
 		cppSrcPartition:     bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
 		syspropSrcPartition: bazel.LabelPartition{Extensions: []string{".sysprop"}},
+		yaccSrcPartition:    bazel.LabelPartition{Extensions: []string{".y", "yy"}},
 	}
 
 	return bazel.PartitionLabelListAttribute(ctx, &srcs, labels)
@@ -404,6 +406,12 @@
 	// Sysprop sources
 	syspropSrcs bazel.LabelListAttribute
 
+	// Yacc sources
+	yaccSrc               *bazel.LabelAttribute
+	yaccFlags             bazel.StringListAttribute
+	yaccGenLocationHeader bazel.BoolAttribute
+	yaccGenPositionHeader bazel.BoolAttribute
+
 	hdrs bazel.LabelListAttribute
 
 	rtti bazel.BoolAttribute
@@ -492,7 +500,7 @@
 
 	instructionSet := proptools.StringDefault(props.Instruction_set, "")
 	if instructionSet == "arm" {
-		ca.features.SetSelectValue(axis, config, []string{"arm_isa_arm", "-arm_isa_thumb"})
+		ca.features.SetSelectValue(axis, config, []string{"arm_isa_arm"})
 	} else if instructionSet != "" && instructionSet != "thumb" {
 		ctx.ModuleErrorf("Unknown value for instruction_set: %s", instructionSet)
 	}
@@ -566,6 +574,12 @@
 	ca.asmSrcs = partitionedSrcs[asmSrcPartition]
 	ca.lSrcs = partitionedSrcs[lSrcPartition]
 	ca.llSrcs = partitionedSrcs[llSrcPartition]
+	if yacc := partitionedSrcs[yaccSrcPartition]; !yacc.IsEmpty() {
+		if len(yacc.Value.Includes) > 1 {
+			ctx.PropertyErrorf("srcs", "Found multiple yacc (.y/.yy) files in library")
+		}
+		ca.yaccSrc = bazel.MakeLabelAttribute(yacc.Value.Includes[0].Label)
+	}
 	ca.syspropSrcs = partitionedSrcs[syspropSrcPartition]
 
 	ca.absoluteIncludes.DeduplicateAxesFromBase()
@@ -728,6 +742,8 @@
 	compilerAttrs := compilerAttributes{}
 	linkerAttrs := linkerAttributes{}
 
+	var aidlLibs bazel.LabelList
+
 	// Iterate through these axes in a deterministic order. This is required
 	// because processing certain dependencies may result in concatenating
 	// elements along other axes. (For example, processing NoConfig may result
@@ -742,7 +758,13 @@
 				if baseCompilerProps.Lex != nil {
 					compilerAttrs.lexopts.SetSelectValue(axis, cfg, baseCompilerProps.Lex.Flags)
 				}
+				if baseCompilerProps.Yacc != nil {
+					compilerAttrs.yaccFlags.SetSelectValue(axis, cfg, baseCompilerProps.Yacc.Flags)
+					compilerAttrs.yaccGenLocationHeader.SetSelectValue(axis, cfg, baseCompilerProps.Yacc.Gen_location_hh)
+					compilerAttrs.yaccGenPositionHeader.SetSelectValue(axis, cfg, baseCompilerProps.Yacc.Gen_position_hh)
+				}
 				(&compilerAttrs).bp2buildForAxisAndConfig(ctx, axis, cfg, baseCompilerProps)
+				aidlLibs.Append(android.BazelLabelForModuleDeps(ctx, baseCompilerProps.Aidl.Libs))
 			}
 
 			var exportHdrs []string
@@ -815,7 +837,15 @@
 	(&linkerAttrs).wholeArchiveDeps.Add(protoDep.wholeStaticLib)
 	(&linkerAttrs).implementationWholeArchiveDeps.Add(protoDep.implementationWholeStaticLib)
 
-	aidlDep := bp2buildCcAidlLibrary(ctx, module, compilerAttrs.aidlSrcs, linkerAttrs)
+	aidlDep := bp2buildCcAidlLibrary(
+		ctx, module,
+		compilerAttrs.aidlSrcs,
+		bazel.LabelListAttribute{
+			Value: aidlLibs,
+		},
+		linkerAttrs,
+		compilerAttrs,
+	)
 	if aidlDep != nil {
 		if lib, ok := module.linker.(*libraryDecorator); ok {
 			if proptools.Bool(lib.Properties.Aidl.Export_aidl_headers) {
@@ -826,6 +856,12 @@
 		}
 	}
 
+	// Create a cc_yacc_static_library if srcs contains .y/.yy files
+	// This internal target will produce an .a file that will be statically linked to the parent library
+	if yaccDep := bp2buildCcYaccLibrary(ctx, compilerAttrs, linkerAttrs); yaccDep != nil {
+		(&linkerAttrs).implementationWholeArchiveDeps.Add(yaccDep)
+	}
+
 	convertedLSrcs := bp2BuildLex(ctx, module.Name(), compilerAttrs)
 	(&compilerAttrs).srcs.Add(&convertedLSrcs.srcName)
 	(&compilerAttrs).cSrcs.Add(&convertedLSrcs.cSrcName)
@@ -864,6 +900,48 @@
 	}
 }
 
+type ccYaccLibraryAttributes struct {
+	Src                         bazel.LabelAttribute
+	Flags                       bazel.StringListAttribute
+	Gen_location_hh             bazel.BoolAttribute
+	Gen_position_hh             bazel.BoolAttribute
+	Local_includes              bazel.StringListAttribute
+	Implementation_deps         bazel.LabelListAttribute
+	Implementation_dynamic_deps bazel.LabelListAttribute
+}
+
+func bp2buildCcYaccLibrary(ctx android.Bp2buildMutatorContext, ca compilerAttributes, la linkerAttributes) *bazel.LabelAttribute {
+	if ca.yaccSrc == nil {
+		return nil
+	}
+	yaccLibraryLabel := ctx.Module().Name() + "_yacc"
+	ctx.CreateBazelTargetModule(
+		bazel.BazelTargetModuleProperties{
+			Rule_class:        "cc_yacc_static_library",
+			Bzl_load_location: "//build/bazel/rules/cc:cc_yacc_library.bzl",
+		},
+		android.CommonAttributes{
+			Name: yaccLibraryLabel,
+		},
+		&ccYaccLibraryAttributes{
+			Src:                         *ca.yaccSrc,
+			Flags:                       ca.yaccFlags,
+			Gen_location_hh:             ca.yaccGenLocationHeader,
+			Gen_position_hh:             ca.yaccGenPositionHeader,
+			Local_includes:              ca.localIncludes,
+			Implementation_deps:         la.implementationDeps,
+			Implementation_dynamic_deps: la.implementationDynamicDeps,
+		},
+	)
+
+	yaccLibrary := &bazel.LabelAttribute{
+		Value: &bazel.Label{
+			Label: ":" + yaccLibraryLabel,
+		},
+	}
+	return yaccLibrary
+}
+
 // As a workaround for b/261657184, we are manually adding the default value
 // of system_dynamic_deps for the linux_musl os.
 // TODO: Solve this properly
@@ -912,11 +990,16 @@
 func bp2buildCcAidlLibrary(
 	ctx android.Bp2buildMutatorContext,
 	m *Module,
-	aidlLabelList bazel.LabelListAttribute,
+	aidlSrcs bazel.LabelListAttribute,
+	aidlLibs bazel.LabelListAttribute,
 	linkerAttrs linkerAttributes,
+	compilerAttrs compilerAttributes,
 ) *bazel.LabelAttribute {
-	if !aidlLabelList.IsEmpty() {
-		aidlLibs, aidlSrcs := aidlLabelList.Partition(func(src bazel.Label) bool {
+	var aidlLibsFromSrcs, aidlFiles bazel.LabelListAttribute
+	apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx.(android.TopDownMutatorContext), ctx.Module())
+
+	if !aidlSrcs.IsEmpty() {
+		aidlLibsFromSrcs, aidlFiles = aidlSrcs.Partition(func(src bazel.Label) bool {
 			if fg, ok := android.ToFileGroupAsLibrary(ctx, src.OriginalModuleName); ok &&
 				fg.ShouldConvertToAidlLibrary(ctx) {
 				return true
@@ -924,57 +1007,71 @@
 			return false
 		})
 
-		apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx.(android.TopDownMutatorContext), ctx.Module())
-		sdkAttrs := bp2BuildParseSdkAttributes(m)
-
-		if !aidlSrcs.IsEmpty() {
+		if !aidlFiles.IsEmpty() {
 			aidlLibName := m.Name() + "_aidl_library"
 			ctx.CreateBazelTargetModule(
 				bazel.BazelTargetModuleProperties{
 					Rule_class:        "aidl_library",
 					Bzl_load_location: "//build/bazel/rules/aidl:aidl_library.bzl",
 				},
-				android.CommonAttributes{Name: aidlLibName},
-				&aidlLibraryAttributes{
-					Srcs: aidlSrcs,
+				android.CommonAttributes{
+					Name: aidlLibName,
 					Tags: apexAvailableTags,
 				},
-			)
-			aidlLibs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}})
-		}
-
-		if !aidlLibs.IsEmpty() {
-			ccAidlLibrarylabel := m.Name() + "_cc_aidl_library"
-			// Since parent cc_library already has these dependencies, we can add them as implementation
-			// deps so that they don't re-export
-			implementationDeps := linkerAttrs.deps.Clone()
-			implementationDeps.Append(linkerAttrs.implementationDeps)
-			implementationDynamicDeps := linkerAttrs.dynamicDeps.Clone()
-			implementationDynamicDeps.Append(linkerAttrs.implementationDynamicDeps)
-
-			ctx.CreateBazelTargetModule(
-				bazel.BazelTargetModuleProperties{
-					Rule_class:        "cc_aidl_library",
-					Bzl_load_location: "//build/bazel/rules/cc:cc_aidl_library.bzl",
-				},
-				android.CommonAttributes{Name: ccAidlLibrarylabel},
-				&ccAidlLibraryAttributes{
-					Deps:                        aidlLibs,
-					Implementation_deps:         *implementationDeps,
-					Implementation_dynamic_deps: *implementationDynamicDeps,
-					Tags:                        apexAvailableTags,
-					sdkAttributes:               sdkAttrs,
+				&aidlLibraryAttributes{
+					Srcs: aidlFiles,
 				},
 			)
-			label := &bazel.LabelAttribute{
-				Value: &bazel.Label{
-					Label: ":" + ccAidlLibrarylabel,
-				},
-			}
-			return label
+			aidlLibsFromSrcs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}})
 		}
 	}
 
+	allAidlLibs := aidlLibs.Clone()
+	allAidlLibs.Append(aidlLibsFromSrcs)
+
+	if !allAidlLibs.IsEmpty() {
+		ccAidlLibrarylabel := m.Name() + "_cc_aidl_library"
+		// Since parent cc_library already has these dependencies, we can add them as implementation
+		// deps so that they don't re-export
+		implementationDeps := linkerAttrs.deps.Clone()
+		implementationDeps.Append(linkerAttrs.implementationDeps)
+		implementationDynamicDeps := linkerAttrs.dynamicDeps.Clone()
+		implementationDynamicDeps.Append(linkerAttrs.implementationDynamicDeps)
+
+		sdkAttrs := bp2BuildParseSdkAttributes(m)
+
+		exportedIncludes := bp2BuildParseExportedIncludes(ctx, m, &compilerAttrs.includes)
+		includeAttrs := includesAttributes{
+			Export_includes:          exportedIncludes.Includes,
+			Export_absolute_includes: exportedIncludes.AbsoluteIncludes,
+			Export_system_includes:   exportedIncludes.SystemIncludes,
+			Local_includes:           compilerAttrs.localIncludes,
+			Absolute_includes:        compilerAttrs.absoluteIncludes,
+		}
+
+		ctx.CreateBazelTargetModule(
+			bazel.BazelTargetModuleProperties{
+				Rule_class:        "cc_aidl_library",
+				Bzl_load_location: "//build/bazel/rules/cc:cc_aidl_library.bzl",
+			},
+			android.CommonAttributes{Name: ccAidlLibrarylabel},
+			&ccAidlLibraryAttributes{
+				Deps:                        *allAidlLibs,
+				Implementation_deps:         *implementationDeps,
+				Implementation_dynamic_deps: *implementationDynamicDeps,
+				Tags:                        apexAvailableTags,
+				sdkAttributes:               sdkAttrs,
+				includesAttributes:          includeAttrs,
+			},
+		)
+		label := &bazel.LabelAttribute{
+			Value: &bazel.Label{
+				Label: ":" + ccAidlLibrarylabel,
+			},
+		}
+		return label
+	}
+
 	return nil
 }
 
@@ -1169,6 +1266,9 @@
 	}
 
 	la.additionalLinkerInputs.SetSelectValue(axis, config, additionalLinkerInputs)
+	if axis == bazel.OsConfigurationAxis && (config == bazel.OsDarwin || config == bazel.OsLinux || config == bazel.OsWindows) {
+		linkerFlags = append(linkerFlags, props.Host_ldlibs...)
+	}
 	la.linkopts.SetSelectValue(axis, config, linkerFlags)
 
 	if axisFeatures != nil {
diff --git a/cc/cc.go b/cc/cc.go
index 7237686..f4b5655 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -27,6 +27,7 @@
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 
+	"android/soong/aidl_library"
 	"android/soong/android"
 	"android/soong/bazel/cquery"
 	"android/soong/cc/config"
@@ -110,6 +111,9 @@
 	// Used by DepsMutator to pass system_shared_libs information to check_elf_file.py.
 	SystemSharedLibs []string
 
+	// Used by DepMutator to pass aidl_library modules to aidl compiler
+	AidlLibs []string
+
 	// If true, statically link the unwinder into native libraries/binaries.
 	StaticUnwinderIfLegacy bool
 
@@ -182,6 +186,9 @@
 	// For Darwin builds, the path to the second architecture's output that should
 	// be combined with this architectures's output into a FAT MachO file.
 	DarwinSecondArchOutput android.OptionalPath
+
+	// Paths to direct srcs and transitive include dirs from direct aidl_library deps
+	AidlLibraryInfos []aidl_library.AidlLibraryInfo
 }
 
 // LocalOrGlobalFlags contains flags that need to have values set globally by the build system or locally by the module
@@ -765,6 +772,7 @@
 	stubImplDepTag        = dependencyTag{name: "stub_impl"}
 	JniFuzzLibTag         = dependencyTag{name: "jni_fuzz_lib_tag"}
 	FdoProfileTag         = dependencyTag{name: "fdo_profile"}
+	aidlLibraryTag        = dependencyTag{name: "aidl_library"}
 )
 
 func IsSharedDepTag(depTag blueprint.DependencyTag) bool {
@@ -2751,6 +2759,14 @@
 		}
 	}
 
+	if len(deps.AidlLibs) > 0 {
+		actx.AddDependency(
+			c,
+			aidlLibraryTag,
+			deps.AidlLibs...,
+		)
+	}
+
 	updateImportedLibraryDependency(ctx)
 }
 
@@ -3055,6 +3071,17 @@
 			return
 		}
 
+		if depTag == aidlLibraryTag {
+			if ctx.OtherModuleHasProvider(dep, aidl_library.AidlLibraryProvider) {
+				depPaths.AidlLibraryInfos = append(
+					depPaths.AidlLibraryInfos,
+					ctx.OtherModuleProvider(
+						dep,
+						aidl_library.AidlLibraryProvider).(aidl_library.AidlLibraryInfo),
+				)
+			}
+		}
+
 		ccDep, ok := dep.(LinkableInterface)
 		if !ok {
 
diff --git a/cc/cc_test.go b/cc/cc_test.go
index f9e661f..422df73 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -24,6 +24,7 @@
 	"strings"
 	"testing"
 
+	"android/soong/aidl_library"
 	"android/soong/android"
 	"android/soong/bazel/cquery"
 )
@@ -38,6 +39,7 @@
 
 var prepareForCcTest = android.GroupFixturePreparers(
 	PrepareForTestWithCcIncludeVndk,
+	aidl_library.PrepareForTestWithAidlLibrary,
 	android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
 		variables.DeviceVndkVersion = StringPtr("current")
 		variables.ProductVndkVersion = StringPtr("current")
@@ -4418,9 +4420,65 @@
 	}
 }
 
+func TestAidlLibraryWithHeader(t *testing.T) {
+	t.Parallel()
+	ctx := android.GroupFixturePreparers(
+		prepareForCcTest,
+		aidl_library.PrepareForTestWithAidlLibrary,
+		android.MockFS{
+			"package_bar/Android.bp": []byte(`
+			aidl_library {
+				name: "bar",
+				srcs: ["x/y/Bar.aidl"],
+				strip_import_prefix: "x",
+			}
+			`)}.AddToFixture(),
+		android.MockFS{
+			"package_foo/Android.bp": []byte(`
+			aidl_library {
+				name: "foo",
+				srcs: ["a/b/Foo.aidl"],
+				strip_import_prefix: "a",
+				deps: ["bar"],
+			}
+			cc_library {
+				name: "libfoo",
+				aidl: {
+					libs: ["foo"],
+				}
+			}
+			`),
+		}.AddToFixture(),
+	).RunTest(t).TestContext
+
+	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
+	manifest := android.RuleBuilderSboxProtoForTests(t, libfoo.Output("aidl.sbox.textproto"))
+	aidlCommand := manifest.Commands[0].GetCommand()
+
+	expectedAidlFlags := "-Ipackage_foo/a -Ipackage_bar/x"
+	if !strings.Contains(aidlCommand, expectedAidlFlags) {
+		t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlags)
+	}
+
+	outputs := strings.Join(libfoo.AllOutputs(), " ")
+
+	android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl/b/BpFoo.h")
+	android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl/b/BnFoo.h")
+	android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl/b/Foo.h")
+	android.AssertStringDoesContain(t, "aidl-generated cpp", outputs, "b/Foo.cpp")
+	// Confirm that the aidl header doesn't get compiled to cpp and h files
+	android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl/y/BpBar.h")
+	android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl/y/BnBar.h")
+	android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl/y/Bar.h")
+	android.AssertStringDoesNotContain(t, "aidl-generated cpp", outputs, "y/Bar.cpp")
+}
+
 func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) {
 	t.Parallel()
-	ctx := testCc(t, `
+	ctx := android.GroupFixturePreparers(
+		prepareForCcTest,
+		aidl_library.PrepareForTestWithAidlLibrary,
+	).RunTestWithBp(t, `
 		cc_library {
 			name: "libfoo",
 			srcs: ["a/Foo.aidl"],
@@ -4705,7 +4763,15 @@
 	})
 
 	t.Run("ensure only aidl headers are exported", func(t *testing.T) {
-		ctx := testCc(t, genRuleModules+`
+		ctx := android.GroupFixturePreparers(
+			prepareForCcTest,
+			aidl_library.PrepareForTestWithAidlLibrary,
+		).RunTestWithBp(t, `
+		aidl_library {
+			name: "libfoo_aidl",
+			srcs: ["x/y/Bar.aidl"],
+			strip_import_prefix: "x",
+		}
 		cc_library_shared {
 			name: "libfoo",
 			srcs: [
@@ -4714,10 +4780,11 @@
 				"a.proto",
 			],
 			aidl: {
+				libs: ["libfoo_aidl"],
 				export_aidl_headers: true,
 			}
 		}
-		`)
+		`).TestContext
 		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
 		checkIncludeDirs(t, ctx, foo,
 			expectedIncludeDirs(`
@@ -4728,11 +4795,17 @@
 				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
 				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
 				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
+				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/Bar.h
+				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/BnBar.h
+				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/BpBar.h
 			`),
 			expectedOrderOnlyDeps(`
 				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
 				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
 				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
+				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/Bar.h
+				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/BnBar.h
+				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/BpBar.h
 			`),
 		)
 	})
diff --git a/cc/compiler.go b/cc/compiler.go
index 88985b6..5da745e 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -120,6 +120,9 @@
 	Lex  *LexProperties
 
 	Aidl struct {
+		// List of aidl_library modules
+		Libs []string
+
 		// list of directories that will be added to the aidl include paths.
 		Include_dirs []string
 
@@ -272,6 +275,7 @@
 	deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
 	deps.GeneratedSources = removeListFromList(deps.GeneratedSources, compiler.Properties.Exclude_generated_sources)
 	deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...)
+	deps.AidlLibs = append(deps.AidlLibs, compiler.Properties.Aidl.Libs...)
 
 	android.ProtoDeps(ctx, &compiler.Proto)
 	if compiler.hasSrcExt(".proto") {
@@ -561,7 +565,7 @@
 			"-I"+android.PathForModuleGen(ctx, "yacc", ctx.ModuleDir()).String())
 	}
 
-	if compiler.hasSrcExt(".aidl") {
+	if compiler.hasAidl(deps) {
 		flags.aidlFlags = append(flags.aidlFlags, compiler.Properties.Aidl.Flags...)
 		if len(compiler.Properties.Aidl.Local_include_dirs) > 0 {
 			localAidlIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Aidl.Local_include_dirs)
@@ -572,6 +576,14 @@
 			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs))
 		}
 
+		var rootAidlIncludeDirs android.Paths
+		for _, aidlLibraryInfo := range deps.AidlLibraryInfos {
+			rootAidlIncludeDirs = append(rootAidlIncludeDirs, aidlLibraryInfo.IncludeDirs.ToList()...)
+		}
+		if len(rootAidlIncludeDirs) > 0 {
+			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs))
+		}
+
 		if proptools.BoolDefault(compiler.Properties.Aidl.Generate_traces, true) {
 			flags.aidlFlags = append(flags.aidlFlags, "-t")
 		}
@@ -660,6 +672,10 @@
 	return nil
 }
 
+func (compiler *baseCompiler) hasAidl(deps PathDeps) bool {
+	return len(deps.AidlLibraryInfos) > 0 || compiler.hasSrcExt(".aidl")
+}
+
 func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
 	pathDeps := deps.GeneratedDeps
 	pathDeps = append(pathDeps, ndkPathDeps(ctx)...)
@@ -668,7 +684,7 @@
 
 	srcs := append(android.Paths(nil), compiler.srcsBeforeGen...)
 
-	srcs, genDeps, info := genSources(ctx, srcs, buildFlags)
+	srcs, genDeps, info := genSources(ctx, deps.AidlLibraryInfos, srcs, buildFlags)
 	pathDeps = append(pathDeps, genDeps...)
 
 	compiler.pathDeps = pathDeps
diff --git a/cc/config/global.go b/cc/config/global.go
index e5ce48e..d4106eb 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -354,14 +354,14 @@
 		// Automatically initialize any uninitialized stack variables.
 		// Prefer zero-init if multiple options are set.
 		if ctx.Config().IsEnvTrue("AUTO_ZERO_INITIALIZE") {
-			flags = append(flags, "-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang -Wno-unused-command-line-argument")
+			flags = append(flags, "-ftrivial-auto-var-init=zero")
 		} else if ctx.Config().IsEnvTrue("AUTO_PATTERN_INITIALIZE") {
 			flags = append(flags, "-ftrivial-auto-var-init=pattern")
 		} else if ctx.Config().IsEnvTrue("AUTO_UNINITIALIZE") {
 			flags = append(flags, "-ftrivial-auto-var-init=uninitialized")
 		} else {
 			// Default to zero initialization.
-			flags = append(flags, "-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang -Wno-unused-command-line-argument")
+			flags = append(flags, "-ftrivial-auto-var-init=zero")
 		}
 
 		// Workaround for ccache with clang.
diff --git a/cc/gen.go b/cc/gen.go
index dfbb177..dbb9560 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -18,7 +18,9 @@
 	"path/filepath"
 	"strings"
 
+	"android/soong/aidl_library"
 	"android/soong/bazel"
+
 	"github.com/google/blueprint"
 
 	"android/soong/android"
@@ -124,11 +126,6 @@
 	headerBn := outDir.Join(ctx, aidlPackage, "Bn"+shortName+".h")
 	headerBp := outDir.Join(ctx, aidlPackage, "Bp"+shortName+".h")
 
-	baseDir := strings.TrimSuffix(aidlFile.String(), aidlFile.Rel())
-	if baseDir != "" {
-		aidlFlags += " -I" + baseDir
-	}
-
 	cmd := rule.Command()
 	cmd.BuiltTool("aidl-cpp").
 		FlagWithDepFile("-d", depFile).
@@ -282,7 +279,10 @@
 	syspropOrderOnlyDeps android.Paths
 }
 
-func genSources(ctx android.ModuleContext, srcFiles android.Paths,
+func genSources(
+	ctx android.ModuleContext,
+	aidlLibraryInfos []aidl_library.AidlLibraryInfo,
+	srcFiles android.Paths,
 	buildFlags builderFlags) (android.Paths, android.Paths, generatedSourceInfo) {
 
 	var info generatedSourceInfo
@@ -330,7 +330,8 @@
 				aidlRule = android.NewRuleBuilder(pctx, ctx).Sbox(android.PathForModuleGen(ctx, "aidl"),
 					android.PathForModuleGen(ctx, "aidl.sbox.textproto"))
 			}
-			cppFile, aidlHeaders := genAidl(ctx, aidlRule, srcFile, buildFlags.aidlFlags)
+			baseDir := strings.TrimSuffix(srcFile.String(), srcFile.Rel())
+			cppFile, aidlHeaders := genAidl(ctx, aidlRule, srcFile, buildFlags.aidlFlags+" -I"+baseDir)
 			srcFiles[i] = cppFile
 
 			info.aidlHeaders = append(info.aidlHeaders, aidlHeaders...)
@@ -352,6 +353,24 @@
 		}
 	}
 
+	for _, aidlLibraryInfo := range aidlLibraryInfos {
+		for _, aidlSrc := range aidlLibraryInfo.Srcs {
+			if aidlRule == nil {
+				// TODO(b/279960133): Sandbox inputs to ensure aidl headers are explicitly specified
+				aidlRule = android.NewRuleBuilder(pctx, ctx).Sbox(android.PathForModuleGen(ctx, "aidl"),
+					android.PathForModuleGen(ctx, "aidl.sbox.textproto"))
+			}
+			cppFile, aidlHeaders := genAidl(ctx, aidlRule, aidlSrc, buildFlags.aidlFlags)
+
+			srcFiles = append(srcFiles, cppFile)
+			info.aidlHeaders = append(info.aidlHeaders, aidlHeaders...)
+			// Use the generated headers as order only deps to ensure that they are up to date when
+			// needed.
+			// TODO: Reduce the size of the ninja file by using one order only dep for the whole rule
+			info.aidlOrderOnlyDeps = append(info.aidlOrderOnlyDeps, aidlHeaders...)
+		}
+	}
+
 	if aidlRule != nil {
 		aidlRule.Build("aidl", "gen aidl")
 	}
diff --git a/cc/library.go b/cc/library.go
index 13b333a..09a7253 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -271,7 +271,9 @@
 	Implementation_deps         bazel.LabelListAttribute
 	Implementation_dynamic_deps bazel.LabelListAttribute
 	Tags                        bazel.StringListAttribute
+
 	sdkAttributes
+	includesAttributes
 }
 
 type stripAttributes struct {
@@ -335,6 +337,14 @@
 		Native_coverage:                   baseAttributes.Native_coverage,
 	}
 
+	includeAttrs := includesAttributes{
+		Export_includes:          exportedIncludes.Includes,
+		Export_absolute_includes: exportedIncludes.AbsoluteIncludes,
+		Export_system_includes:   exportedIncludes.SystemIncludes,
+		Local_includes:           compilerAttrs.localIncludes,
+		Absolute_includes:        compilerAttrs.absoluteIncludes,
+	}
+
 	sharedCommonAttrs := staticOrSharedAttributes{
 		Srcs:    *srcs.Clone().Append(sharedAttrs.Srcs),
 		Srcs_c:  *compilerAttrs.cSrcs.Clone().Append(sharedAttrs.Srcs_c),
@@ -356,41 +366,34 @@
 
 	staticTargetAttrs := &bazelCcLibraryStaticAttributes{
 		staticOrSharedAttributes: staticCommonAttrs,
+		includesAttributes:       includeAttrs,
 
 		Cppflags:   compilerAttrs.cppFlags,
 		Conlyflags: compilerAttrs.conlyFlags,
 		Asflags:    asFlags,
 
-		Export_includes:          exportedIncludes.Includes,
-		Export_absolute_includes: exportedIncludes.AbsoluteIncludes,
-		Export_system_includes:   exportedIncludes.SystemIncludes,
-		Local_includes:           compilerAttrs.localIncludes,
-		Absolute_includes:        compilerAttrs.absoluteIncludes,
-		Rtti:                     compilerAttrs.rtti,
-		Stl:                      compilerAttrs.stl,
-		Cpp_std:                  compilerAttrs.cppStd,
-		C_std:                    compilerAttrs.cStd,
+		Rtti:    compilerAttrs.rtti,
+		Stl:     compilerAttrs.stl,
+		Cpp_std: compilerAttrs.cppStd,
+		C_std:   compilerAttrs.cStd,
 
 		Features: *staticFeatures,
 	}
 
 	sharedTargetAttrs := &bazelCcLibrarySharedAttributes{
 		staticOrSharedAttributes: sharedCommonAttrs,
-		Cppflags:                 compilerAttrs.cppFlags,
-		Conlyflags:               compilerAttrs.conlyFlags,
-		Asflags:                  asFlags,
+		includesAttributes:       includeAttrs,
 
-		Export_includes:          exportedIncludes.Includes,
-		Export_absolute_includes: exportedIncludes.AbsoluteIncludes,
-		Export_system_includes:   exportedIncludes.SystemIncludes,
-		Local_includes:           compilerAttrs.localIncludes,
-		Absolute_includes:        compilerAttrs.absoluteIncludes,
-		Linkopts:                 linkerAttrs.linkopts,
-		Rtti:                     compilerAttrs.rtti,
-		Stl:                      compilerAttrs.stl,
-		Cpp_std:                  compilerAttrs.cppStd,
-		C_std:                    compilerAttrs.cStd,
-		Use_version_lib:          linkerAttrs.useVersionLib,
+		Cppflags:   compilerAttrs.cppFlags,
+		Conlyflags: compilerAttrs.conlyFlags,
+		Asflags:    asFlags,
+
+		Linkopts:        linkerAttrs.linkopts,
+		Rtti:            compilerAttrs.rtti,
+		Stl:             compilerAttrs.stl,
+		Cpp_std:         compilerAttrs.cppStd,
+		C_std:           compilerAttrs.cStd,
+		Use_version_lib: linkerAttrs.useVersionLib,
 
 		Additional_linker_inputs: linkerAttrs.additionalLinkerInputs,
 
@@ -2114,7 +2117,7 @@
 
 	// Optionally export aidl headers.
 	if Bool(library.Properties.Aidl.Export_aidl_headers) {
-		if library.baseCompiler.hasSrcExt(".aidl") {
+		if library.baseCompiler.hasAidl(deps) {
 			dir := android.PathForModuleGen(ctx, "aidl")
 			library.reexportDirs(dir)
 
@@ -2880,6 +2883,13 @@
 	linkerAttrs := baseAttributes.linkerAttributes
 
 	exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, &compilerAttrs.includes)
+	includeAttrs := includesAttributes{
+		Export_includes:          exportedIncludes.Includes,
+		Export_absolute_includes: exportedIncludes.AbsoluteIncludes,
+		Export_system_includes:   exportedIncludes.SystemIncludes,
+		Local_includes:           compilerAttrs.localIncludes,
+		Absolute_includes:        compilerAttrs.absoluteIncludes,
+	}
 
 	// Append shared/static{} stanza properties. These won't be specified on
 	// cc_library_* itself, but may be specified in cc_defaults that this module
@@ -2937,11 +2947,7 @@
 			Cpp_std:                  compilerAttrs.cppStd,
 			C_std:                    compilerAttrs.cStd,
 
-			Export_includes:          exportedIncludes.Includes,
-			Export_absolute_includes: exportedIncludes.AbsoluteIncludes,
-			Export_system_includes:   exportedIncludes.SystemIncludes,
-			Local_includes:           compilerAttrs.localIncludes,
-			Absolute_includes:        compilerAttrs.absoluteIncludes,
+			includesAttributes: includeAttrs,
 
 			Cppflags:   compilerAttrs.cppFlags,
 			Conlyflags: compilerAttrs.conlyFlags,
@@ -2967,11 +2973,8 @@
 			Cpp_std: compilerAttrs.cppStd,
 			C_std:   compilerAttrs.cStd,
 
-			Export_includes:          exportedIncludes.Includes,
-			Export_absolute_includes: exportedIncludes.AbsoluteIncludes,
-			Export_system_includes:   exportedIncludes.SystemIncludes,
-			Local_includes:           compilerAttrs.localIncludes,
-			Absolute_includes:        compilerAttrs.absoluteIncludes,
+			includesAttributes: includeAttrs,
+
 			Additional_linker_inputs: linkerAttrs.additionalLinkerInputs,
 
 			Strip: stripAttrsFromLinkerAttrs(&linkerAttrs),
@@ -3007,9 +3010,18 @@
 	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name(), Tags: tags}, attrs)
 }
 
+type includesAttributes struct {
+	Export_includes          bazel.StringListAttribute
+	Export_absolute_includes bazel.StringListAttribute
+	Export_system_includes   bazel.StringListAttribute
+	Local_includes           bazel.StringListAttribute
+	Absolute_includes        bazel.StringListAttribute
+}
+
 // TODO(b/199902614): Can this be factored to share with the other Attributes?
 type bazelCcLibraryStaticAttributes struct {
 	staticOrSharedAttributes
+	includesAttributes
 
 	Use_version_lib bazel.BoolAttribute
 	Rtti            bazel.BoolAttribute
@@ -3017,12 +3029,7 @@
 	Cpp_std         *string
 	C_std           *string
 
-	Export_includes          bazel.StringListAttribute
-	Export_absolute_includes bazel.StringListAttribute
-	Export_system_includes   bazel.StringListAttribute
-	Local_includes           bazel.StringListAttribute
-	Absolute_includes        bazel.StringListAttribute
-	Hdrs                     bazel.LabelListAttribute
+	Hdrs bazel.LabelListAttribute
 
 	Cppflags   bazel.StringListAttribute
 	Conlyflags bazel.StringListAttribute
@@ -3034,6 +3041,7 @@
 // TODO(b/199902614): Can this be factored to share with the other Attributes?
 type bazelCcLibrarySharedAttributes struct {
 	staticOrSharedAttributes
+	includesAttributes
 
 	Linkopts        bazel.StringListAttribute
 	Use_version_lib bazel.BoolAttribute
@@ -3043,12 +3051,7 @@
 	Cpp_std *string
 	C_std   *string
 
-	Export_includes          bazel.StringListAttribute
-	Export_absolute_includes bazel.StringListAttribute
-	Export_system_includes   bazel.StringListAttribute
-	Local_includes           bazel.StringListAttribute
-	Absolute_includes        bazel.StringListAttribute
-	Hdrs                     bazel.LabelListAttribute
+	Hdrs bazel.LabelListAttribute
 
 	Strip                    stripAttributes
 	Additional_linker_inputs bazel.LabelListAttribute
diff --git a/cc/lto.go b/cc/lto.go
index 581856b..1afa1dd 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -91,6 +91,11 @@
 		return flags
 	}
 
+	// TODO(b/254713216): LTO doesn't work on riscv64 yet.
+	if ctx.Arch().ArchType == android.Riscv64 {
+		return flags
+	}
+
 	if lto.LTO(ctx) {
 		var ltoCFlag string
 		var ltoLdFlag string
diff --git a/cc/sanitize.go b/cc/sanitize.go
index df96b89..7fddc1b 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -653,6 +653,12 @@
 		s.Integer_overflow = nil
 	}
 
+	// TODO(b/254713216): CFI doesn't work for riscv64 yet because LTO doesn't work.
+	if ctx.Arch().ArchType == android.Riscv64 {
+		s.Cfi = nil
+		s.Diag.Cfi = nil
+	}
+
 	// Disable CFI for musl
 	if ctx.toolchain().Musl() {
 		s.Cfi = nil
diff --git a/device_config/Android.bp b/device_config/Android.bp
new file mode 100644
index 0000000..360b389
--- /dev/null
+++ b/device_config/Android.bp
@@ -0,0 +1,30 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+    name: "soong-device_config",
+    pkgPath: "android/soong/device_config",
+    deps: [
+        "blueprint",
+        "blueprint-pathtools",
+        "sbox_proto",
+        "soong",
+        "soong-android",
+        "soong-bazel",
+        "soong-shared",
+    ],
+    srcs: [
+        "device_config_definitions.go",
+        "device_config_values.go",
+        "device_config_value_set.go",
+        "init.go",
+        //"testing.go"
+    ],
+    /*
+    testSrcs: [
+        "device_config_test.go",
+    ],
+    */
+    pluginFor: ["soong_build"],
+}
diff --git a/device_config/device_config_definitions.go b/device_config/device_config_definitions.go
new file mode 100644
index 0000000..c565766
--- /dev/null
+++ b/device_config/device_config_definitions.go
@@ -0,0 +1,150 @@
+// Copyright 2023 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 device_config
+
+import (
+	"android/soong/android"
+	"fmt"
+	"github.com/google/blueprint"
+	"strings"
+)
+
+type DefinitionsModule struct {
+	android.ModuleBase
+	android.DefaultableModuleBase
+
+	// Properties for "device_config_definitions"
+	properties struct {
+		// aconfig files, relative to this Android.bp file
+		Srcs []string `android:"path"`
+
+		// Release config flag namespace
+		Namespace string
+
+		// Values from TARGET_RELEASE / RELEASE_DEVICE_CONFIG_VALUE_SETS
+		Values []string `blueprint:"mutated"`
+	}
+
+	intermediatePath android.WritablePath
+	srcJarPath       android.WritablePath
+}
+
+func DefinitionsFactory() android.Module {
+	module := &DefinitionsModule{}
+
+	android.InitAndroidModule(module)
+	android.InitDefaultableModule(module)
+	module.AddProperties(&module.properties)
+	// TODO: bp2build
+	//android.InitBazelModule(module)
+
+	return module
+}
+
+type implicitValuesTagType struct {
+	blueprint.BaseDependencyTag
+}
+
+var implicitValuesTag = implicitValuesTagType{}
+
+func (module *DefinitionsModule) DepsMutator(ctx android.BottomUpMutatorContext) {
+	// Validate Properties
+	if len(module.properties.Srcs) == 0 {
+		ctx.PropertyErrorf("srcs", "missing source files")
+		return
+	}
+	if len(module.properties.Namespace) == 0 {
+		ctx.PropertyErrorf("namespace", "missing namespace property")
+	}
+
+	// Add a dependency on the device_config_value_sets defined in
+	// RELEASE_DEVICE_CONFIG_VALUE_SETS, and add any device_config_values that
+	// match our namespace.
+	valuesFromConfig := ctx.Config().ReleaseDeviceConfigValueSets()
+	ctx.AddDependency(ctx.Module(), implicitValuesTag, valuesFromConfig...)
+}
+
+func (module *DefinitionsModule) OutputFiles(tag string) (android.Paths, error) {
+	switch tag {
+	case ".srcjar":
+		return []android.Path{module.srcJarPath}, nil
+	case "":
+		// The default output of this module is the intermediates format, which is
+		// not installable and in a private format that no other rules can handle
+		// correctly.
+		return []android.Path{module.intermediatePath}, nil
+	default:
+		return nil, fmt.Errorf("unsupported device_config_definitions module reference tag %q", tag)
+	}
+}
+
+func joinAndPrefix(prefix string, values []string) string {
+	var sb strings.Builder
+	for _, v := range values {
+		sb.WriteString(prefix)
+		sb.WriteString(v)
+	}
+	return sb.String()
+}
+
+func (module *DefinitionsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	// Get the values that came from the global RELEASE_DEVICE_CONFIG_VALUE_SETS flag
+	ctx.VisitDirectDeps(func(dep android.Module) {
+		if !ctx.OtherModuleHasProvider(dep, valueSetProviderKey) {
+			// Other modules get injected as dependencies too, for example the license modules
+			return
+		}
+		depData := ctx.OtherModuleProvider(dep, valueSetProviderKey).(valueSetProviderData)
+		valuesFiles, ok := depData.AvailableNamespaces[module.properties.Namespace]
+		if ok {
+			for _, path := range valuesFiles {
+				module.properties.Values = append(module.properties.Values, path.String())
+			}
+		}
+	})
+
+	// Intermediate format
+	inputFiles := android.PathsForModuleSrc(ctx, module.properties.Srcs)
+	module.intermediatePath = android.PathForModuleOut(ctx, "intermediate.json")
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        aconfigRule,
+		Inputs:      inputFiles,
+		Output:      module.intermediatePath,
+		Description: "device_config_definitions",
+		Args: map[string]string{
+			"release_version": ctx.Config().ReleaseVersion(),
+			"namespace":       module.properties.Namespace,
+			"values":          joinAndPrefix(" --values ", module.properties.Values),
+		},
+	})
+
+	// Generated java inside a srcjar
+	module.srcJarPath = android.PathForModuleGen(ctx, ctx.ModuleName()+".srcjar")
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        srcJarRule,
+		Input:       module.intermediatePath,
+		Output:      module.srcJarPath,
+		Description: "device_config.srcjar",
+	})
+
+	// TODO: C++
+
+	// Phony target for debugging convenience
+	ctx.Build(pctx, android.BuildParams{
+		Rule:   blueprint.Phony,
+		Output: android.PathForPhony(ctx, ctx.ModuleName()),
+		Inputs: []android.Path{module.srcJarPath}, // TODO: C++
+	})
+}
diff --git a/device_config/device_config_test.go b/device_config/device_config_test.go
new file mode 100644
index 0000000..91a06a7
--- /dev/null
+++ b/device_config/device_config_test.go
@@ -0,0 +1,61 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package device_config
+
+import (
+	"os"
+	"testing"
+
+	"android/soong/android"
+	"android/soong/java"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(m.Run())
+}
+
+func test(t *testing.T, bp string) *android.TestResult {
+	t.Helper()
+
+	mockFS := android.MockFS{
+		"config.aconfig": nil,
+	}
+
+	result := android.GroupFixturePreparers(
+		java.PrepareForTestWithJavaDefaultModules,
+		PrepareForTestWithSyspropBuildComponents,
+		// TODO: Consider values files, although maybe in its own test
+		// android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+		//	variables.ReleaseConfigValuesBasePaths = ...
+		//})
+		mockFS.AddToFixture(),
+		android.FixtureWithRootAndroidBp(bp),
+	).RunTest(t)
+
+	return result
+}
+
+func TestOutputs(t *testing.T) {
+	/*result := */ test(t, `
+        device_config {
+            name: "my_device_config",
+            srcs: ["config.aconfig"],
+        }
+	`)
+
+	// TODO: Make sure it exports a .srcjar, which is used by java libraries
+	// TODO: Make sure it exports an intermediates file
+	// TODO: Make sure the intermediates file is propagated to the Android.mk file
+}
diff --git a/device_config/device_config_value_set.go b/device_config/device_config_value_set.go
new file mode 100644
index 0000000..e406d20
--- /dev/null
+++ b/device_config/device_config_value_set.go
@@ -0,0 +1,92 @@
+// Copyright 2023 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 device_config
+
+import (
+	"android/soong/android"
+	"github.com/google/blueprint"
+)
+
+// Properties for "device_config_value_set"
+type ValueSetModule struct {
+	android.ModuleBase
+	android.DefaultableModuleBase
+
+	properties struct {
+		// device_config_values modules
+		Values []string
+	}
+}
+
+func ValueSetFactory() android.Module {
+	module := &ValueSetModule{}
+
+	android.InitAndroidModule(module)
+	android.InitDefaultableModule(module)
+	module.AddProperties(&module.properties)
+	// TODO: bp2build
+	//android.InitBazelModule(module)
+
+	return module
+}
+
+// Dependency tag for values property
+type valueSetType struct {
+	blueprint.BaseDependencyTag
+}
+
+var valueSetTag = valueSetType{}
+
+// Provider published by device_config_value_set
+type valueSetProviderData struct {
+	// The namespace of each of the
+	// (map of namespace --> device_config_module)
+	AvailableNamespaces map[string]android.Paths
+}
+
+var valueSetProviderKey = blueprint.NewProvider(valueSetProviderData{})
+
+func (module *ValueSetModule) DepsMutator(ctx android.BottomUpMutatorContext) {
+	deps := ctx.AddDependency(ctx.Module(), valueSetTag, module.properties.Values...)
+	for _, dep := range deps {
+		_, ok := dep.(*ValuesModule)
+		if !ok {
+			ctx.PropertyErrorf("values", "values must be a device_config_values module")
+			return
+		}
+	}
+}
+
+func (module *ValueSetModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	// Accumulate the namespaces of the values modules listed, and set that as an
+	// valueSetProviderKey provider that device_config modules can read and use
+	// to append values to their aconfig actions.
+	namespaces := make(map[string]android.Paths)
+	ctx.VisitDirectDeps(func(dep android.Module) {
+		if !ctx.OtherModuleHasProvider(dep, valuesProviderKey) {
+			// Other modules get injected as dependencies too, for example the license modules
+			return
+		}
+		depData := ctx.OtherModuleProvider(dep, valuesProviderKey).(valuesProviderData)
+
+		srcs := make([]android.Path, len(depData.Values))
+		copy(srcs, depData.Values)
+		namespaces[depData.Namespace] = srcs
+
+	})
+	ctx.SetProvider(valueSetProviderKey, valueSetProviderData{
+		AvailableNamespaces: namespaces,
+	})
+}
diff --git a/device_config/device_config_values.go b/device_config/device_config_values.go
new file mode 100644
index 0000000..110f12a
--- /dev/null
+++ b/device_config/device_config_values.go
@@ -0,0 +1,70 @@
+// Copyright 2023 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 device_config
+
+import (
+	"android/soong/android"
+	"github.com/google/blueprint"
+)
+
+// Properties for "device_config_value"
+type ValuesModule struct {
+	android.ModuleBase
+	android.DefaultableModuleBase
+
+	properties struct {
+		// aconfig files, relative to this Android.bp file
+		Srcs []string `android:"path"`
+
+		// Release config flag namespace
+		Namespace string
+	}
+}
+
+func ValuesFactory() android.Module {
+	module := &ValuesModule{}
+
+	android.InitAndroidModule(module)
+	android.InitDefaultableModule(module)
+	module.AddProperties(&module.properties)
+	// TODO: bp2build
+	//android.InitBazelModule(module)
+
+	return module
+}
+
+// Provider published by device_config_value_set
+type valuesProviderData struct {
+	// The namespace that this values module values
+	Namespace string
+
+	// The values aconfig files, relative to the root of the tree
+	Values android.Paths
+}
+
+var valuesProviderKey = blueprint.NewProvider(valuesProviderData{})
+
+func (module *ValuesModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	if len(module.properties.Namespace) == 0 {
+		ctx.PropertyErrorf("namespace", "missing namespace property")
+	}
+
+	// Provide the our source files list to the device_config_value_set as a list of files
+	providerData := valuesProviderData{
+		Namespace: module.properties.Namespace,
+		Values:    android.PathsForModuleSrc(ctx, module.properties.Srcs),
+	}
+	ctx.SetProvider(valuesProviderKey, providerData)
+}
diff --git a/device_config/init.go b/device_config/init.go
new file mode 100644
index 0000000..0a4645b
--- /dev/null
+++ b/device_config/init.go
@@ -0,0 +1,70 @@
+// Copyright 2023 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 device_config
+
+import (
+	"android/soong/android"
+	"github.com/google/blueprint"
+)
+
+var (
+	pctx = android.NewPackageContext("android/soong/device_config")
+
+	// For device_config_definitions: Generate cache file
+	// TODO: Restat
+	aconfigRule = pctx.AndroidStaticRule("aconfig",
+		blueprint.RuleParams{
+			Command: `${aconfig} create-cache` +
+				` --namespace ${namespace}` +
+				` --declarations ${in}` +
+				` ${values}` +
+				` --cache ${out}.tmp` +
+				` && ( if cmp -s ${out}.tmp ; then rm ${out}.tmp ; else mv ${out}.tmp ${out} ; fi )`,
+			//				` --build-id ${release_version}` +
+			CommandDeps: []string{
+				"${aconfig}",
+			},
+			Restat: true,
+		}, "release_version", "namespace", "values")
+
+	// For device_config_definitions: Generate java file
+	srcJarRule = pctx.AndroidStaticRule("aconfig_srcjar",
+		blueprint.RuleParams{
+			Command: `rm -rf ${out}.tmp` +
+				` && mkdir -p ${out}.tmp` +
+				` && ${aconfig} create-java-lib` +
+				`    --cache ${in}` +
+				`    --out ${out}.tmp` +
+				` && $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` +
+				` && rm -rf ${out}.tmp`,
+			CommandDeps: []string{
+				"$aconfig",
+				"$soong_zip",
+			},
+			Restat: true,
+		})
+)
+
+func init() {
+	registerBuildComponents(android.InitRegistrationContext)
+}
+
+func registerBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("device_config_definitions", DefinitionsFactory)
+	ctx.RegisterModuleType("device_config_values", ValuesFactory)
+	ctx.RegisterModuleType("device_config_value_set", ValueSetFactory)
+	pctx.HostBinToolVariable("aconfig", "aconfig")
+	pctx.HostBinToolVariable("soong_zip", "soong_zip")
+}
diff --git a/device_config/testing.go b/device_config/testing.go
new file mode 100644
index 0000000..f054476
--- /dev/null
+++ b/device_config/testing.go
@@ -0,0 +1,19 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package device_config
+
+import "android/soong/android"
+
+var PrepareForTestWithSyspropBuildComponents = android.FixtureRegisterWithContext(registerBuildComponents)
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 6817dce..3e1bbde 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -652,9 +652,7 @@
 		prop := snapshot.SnapshotJsonFlags{}
 		propOut := snapshotLibOut + ".json"
 		prop.InitBaseSnapshotProps(m)
-		if m.subdirProperties.Relative_install_path != nil {
-			prop.RelativeInstallPath = *m.subdirProperties.Relative_install_path
-		}
+		prop.RelativeInstallPath = m.SubDir()
 
 		if m.properties.Filename != nil {
 			prop.Filename = *m.properties.Filename