Merge "Revert "Add BUILD_BROKEN_VENDOR_SEAPP_USES_COREDOMAIN"" into main
diff --git a/aconfig/aconfig_declarations.go b/aconfig/aconfig_declarations.go
index 4e199dd..5cdf5b6 100644
--- a/aconfig/aconfig_declarations.go
+++ b/aconfig/aconfig_declarations.go
@@ -116,32 +116,38 @@
 
 func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	// Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag
+	valuesFiles := make([]android.Path, 0)
 	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.AvailablePackages[module.properties.Package]
+		paths, ok := depData.AvailablePackages[module.properties.Package]
 		if ok {
-			for _, path := range valuesFiles {
+			valuesFiles = append(valuesFiles, paths...)
+			for _, path := range paths {
 				module.properties.Values = append(module.properties.Values, path.String())
 			}
 		}
 	})
 
 	// Intermediate format
-	inputFiles := android.PathsForModuleSrc(ctx, module.properties.Srcs)
+	declarationFiles := android.PathsForModuleSrc(ctx, module.properties.Srcs)
 	intermediatePath := android.PathForModuleOut(ctx, "intermediate.pb")
 	defaultPermission := ctx.Config().ReleaseAconfigFlagDefaultPermission()
+	inputFiles := make([]android.Path, len(declarationFiles))
+	copy(inputFiles, declarationFiles)
+	inputFiles = append(inputFiles, valuesFiles...)
 	ctx.Build(pctx, android.BuildParams{
 		Rule:        aconfigRule,
 		Output:      intermediatePath,
+		Inputs:      inputFiles,
 		Description: "aconfig_declarations",
 		Args: map[string]string{
 			"release_version":    ctx.Config().ReleaseVersion(),
 			"package":            module.properties.Package,
-			"declarations":       android.JoinPathsWithPrefix(inputFiles, "--declarations "),
+			"declarations":       android.JoinPathsWithPrefix(declarationFiles, "--declarations "),
 			"values":             joinAndPrefix(" --values ", module.properties.Values),
 			"default-permission": optionalVariable(" --default-permission ", defaultPermission),
 		},
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 056c1a8..d6998b6 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -255,6 +255,7 @@
 		"hardware/interfaces/audio/aidl/common":                   Bp2BuildDefaultTrue,
 		"hardware/interfaces/audio/aidl/default":                  Bp2BuildDefaultTrue,
 		"hardware/interfaces/audio/aidl/sounddose":                Bp2BuildDefaultTrue,
+		"hardware/interfaces/camera/metadata/aidl":                Bp2BuildDefaultTrueRecursively,
 		"hardware/interfaces/common/aidl":                         Bp2BuildDefaultTrue,
 		"hardware/interfaces/common/fmq/aidl":                     Bp2BuildDefaultTrue,
 		"hardware/interfaces/common/support":                      Bp2BuildDefaultTrue,
@@ -396,6 +397,7 @@
 		"system/media/audio":                                     Bp2BuildDefaultTrueRecursively,
 		"system/media/alsa_utils":                                Bp2BuildDefaultTrueRecursively,
 		"system/media/audio_utils":                               Bp2BuildDefaultTrueRecursively,
+		"system/media/camera":                                    Bp2BuildDefaultTrueRecursively,
 		"system/memory/libion":                                   Bp2BuildDefaultTrueRecursively,
 		"system/memory/libmemunreachable":                        Bp2BuildDefaultTrueRecursively,
 		"system/sepolicy/apex":                                   Bp2BuildDefaultTrueRecursively,
@@ -437,6 +439,7 @@
 		// external/bazelbuild-rules_android/... is needed by mixed builds, otherwise mixed builds analysis fails
 		// e.g. ERROR: Analysis of target '@soong_injection//mixed_builds:buildroot' failed
 		"external/bazelbuild-rules_android":/* recursive = */ true,
+		"external/bazelbuild-rules_cc":/* recursive = */ true,
 		"external/bazelbuild-rules_java":/* recursive = */ true,
 		"external/bazelbuild-rules_license":/* recursive = */ true,
 		"external/bazelbuild-rules_go":/* recursive = */ true,
@@ -668,6 +671,9 @@
 		//frameworks/native/cmds/cmd
 		"libcmd",
 
+		//system/chre
+		"chre_api",
+
 		//system/core/fs_mgr/libdm
 		"libdm",
 
@@ -905,8 +911,9 @@
 		"apexer_test", "apexer_test_host_tools", "host_apex_verifier",
 
 		// java bugs
-		"libbase_ndk",  // TODO(b/186826477): fails to link libctscamera2_jni for device (required for CtsCameraTestCases)
-		"bouncycastle", // TODO(b/274474005): Need support for custom system_modules.
+		"libbase_ndk",           // TODO(b/186826477): fails to link libctscamera2_jni for device (required for CtsCameraTestCases)
+		"bouncycastle",          // TODO(b/274474005): Need support for custom system_modules.
+		"bouncycastle-test-lib", // TODO(b/274474005): Reverse dependency of bouncycastle
 
 		// genrule incompatibilities
 		"brotli-fuzzer-corpus",                                       // TODO(b/202015218): outputs are in location incompatible with bazel genrule handling.
@@ -1554,6 +1561,10 @@
 
 		// depends on libart-unstripped and new module type llvm_prebuilt_build_tool
 		"check_cfi",
+
+		// TODO(b/297070571): cannot convert prebuilts_etc module which possess identical name and src properties
+		"boringssl_self_test.zygote64.rc",
+		"boringssl_self_test.zygote64_32.rc",
 	}
 
 	// Bazel prod-mode allowlist. Modules in this list are built by Bazel
diff --git a/android/bazel.go b/android/bazel.go
index e4fada0..94b36e3 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -689,3 +689,21 @@
 	})
 	return validatedOutputFilePath
 }
+
+func RunsOn(hostSupported bool, deviceSupported bool, unitTest bool) []string {
+	var runsOn []string
+
+	if hostSupported && deviceSupported {
+		runsOn = []string{"host_without_device", "device"}
+	} else if hostSupported {
+		if unitTest {
+			runsOn = []string{"host_without_device"}
+		} else {
+			runsOn = []string{"host_with_device"}
+		}
+	} else if deviceSupported {
+		runsOn = []string{"device"}
+	}
+
+	return runsOn
+}
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index 02ae5ca..86829ce 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -205,6 +205,21 @@
 	return labels
 }
 
+func BazelLabelForSrcPatternExcludes(ctx BazelConversionPathContext, dir, pattern string, excludes []string) bazel.LabelList {
+	topRelPaths, err := ctx.GlobWithDeps(filepath.Join(dir, pattern), excludes)
+	if err != nil {
+		ctx.ModuleErrorf("Could not search dir: %s for pattern %s due to %v\n", dir, pattern, err)
+	}
+	// An intermediate list of labels relative to `dir` that assumes that there no subpacakges beneath `dir`
+	dirRelLabels := []bazel.Label{}
+	for _, topRelPath := range topRelPaths {
+		dirRelPath := Rel(ctx, dir, topRelPath)
+		dirRelLabels = append(dirRelLabels, bazel.Label{Label: "./" + dirRelPath})
+	}
+	// Return the package boudary resolved labels
+	return TransformSubpackagePaths(ctx.Config(), dir, bazel.MakeLabelList(dirRelLabels))
+}
+
 // Returns true if a prefix + components[:i] is a package boundary.
 //
 // A package boundary is determined by a BUILD file in the directory. This can happen in 2 cases:
diff --git a/android/bazel_paths_test.go b/android/bazel_paths_test.go
index 75b77a3..bed719c 100644
--- a/android/bazel_paths_test.go
+++ b/android/bazel_paths_test.go
@@ -15,6 +15,7 @@
 package android
 
 import (
+	"fmt"
 	"path/filepath"
 	"testing"
 
@@ -114,8 +115,9 @@
 
 type TestBazelConversionPathContext struct {
 	TestBazelConversionContext
-	moduleDir string
-	cfg       Config
+	moduleDir       string
+	cfg             Config
+	mockGlobResults *[]string
 }
 
 func (ctx *TestBazelConversionPathContext) AddNinjaFileDeps(...string) {
@@ -123,7 +125,10 @@
 }
 
 func (ctx *TestBazelConversionPathContext) GlobWithDeps(string, []string) ([]string, error) {
-	panic("Unimplemented")
+	if ctx.mockGlobResults == nil {
+		return []string{}, fmt.Errorf("Set mock glob results first")
+	}
+	return *ctx.mockGlobResults, nil
 }
 
 func (ctx *TestBazelConversionPathContext) PropertyErrorf(string, string, ...interface{}) {
@@ -190,3 +195,46 @@
 		}
 	}
 }
+
+// Check that the files in a specific directory are returned with labels that respect package boundaries
+// Since the test uses a mock for GlobWithDeps, the params passed to BazelLabelForSrcPatternExcludes are no-ops
+func TestBazelLabelForSrcPatternExcludes(t *testing.T) {
+	cfg := NullConfig("out", "out/soong")
+	cfg.fs = pathtools.MockFs(map[string][]byte{
+		"x/Android.bp":   nil,
+		"x/y/Android.bp": nil,
+		// .proto files
+		"foo.proto":     nil,
+		"x/bar.proto":   nil,
+		"x/baz.proto":   nil,
+		"x/y/qux.proto": nil,
+	})
+
+	var ctx BazelConversionPathContext = &TestBazelConversionPathContext{
+		cfg: cfg,
+	}
+
+	// Root dir
+	ctx.(*TestBazelConversionPathContext).mockGlobResults = &[]string{"foo.proto", "x/bar.proto", "x/baz.proto", "x/y/qux.proto"}
+	actualLabelsFromRoot := BazelLabelForSrcPatternExcludes(ctx, ".", "**/*.proto", []string{})
+	expectedLabelsAsString := []string{"foo.proto", "//x:bar.proto", "//x:baz.proto", "//x/y:qux.proto"}
+	for i, actual := range actualLabelsFromRoot.Includes {
+		AssertStringEquals(t, "Error in finding src labels relative to root directory", expectedLabelsAsString[i], actual.Label)
+	}
+
+	// x dir
+	ctx.(*TestBazelConversionPathContext).mockGlobResults = &[]string{"x/bar.proto", "x/baz.proto", "x/y/qux.proto"}
+	actualLabelsFromRoot = BazelLabelForSrcPatternExcludes(ctx, "x", "**/*.proto", []string{})
+	expectedLabelsAsString = []string{"bar.proto", "baz.proto", "//x/y:qux.proto"}
+	for i, actual := range actualLabelsFromRoot.Includes {
+		AssertStringEquals(t, "Error in finding src labels relative to x directory", expectedLabelsAsString[i], actual.Label)
+	}
+
+	// y dir
+	ctx.(*TestBazelConversionPathContext).mockGlobResults = &[]string{"x/y/qux.proto"}
+	actualLabelsFromRoot = BazelLabelForSrcPatternExcludes(ctx, "x/y", "**/*.proto", []string{})
+	expectedLabelsAsString = []string{"qux.proto"}
+	for i, actual := range actualLabelsFromRoot.Includes {
+		AssertStringEquals(t, "Error in finding src labels relative to x/y directory", expectedLabelsAsString[i], actual.Label)
+	}
+}
diff --git a/android/proto.go b/android/proto.go
index b21efd6..0ffb9b6 100644
--- a/android/proto.go
+++ b/android/proto.go
@@ -156,8 +156,9 @@
 
 // Bp2buildProtoInfo contains information necessary to pass on to language specific conversion.
 type Bp2buildProtoInfo struct {
-	Type       *string
-	Proto_libs bazel.LabelList
+	Type                  *string
+	Proto_libs            bazel.LabelList
+	Transitive_proto_libs bazel.LabelList
 }
 
 type ProtoAttrs struct {
@@ -211,6 +212,7 @@
 	}
 
 	var protoLibraries bazel.LabelList
+	var transitiveProtoLibraries bazel.LabelList
 	var directProtoSrcs bazel.LabelList
 
 	// For filegroups that should be converted to proto_library just collect the
@@ -234,6 +236,7 @@
 
 	if len(directProtoSrcs.Includes) > 0 {
 		pkgToSrcs := partitionSrcsByPackage(ctx.ModuleDir(), directProtoSrcs)
+		protoIncludeDirs := []string{}
 		for _, pkg := range SortedStringKeys(pkgToSrcs) {
 			srcs := pkgToSrcs[pkg]
 			attrs := ProtoAttrs{
@@ -262,7 +265,7 @@
 							if dep, ok := includeDirsToProtoDeps[dir]; ok {
 								attrs.Deps.Add(bazel.MakeLabelAttribute(dep))
 							} else {
-								ctx.PropertyErrorf("Could not find the proto_library target for include dir", dir)
+								protoIncludeDirs = append(protoIncludeDirs, dir)
 							}
 						}
 					} else if props.Proto.Type != info.Type && props.Proto.Type != nil {
@@ -308,9 +311,84 @@
 				Label: l,
 			})
 		}
+		protoLibrariesInIncludeDir := createProtoLibraryTargetsForIncludeDirs(ctx, protoIncludeDirs)
+		transitiveProtoLibraries.Append(protoLibrariesInIncludeDir)
 	}
 
 	info.Proto_libs = protoLibraries
+	info.Transitive_proto_libs = transitiveProtoLibraries
 
 	return info, true
 }
+
+var (
+	protoIncludeDirGeneratedSuffix = ".include_dir_bp2build_generated_proto"
+	protoIncludeDirsBp2buildKey    = NewOnceKey("protoIncludeDirsBp2build")
+)
+
+func getProtoIncludeDirsBp2build(config Config) *map[protoIncludeDirKey]bool {
+	return config.Once(protoIncludeDirsBp2buildKey, func() interface{} {
+		return &map[protoIncludeDirKey]bool{}
+	}).(*map[protoIncludeDirKey]bool)
+}
+
+// key for dynamically creating proto_library per proto.include_dirs
+type protoIncludeDirKey struct {
+	dir            string
+	subpackgeInDir string
+}
+
+// createProtoLibraryTargetsForIncludeDirs creates additional proto_library targets for .proto files in includeDirs
+// Since Bazel imposes a constratint that the proto_library must be in the same package as the .proto file, this function
+// might create the targets in a subdirectory of `includeDir`
+// Returns the labels of the proto_library targets
+func createProtoLibraryTargetsForIncludeDirs(ctx Bp2buildMutatorContext, includeDirs []string) bazel.LabelList {
+	var ret bazel.LabelList
+	for _, dir := range includeDirs {
+		if exists, _, _ := ctx.Config().fs.Exists(filepath.Join(dir, "Android.bp")); !exists {
+			ctx.ModuleErrorf("TODO: Add support for proto.include_dir: %v. This directory does not contain an Android.bp file", dir)
+		}
+		dirMap := getProtoIncludeDirsBp2build(ctx.Config())
+		// Find all proto file targets in this dir
+		protoLabelsInDir := BazelLabelForSrcPatternExcludes(ctx, dir, "**/*.proto", []string{})
+		// Partition the labels by package and subpackage(s)
+		protoLabelelsPartitionedByPkg := partitionSrcsByPackage(dir, protoLabelsInDir)
+		for _, pkg := range SortedStringKeys(protoLabelelsPartitionedByPkg) {
+			label := strings.ReplaceAll(dir, "/", ".") + protoIncludeDirGeneratedSuffix
+			ret.Add(&bazel.Label{
+				Label: "//" + pkg + ":" + label,
+			})
+			key := protoIncludeDirKey{dir: dir, subpackgeInDir: pkg}
+			if _, exists := (*dirMap)[key]; exists {
+				// A proto_library has already been created for this package relative to this include dir
+				continue
+			}
+			(*dirMap)[key] = true
+			srcs := protoLabelelsPartitionedByPkg[pkg]
+			rel, err := filepath.Rel(dir, pkg)
+			if err != nil {
+				ctx.ModuleErrorf("Could not create a proto_library in pkg %v due to %v\n", pkg, err)
+			}
+			// Create proto_library
+			attrs := ProtoAttrs{
+				Srcs:                bazel.MakeLabelListAttribute(srcs),
+				Strip_import_prefix: proptools.StringPtr(""),
+			}
+			if rel != "." {
+				attrs.Import_prefix = proptools.StringPtr(rel)
+			}
+			ctx.CreateBazelTargetModule(
+				bazel.BazelTargetModuleProperties{Rule_class: "proto_library"},
+				CommonAttributes{
+					Name: label,
+					Dir:  proptools.StringPtr(pkg),
+					// This proto_library is used to construct a ProtoInfo
+					// But it might not be buildable on its own
+					Tags: bazel.MakeStringListAttribute([]string{"manual"}),
+				},
+				&attrs,
+			)
+		}
+	}
+	return ret
+}
diff --git a/apex/androidmk.go b/apex/androidmk.go
index f469062..b0c3918 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -287,6 +287,7 @@
 			if a.installable() {
 				fmt.Fprintln(w, "LOCAL_SOONG_INSTALLED_MODULE :=", a.installedFile.String())
 				fmt.Fprintln(w, "LOCAL_SOONG_INSTALL_PAIRS :=", a.outputFile.String()+":"+a.installedFile.String())
+				fmt.Fprintln(w, "LOCAL_SOONG_INSTALL_SYMLINKS := ", strings.Join(a.compatSymlinks.Strings(), " "))
 			}
 
 			// Because apex writes .mk with Custom(), we need to write manually some common properties
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 8368db1..da059eb 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -3870,6 +3870,7 @@
 			}
 		`+vndkLibrariesTxtFiles("current"), android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
 				variables.DeviceVndkVersion = proptools.StringPtr(tc.vndkVersion)
+				variables.KeepVndk = proptools.BoolPtr(true)
 			}))
 			ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", tc.expectedFiles)
 		})
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 3509e6c..f2e87c8 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -235,6 +235,7 @@
 					entries.SetString("LOCAL_MODULE_STEM", p.installFilename)
 					entries.SetPath("LOCAL_SOONG_INSTALLED_MODULE", p.installedFile)
 					entries.SetString("LOCAL_SOONG_INSTALL_PAIRS", p.outputApex.String()+":"+p.installedFile.String())
+					entries.AddStrings("LOCAL_SOONG_INSTALL_SYMLINKS", p.compatSymlinks.Strings()...)
 					entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable())
 					entries.AddStrings("LOCAL_OVERRIDES_MODULES", p.prebuiltCommonProperties.Overrides...)
 					p.addRequiredModules(entries)
diff --git a/apex/vndk.go b/apex/vndk.go
index 095e89d..68b3a40 100644
--- a/apex/vndk.go
+++ b/apex/vndk.go
@@ -80,6 +80,10 @@
 			// config targets the 'current' VNDK (see `vndkVersion`).
 			ab.Disable()
 		}
+		if proptools.String(ab.vndkProperties.Vndk_version) != "" &&
+			apiLevel.GreaterThanOrEqualTo(android.ApiLevelOrPanic(mctx, mctx.DeviceConfig().PlatformVndkVersion())) {
+			ab.Disable()
+		}
 	}
 }
 
@@ -103,7 +107,7 @@
 		}
 	} else if a, ok := mctx.Module().(*apexBundle); ok && a.vndkApex {
 		vndkVersion := proptools.StringDefault(a.vndkProperties.Vndk_version, "current")
-		mctx.AddDependency(mctx.Module(), prebuiltTag, cc.VndkLibrariesTxtModules(vndkVersion)...)
+		mctx.AddDependency(mctx.Module(), prebuiltTag, cc.VndkLibrariesTxtModules(vndkVersion, mctx)...)
 	}
 }
 
diff --git a/apex/vndk_test.go b/apex/vndk_test.go
index 21526c3..4327a61 100644
--- a/apex/vndk_test.go
+++ b/apex/vndk_test.go
@@ -51,6 +51,7 @@
 	`+vndkLibrariesTxtFiles("current"),
 		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
 			variables.DeviceVndkVersion = proptools.StringPtr("")
+			variables.KeepVndk = proptools.BoolPtr(true)
 		}),
 	)
 	// VNDK-Lite contains only core variants of VNDK-Sp libraries
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index e70cd10..28dbf7e 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -2394,7 +2394,7 @@
 	},
 	include_build_directory: false,
 }`,
-		ExpectedErr: fmt.Errorf("module \"foo\": Could not find the proto_library target for include dir: external/protobuf/abc"),
+		ExpectedErr: fmt.Errorf("module \"foo\": TODO: Add support for proto.include_dir: external/protobuf/abc. This directory does not contain an Android.bp file"),
 	})
 }
 
@@ -5068,3 +5068,72 @@
 	}
 	runCcLibraryTestCase(t, tc)
 }
+
+func TestProtoIncludeDirs(t *testing.T) {
+	tc := Bp2buildTestCase{
+		Description:                "cc_library depends on .proto files using proto.include_dirs",
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Blueprint: `
+cc_library_static {
+	name: "foo",
+	srcs: [
+	   "foo.proto",
+	],
+	proto: {
+		include_dirs: ["bar"],
+	}
+}
+` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"),
+		Filesystem: map[string]string{
+			"bar/Android.bp":     "",
+			"bar/bar.proto":      "",
+			"bar/baz/Android.bp": "",
+			"bar/baz/baz.proto":  "",
+		},
+	}
+
+	// We will run the test 3 times and check in the root, bar and bar/baz directories
+	// Root dir
+	tc.ExpectedBazelTargets = []string{
+		MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
+			"local_includes":                    `["."]`,
+			"deps":                              `[":libprotobuf-cpp-lite"]`,
+			"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
+		}),
+		MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			"srcs": `["foo.proto"]`,
+		}),
+		MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
+			"deps": `[":foo_proto"]`,
+			"transitive_deps": `[
+        "//bar:bar.include_dir_bp2build_generated_proto",
+        "//bar/baz:bar.include_dir_bp2build_generated_proto",
+    ]`,
+		}),
+	}
+	runCcLibraryTestCase(t, tc)
+
+	// bar dir
+	tc.Dir = "bar"
+	tc.ExpectedBazelTargets = []string{
+		MakeBazelTarget("proto_library", "bar.include_dir_bp2build_generated_proto", AttrNameToString{
+			"srcs":                `["bar.proto"]`,
+			"strip_import_prefix": `""`,
+			"tags":                `["manual"]`,
+		}),
+	}
+	runCcLibraryTestCase(t, tc)
+
+	// bar/baz dir
+	tc.Dir = "bar/baz"
+	tc.ExpectedBazelTargets = []string{
+		MakeBazelTarget("proto_library", "bar.include_dir_bp2build_generated_proto", AttrNameToString{
+			"srcs":                `["//bar/baz:baz.proto"]`,
+			"strip_import_prefix": `""`,
+			"import_prefix":       `"baz"`,
+			"tags":                `["manual"]`,
+		}),
+	}
+	runCcLibraryTestCase(t, tc)
+}
diff --git a/bp2build/cc_test_conversion_test.go b/bp2build/cc_test_conversion_test.go
index 3c037b4..abceac8 100644
--- a/bp2build/cc_test_conversion_test.go
+++ b/bp2build/cc_test_conversion_test.go
@@ -135,6 +135,10 @@
         "//build/bazel/platforms/os:linux_musl": ["linux.cpp"],
         "//conditions:default": [],
     })`,
+				"runs_on": `[
+        "host_without_device",
+        "device",
+    ]`,
 			},
 			},
 		},
@@ -158,6 +162,10 @@
 				"gtest":          "False",
 				"local_includes": `["."]`,
 				"srcs":           `["test.cpp"]`,
+				"runs_on": `[
+        "host_without_device",
+        "device",
+    ]`,
 			},
 			},
 		},
@@ -185,6 +193,10 @@
         ":libgtest_main",
         ":libgtest",
     ]`,
+				"runs_on": `[
+        "host_without_device",
+        "device",
+    ]`,
 			},
 			},
 		},
@@ -215,6 +227,7 @@
         ":libgtest_main",
         ":libgtest",
     ]`,
+				"runs_on": `["device"]`,
 			},
 			},
 		},
@@ -244,6 +257,7 @@
         ":libgtest_main",
         ":libgtest",
     ]`,
+				"runs_on": `["device"]`,
 			},
 			},
 		},
@@ -280,6 +294,7 @@
 				"template_test_config":  `"test_config_template.xml"`,
 				"deps":                  `[":libgtest_isolated_main"]`,
 				"dynamic_deps":          `[":liblog"]`,
+				"runs_on":               `["device"]`,
 			},
 			},
 		},
@@ -306,6 +321,7 @@
         ":libgtest",
         ":libgtest_main",
     ]`,
+				"runs_on": `["device"]`,
 			},
 			},
 		},
@@ -331,6 +347,7 @@
 				"target_compatible_with": `["//build/bazel/platforms/os:android"]`,
 				"deps":                   `[":libgtest_isolated_main"]`,
 				"dynamic_deps":           `[":liblog"]`,
+				"runs_on":                `["device"]`,
 			},
 			},
 		},
@@ -361,12 +378,14 @@
     ]`,
 				"gtest":                  "True",
 				"target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+				"runs_on":                `["device"]`,
 			},
 			},
 			{"cc_test", "mytest_with_no_gtest", AttrNameToString{
 				"local_includes":         `["."]`,
 				"gtest":                  "False",
 				"target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+				"runs_on":                `["device"]`,
 			},
 			},
 		},
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 0157632..7f78e28 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -960,7 +960,7 @@
 	(&linkerAttrs).wholeArchiveDeps.Append(compilerAttrs.exportXsdSrcs)
 	(&linkerAttrs).implementationWholeArchiveDeps.Append(compilerAttrs.xsdSrcs)
 
-	protoDep := bp2buildProto(ctx, module, compilerAttrs.protoSrcs)
+	protoDep := bp2buildProto(ctx, module, compilerAttrs.protoSrcs, linkerAttrs)
 
 	// bp2buildProto will only set wholeStaticLib or implementationWholeStaticLib, but we don't know
 	// which. This will add the newly generated proto library to the appropriate attribute and nothing
diff --git a/cc/cc_test.go b/cc/cc_test.go
index d95ed3f..7ce0f37 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -654,6 +654,7 @@
 	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
 	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
 	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
+	config.TestProductVariables.KeepVndk = BoolPtr(true)
 	ctx := testCcWithConfig(t, config)
 
 	module := ctx.ModuleForTests("llndk.libraries.txt", "android_common")
diff --git a/cc/config/global.go b/cc/config/global.go
index ff5ab05..61ea0ad 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -75,24 +75,22 @@
 		// Help catch common 32/64-bit errors.
 		"-Werror=int-conversion",
 
-		// Disable overly aggressive warning for macros defined with a leading underscore
-		// This happens in AndroidConfig.h, which is included nearly everywhere.
-		// TODO: can we remove this now?
-		"-Wno-reserved-id-macro",
-
 		// Force clang to always output color diagnostics. Ninja will strip the ANSI
 		// color codes if it is not running in a terminal.
 		"-fcolor-diagnostics",
 
-		// Warnings from clang-7.0
+		// -Wno-sign-compare is incompatible with the Google C++ style guidance
+		// to use 'int' for loop indices, and the signal to noise ratio is poor
+		// anyway.
 		"-Wno-sign-compare",
 
-		// Disable -Winconsistent-missing-override until we can clean up the existing
-		// codebase for it.
+		// AIDL generated code redeclares pure virtual methods in each
+		// subsequent version of an interface, so this is currently infeasible
+		// to enable.
 		"-Wno-inconsistent-missing-override",
 
-		// Warnings from clang-10
-		// Nested and array designated initialization is nice to have.
+		// Designated initializer syntax is recommended by the Google C++ style
+		// guide and should not be a warning, at least by default.
 		"-Wno-c99-designator",
 
 		// Many old files still have GNU designator syntax.
@@ -101,6 +99,9 @@
 		// Warnings from clang-12
 		"-Wno-gnu-folding-constant",
 
+		// http://b/145210666
+		"-Wno-error=reorder-init-list",
+
 		// Calls to the APIs that are newer than the min sdk version of the caller should be
 		// guarded with __builtin_available.
 		"-Wunguarded-availability",
@@ -194,6 +195,8 @@
 		"-Wno-gnu-include-next",
 	}
 
+	// These flags are appended after the module's cflags, so they cannot be
+	// overridden from Android.bp files.
 	noOverrideGlobalCflags = []string{
 		"-Werror=bool-operation",
 		"-Werror=format-insufficient-args",
@@ -218,8 +221,6 @@
 		// new warnings are fixed.
 		"-Wno-tautological-constant-compare",
 		"-Wno-tautological-type-limit-compare",
-		// http://b/145210666
-		"-Wno-reorder-init-list",
 		// http://b/145211066
 		"-Wno-implicit-int-float-conversion",
 		// New warnings to be fixed after clang-r377782.
@@ -247,16 +248,30 @@
 
 	noOverride64GlobalCflags = []string{}
 
+	// Similar to noOverrideGlobalCflags, but applies only to third-party code
+	// (anything for which IsThirdPartyPath() in build/soong/android/paths.go
+	// returns true - includes external/, most of vendor/ and most of hardware/)
 	noOverrideExternalGlobalCflags = []string{
 		// http://b/191699019
 		"-Wno-format-insufficient-args",
+		// http://b/296422292
+		// Usually signals a mistake and should be a hard error.
 		"-Wno-sizeof-array-div",
+		// http://b/296321145
+		// Indicates potential memory or stack corruption, so should be changed
+		// to a hard error. Currently triggered by some vendor code.
 		"-Wno-incompatible-function-pointer-types",
+		// http://b/296321508
+		// Introduced in response to a critical security vulnerability and
+		// should be a hard error - it requires only whitespace changes to fix.
+		"-Wno-misleading-indentation",
+		// Triggered by old LLVM code in external/llvm. Likely not worth
+		// enabling since it's a cosmetic issue.
+		"-Wno-bitwise-instead-of-logical",
+
 		"-Wno-unused-but-set-variable",
 		"-Wno-unused-but-set-parameter",
 		"-Wno-unqualified-std-cast-call",
-		"-Wno-bitwise-instead-of-logical",
-		"-Wno-misleading-indentation",
 		"-Wno-array-parameter",
 		"-Wno-gnu-offsetof-extensions",
 	}
diff --git a/cc/proto.go b/cc/proto.go
index 5d9aef6..0ed4381 100644
--- a/cc/proto.go
+++ b/cc/proto.go
@@ -165,7 +165,17 @@
 }
 
 type protoAttributes struct {
-	Deps            bazel.LabelListAttribute
+	Deps bazel.LabelListAttribute
+
+	// A list of proto_library targets that that the proto_library in `deps` depends on
+	// This list is overestimation.
+	// Overestimation is necessary since Soong includes other protos via proto.include_dirs and not
+	// a specific .proto file module explicitly.
+	Transitive_deps bazel.LabelListAttribute
+
+	// A list of cc_library_* targets that the generated cpp code depends on
+	Cc_deps bazel.LabelListAttribute
+
 	Min_sdk_version *string
 }
 
@@ -175,7 +185,7 @@
 	protoDep                     *bazel.LabelAttribute
 }
 
-func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute) bp2buildProtoDeps {
+func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute, la linkerAttributes) bp2buildProtoDeps {
 	var ret bp2buildProtoDeps
 
 	protoInfo, ok := android.Bp2buildProtoProperties(ctx, &m.ModuleBase, protoSrcs)
@@ -204,6 +214,35 @@
 
 	var protoAttrs protoAttributes
 	protoAttrs.Deps.SetValue(protoInfo.Proto_libs)
+	protoAttrs.Transitive_deps.SetValue(protoInfo.Transitive_proto_libs)
+
+	// Add the implementation deps of the top-level cc_library_static
+	// This is necessary to compile the internal root of cc_proto_library.
+	// Without this, clang might not be able to find .h files that the generated cpp files depends on
+	protoAttrs.Cc_deps = *la.implementationDeps.Clone()
+	protoAttrs.Cc_deps.Append(la.implementationDynamicDeps)
+	protoAttrs.Cc_deps.Append(la.implementationWholeArchiveDeps)
+	protoAttrs.Cc_deps.Append(la.wholeArchiveDeps)
+	// Subtract myself to prevent possible circular dep
+	protoAttrs.Cc_deps = bazel.SubtractBazelLabelListAttribute(
+		protoAttrs.Cc_deps,
+		bazel.MakeLabelListAttribute(
+			bazel.MakeLabelList([]bazel.Label{
+				bazel.Label{Label: ":" + m.Name() + suffix},
+			}),
+		),
+	)
+	// Subtract the protobuf libraries since cc_proto_library implicitly adds them
+	protoAttrs.Cc_deps = bazel.SubtractBazelLabelListAttribute(
+		protoAttrs.Cc_deps,
+		bazel.MakeLabelListAttribute(
+			bazel.MakeLabelList([]bazel.Label{
+				bazel.Label{Label: "//external/protobuf:libprotobuf-cpp-full", OriginalModuleName: "libprotobuf-cpp-full"},
+				bazel.Label{Label: "//external/protobuf:libprotobuf-cpp-lite", OriginalModuleName: "libprotobuf-cpp-lite"},
+			}),
+		),
+	)
+
 	protoAttrs.Min_sdk_version = m.Properties.Min_sdk_version
 
 	name := m.Name() + suffix
diff --git a/cc/test.go b/cc/test.go
index 0be2301..adc80c2 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -686,6 +686,8 @@
 
 	tidyAttributes
 	tradefed.TestConfigAttributes
+
+	Runs_on bazel.StringListAttribute
 }
 
 // testBinaryBp2build is the bp2build converter for cc_test modules. A cc_test's
@@ -730,6 +732,8 @@
 
 	addImplicitGtestDeps(ctx, &testBinaryAttrs, gtest, gtestIsolated)
 
+	var unitTest *bool
+
 	for _, testProps := range m.GetProperties() {
 		if p, ok := testProps.(*TestBinaryProperties); ok {
 			useVendor := false // TODO Bug: 262914724
@@ -745,9 +749,15 @@
 				&testInstallBase,
 			)
 			testBinaryAttrs.TestConfigAttributes = testConfigAttributes
+			unitTest = p.Test_options.Unit_test
 		}
 	}
 
+	testBinaryAttrs.Runs_on = bazel.MakeStringListAttribute(android.RunsOn(
+		m.ModuleBase.HostSupported(),
+		m.ModuleBase.DeviceSupported(),
+		gtest || (unitTest != nil && *unitTest)))
+
 	// TODO (b/262914724): convert to tradefed_cc_test and tradefed_cc_test_host
 	ctx.CreateBazelTargetModule(
 		bazel.BazelTargetModuleProperties{
diff --git a/cc/vndk.go b/cc/vndk.go
index 7a2286e..5ac5032 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -39,25 +39,46 @@
 	vndkUsingCoreVariantLibrariesTxt = "vndkcorevariant.libraries.txt"
 )
 
-func VndkLibrariesTxtModules(vndkVersion string) []string {
+func VndkLibrariesTxtModules(vndkVersion string, ctx android.BaseModuleContext) []string {
 	if vndkVersion == "current" {
-		return []string{
-			llndkLibrariesTxt,
-			vndkCoreLibrariesTxt,
-			vndkSpLibrariesTxt,
-			vndkPrivateLibrariesTxt,
-			vndkProductLibrariesTxt,
+		// We can assume all txt files are snapshotted if we find one of them.
+		currentVndkSnapshotted := ctx.OtherModuleExists(insertVndkVersion(llndkLibrariesTxt, ctx.DeviceConfig().PlatformVndkVersion()))
+		if currentVndkSnapshotted {
+			// If the current VNDK is already snapshotted (which can happen with
+			// the `next` config), use the prebuilt txt files in the snapshot.
+			// This is because the txt files built from source are probably be
+			// for the in-development version.
+			vndkVersion = ctx.DeviceConfig().PlatformVndkVersion()
+		} else {
+			// Use the txt files generated from the source
+			result := []string{
+				vndkCoreLibrariesTxt,
+				vndkSpLibrariesTxt,
+				vndkPrivateLibrariesTxt,
+				vndkProductLibrariesTxt,
+			}
+
+			// TODO(b/290159430) This part will not be required once deprecation
+			// of VNDK is handled with 'ro.vndk.version' property
+			if !ctx.Config().IsVndkDeprecated() {
+				result = append(result, llndkLibrariesTxt)
+			}
+
+			return result
 		}
 	}
+
 	// Snapshot vndks have their own *.libraries.VER.txt files.
 	// Note that snapshots don't have "vndkcorevariant.libraries.VER.txt"
-	return []string{
-		insertVndkVersion(llndkLibrariesTxt, vndkVersion),
+	result := []string{
 		insertVndkVersion(vndkCoreLibrariesTxt, vndkVersion),
 		insertVndkVersion(vndkSpLibrariesTxt, vndkVersion),
 		insertVndkVersion(vndkPrivateLibrariesTxt, vndkVersion),
 		insertVndkVersion(vndkProductLibrariesTxt, vndkVersion),
+		insertVndkVersion(llndkLibrariesTxt, vndkVersion),
 	}
+
+	return result
 }
 
 type VndkProperties struct {
@@ -352,11 +373,19 @@
 		return false
 	}
 
-	// prebuilt vndk modules should match with device
 	// TODO(b/142675459): Use enabled: to select target device in vndk_prebuilt_shared
 	// When b/142675459 is landed, remove following check
-	if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok && !p.MatchesWithDevice(mctx.DeviceConfig()) {
-		return false
+	if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok {
+		// prebuilt vndk modules should match with device
+		if !p.MatchesWithDevice(mctx.DeviceConfig()) {
+			return false
+		}
+
+		// ignore prebuilt vndk modules that are newer than or equal to the platform vndk version
+		platformVndkApiLevel := android.ApiLevelOrPanic(mctx, mctx.DeviceConfig().PlatformVndkVersion())
+		if platformVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(mctx, p.Version())) {
+			return false
+		}
 	}
 
 	if lib, ok := m.linker.(libraryInterface); ok {
@@ -518,12 +547,25 @@
 	return filename
 }
 
+func (txt *vndkLibrariesTxt) DepsMutator(mctx android.BottomUpMutatorContext) {
+	versionedName := insertVndkVersion(txt.Name(), mctx.DeviceConfig().PlatformVndkVersion())
+	if mctx.OtherModuleExists(versionedName) {
+		// If the prebuilt vndk libraries txt files exist, install them instead.
+		txt.HideFromMake()
+		mctx.AddDependency(txt, nil, versionedName)
+	}
+}
+
 func (txt *vndkLibrariesTxt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	var filename string
-	if BoolDefault(txt.properties.Insert_vndk_version, true) {
+	filename := txt.Name()
+
+	shouldInsertVndkVersion := BoolDefault(txt.properties.Insert_vndk_version, true)
+	// llndk.libraries.txt file installed in the system image should not contain version info.
+	if ctx.Config().IsVndkDeprecated() && txt.Name() == llndkLibrariesTxt {
+		shouldInsertVndkVersion = false
+	}
+	if shouldInsertVndkVersion {
 		filename = insertVndkVersion(txt.Name(), ctx.DeviceConfig().PlatformVndkVersion())
-	} else {
-		filename = txt.Name()
 	}
 
 	txt.outputFile = android.PathForModuleOut(ctx, filename).OutputPath
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index 37819a4..5e526db 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -131,6 +131,12 @@
 
 func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
 	flags Flags, deps PathDeps, objs Objects) android.Path {
+	platformVndkApiLevel := android.ApiLevelOrPanic(ctx, ctx.DeviceConfig().PlatformVndkVersion())
+	if platformVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(ctx, p.Version())) {
+		// This prebuilt VNDK module is not required for the current build
+		ctx.Module().HideFromMake()
+		return nil
+	}
 
 	if !p.MatchesWithDevice(ctx.DeviceConfig()) {
 		ctx.Module().HideFromMake()
diff --git a/genrule/genrule.go b/genrule/genrule.go
index aa4295d..8e3f278 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -140,7 +140,7 @@
 	// prebuilts or scripts that do not need a module to build them.
 	Tools []string
 
-	// Local file that is used as the tool
+	// Local files that are used by the tool
 	Tool_files []string `android:"path"`
 
 	// List of directories to export generated headers from
@@ -403,7 +403,6 @@
 	}
 
 	addLabelsForInputs := func(propName string, include, exclude []string) android.Paths {
-
 		includeDirInPaths := ctx.DeviceConfig().BuildBrokenInputDir(g.Name())
 		var srcFiles android.Paths
 		for _, in := range include {
diff --git a/java/aar.go b/java/aar.go
index 308a48c..0216196 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -30,7 +30,6 @@
 )
 
 type AndroidLibraryDependency interface {
-	LibraryDependency
 	ExportPackage() android.Path
 	ResourcesNodeDepSet() *android.DepSet[*resourcesNode]
 	RRODirsDepSet() *android.DepSet[rroDir]
@@ -778,17 +777,9 @@
 		ctx.CheckbuildFile(a.aarFile)
 	}
 
-	a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles,
-		android.PathsForModuleSrc(ctx, a.dexProperties.Optimize.Proguard_flags_files)...)
-
-	ctx.VisitDirectDeps(func(m android.Module) {
-		if ctx.OtherModuleDependencyTag(m) == staticLibTag {
-			if lib, ok := m.(LibraryDependency); ok {
-				a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
-			}
-		}
-	})
-	a.exportedProguardFlagFiles = android.FirstUniquePaths(a.exportedProguardFlagFiles)
+	proguardSpecInfo := a.collectProguardSpecInfo(ctx)
+	ctx.SetProvider(ProguardSpecInfoProvider, proguardSpecInfo)
+	a.exportedProguardFlagFiles = proguardSpecInfo.ProguardFlagsFiles.ToList()
 
 	prebuiltJniPackages := android.Paths{}
 	ctx.VisitDirectDeps(func(module android.Module) {
@@ -939,10 +930,6 @@
 func (a *AARImport) ExportPackage() android.Path {
 	return a.exportPackage
 }
-func (a *AARImport) ExportedProguardFlagFiles() android.Paths {
-	return android.Paths{a.proguardFlags}
-}
-
 func (a *AARImport) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
 	return a.resourcesNodesDepSet
 }
@@ -1046,10 +1033,17 @@
 
 	extractedAARDir := android.PathForModuleOut(ctx, "aar")
 	a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar")
-	a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
 	a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
 	aarRTxt := extractedAARDir.Join(ctx, "R.txt")
 	a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip")
+	a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
+	ctx.SetProvider(ProguardSpecInfoProvider, ProguardSpecInfo{
+		ProguardFlagsFiles: android.NewDepSet[android.Path](
+			android.POSTORDER,
+			android.Paths{a.proguardFlags},
+			nil,
+		),
+	})
 
 	ctx.Build(pctx, android.BuildParams{
 		Rule:        unzipAAR,
diff --git a/java/app.go b/java/app.go
index 1d1ea97..7cf86c0 100755
--- a/java/app.go
+++ b/java/app.go
@@ -200,10 +200,6 @@
 	return Bool(a.properties.Installable)
 }
 
-func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
-	return nil
-}
-
 func (a *AndroidApp) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
 	return a.aapt.resourcesNodesDepSet
 }
@@ -482,8 +478,10 @@
 func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
 	var staticLibProguardFlagFiles android.Paths
 	ctx.VisitDirectDeps(func(m android.Module) {
-		if lib, ok := m.(LibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag {
-			staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
+		depProguardInfo := ctx.OtherModuleProvider(m, ProguardSpecInfoProvider).(ProguardSpecInfo)
+		staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
+		if ctx.OtherModuleDependencyTag(m) == staticLibTag {
+			staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...)
 		}
 	})
 
diff --git a/java/base.go b/java/base.go
index f5eb01c..4fe093a 100644
--- a/java/base.go
+++ b/java/base.go
@@ -622,6 +622,8 @@
 			return android.Paths{j.dexer.proguardDictionary.Path()}, nil
 		}
 		return nil, fmt.Errorf("%q was requested, but no output file was found.", tag)
+	case ".generated_srcjars":
+		return j.properties.Generated_srcjars, nil
 	default:
 		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
 	}
@@ -1670,6 +1672,49 @@
 	return android.InList("androidx.compose.runtime_runtime", j.properties.Static_libs)
 }
 
+func (j *Module) collectProguardSpecInfo(ctx android.ModuleContext) ProguardSpecInfo {
+	transitiveUnconditionalExportedFlags := []*android.DepSet[android.Path]{}
+	transitiveProguardFlags := []*android.DepSet[android.Path]{}
+
+	ctx.VisitDirectDeps(func(m android.Module) {
+		depProguardInfo := ctx.OtherModuleProvider(m, ProguardSpecInfoProvider).(ProguardSpecInfo)
+		depTag := ctx.OtherModuleDependencyTag(m)
+
+		if depProguardInfo.UnconditionallyExportedProguardFlags != nil {
+			transitiveUnconditionalExportedFlags = append(transitiveUnconditionalExportedFlags, depProguardInfo.UnconditionallyExportedProguardFlags)
+			transitiveProguardFlags = append(transitiveProguardFlags, depProguardInfo.UnconditionallyExportedProguardFlags)
+		}
+
+		if depTag == staticLibTag && depProguardInfo.ProguardFlagsFiles != nil {
+			transitiveProguardFlags = append(transitiveProguardFlags, depProguardInfo.ProguardFlagsFiles)
+		}
+	})
+
+	directUnconditionalExportedFlags := android.Paths{}
+	proguardFlagsForThisModule := android.PathsForModuleSrc(ctx, j.dexProperties.Optimize.Proguard_flags_files)
+	exportUnconditionally := proptools.Bool(j.dexProperties.Optimize.Export_proguard_flags_files)
+	if exportUnconditionally {
+		// if we explicitly export, then our unconditional exports are the same as our transitive flags
+		transitiveUnconditionalExportedFlags = transitiveProguardFlags
+		directUnconditionalExportedFlags = proguardFlagsForThisModule
+	}
+
+	return ProguardSpecInfo{
+		Export_proguard_flags_files: exportUnconditionally,
+		ProguardFlagsFiles: android.NewDepSet[android.Path](
+			android.POSTORDER,
+			proguardFlagsForThisModule,
+			transitiveProguardFlags,
+		),
+		UnconditionallyExportedProguardFlags: android.NewDepSet[android.Path](
+			android.POSTORDER,
+			directUnconditionalExportedFlags,
+			transitiveUnconditionalExportedFlags,
+		),
+	}
+
+}
+
 // Returns a copy of the supplied flags, but with all the errorprone-related
 // fields copied to the regular build's fields.
 func enableErrorproneFlags(flags javaBuilderFlags) javaBuilderFlags {
diff --git a/java/dex.go b/java/dex.go
index 7e7da00..df501bf 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -71,6 +71,10 @@
 
 		// Specifies the locations of files containing proguard flags.
 		Proguard_flags_files []string `android:"path"`
+
+		// If true, transitive reverse dependencies of this module will have this
+		// module's proguard spec appended to their optimization action
+		Export_proguard_flags_files *bool
 	}
 
 	// Keep the data uncompressed. We always need uncompressed dex for execution,
diff --git a/java/dex_test.go b/java/dex_test.go
index 2ba3831..ec1ef15 100644
--- a/java/dex_test.go
+++ b/java/dex_test.go
@@ -15,6 +15,7 @@
 package java
 
 import (
+	"fmt"
 	"testing"
 
 	"android/soong/android"
@@ -327,7 +328,7 @@
 		fooD8.Args["d8Flags"], staticLibHeader.String())
 }
 
-func TestProguardFlagsInheritance(t *testing.T) {
+func TestProguardFlagsInheritanceStatic(t *testing.T) {
 	result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
 		android_app {
 			name: "app",
@@ -380,3 +381,246 @@
 	android.AssertStringDoesContain(t, "expected tertiary_lib's proguard flags from inherited dep",
 		appR8.Args["r8Flags"], "tertiary.flags")
 }
+
+func TestProguardFlagsInheritance(t *testing.T) {
+	directDepFlagsFileName := "direct_dep.flags"
+	transitiveDepFlagsFileName := "transitive_dep.flags"
+	bp := `
+		android_app {
+			name: "app",
+			static_libs: ["androidlib"], // this must be static_libs to initate dexing
+			platform_apis: true,
+		}
+
+		android_library {
+			name: "androidlib",
+			static_libs: ["app_dep"],
+		}
+
+		java_library {
+			name: "app_dep",
+			%s: ["dep"],
+		}
+
+		java_library {
+			name: "dep",
+			%s: ["transitive_dep"],
+			optimize: {
+				proguard_flags_files: ["direct_dep.flags"],
+				export_proguard_flags_files: %v,
+			},
+		}
+
+		java_library {
+			name: "transitive_dep",
+			optimize: {
+				proguard_flags_files: ["transitive_dep.flags"],
+				export_proguard_flags_files: %v,
+			},
+		}
+	`
+
+	testcases := []struct {
+		name                           string
+		depType                        string
+		depExportsFlagsFiles           bool
+		transitiveDepType              string
+		transitiveDepExportsFlagsFiles bool
+		expectedFlagsFiles             []string
+	}{
+		{
+			name:                           "libs_export_libs_export",
+			depType:                        "libs",
+			depExportsFlagsFiles:           true,
+			transitiveDepType:              "libs",
+			transitiveDepExportsFlagsFiles: true,
+			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
+		},
+		{
+			name:                           "static_export_libs_export",
+			depType:                        "static_libs",
+			depExportsFlagsFiles:           true,
+			transitiveDepType:              "libs",
+			transitiveDepExportsFlagsFiles: true,
+			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
+		},
+		{
+			name:                           "libs_no-export_static_export",
+			depType:                        "libs",
+			depExportsFlagsFiles:           false,
+			transitiveDepType:              "static_libs",
+			transitiveDepExportsFlagsFiles: true,
+			expectedFlagsFiles:             []string{transitiveDepFlagsFileName},
+		},
+		{
+			name:                           "static_no-export_static_export",
+			depType:                        "static_libs",
+			depExportsFlagsFiles:           false,
+			transitiveDepType:              "static_libs",
+			transitiveDepExportsFlagsFiles: true,
+			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
+		},
+		{
+			name:                           "libs_export_libs_no-export",
+			depType:                        "libs",
+			depExportsFlagsFiles:           true,
+			transitiveDepType:              "libs",
+			transitiveDepExportsFlagsFiles: false,
+			expectedFlagsFiles:             []string{directDepFlagsFileName},
+		},
+		{
+			name:                           "static_export_libs_no-export",
+			depType:                        "static_libs",
+			depExportsFlagsFiles:           true,
+			transitiveDepType:              "libs",
+			transitiveDepExportsFlagsFiles: false,
+			expectedFlagsFiles:             []string{directDepFlagsFileName},
+		},
+		{
+			name:                           "libs_no-export_static_no-export",
+			depType:                        "libs",
+			depExportsFlagsFiles:           false,
+			transitiveDepType:              "static_libs",
+			transitiveDepExportsFlagsFiles: false,
+			expectedFlagsFiles:             []string{},
+		},
+		{
+			name:                           "static_no-export_static_no-export",
+			depType:                        "static_libs",
+			depExportsFlagsFiles:           false,
+			transitiveDepType:              "static_libs",
+			transitiveDepExportsFlagsFiles: false,
+			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
+		},
+		{
+			name:                           "libs_no-export_libs_export",
+			depType:                        "libs",
+			depExportsFlagsFiles:           false,
+			transitiveDepType:              "libs",
+			transitiveDepExportsFlagsFiles: true,
+			expectedFlagsFiles:             []string{transitiveDepFlagsFileName},
+		},
+		{
+			name:                           "static_no-export_libs_export",
+			depType:                        "static_libs",
+			depExportsFlagsFiles:           false,
+			transitiveDepType:              "libs",
+			transitiveDepExportsFlagsFiles: true,
+			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
+		},
+		{
+			name:                           "libs_export_static_export",
+			depType:                        "libs",
+			depExportsFlagsFiles:           true,
+			transitiveDepType:              "static_libs",
+			transitiveDepExportsFlagsFiles: true,
+			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
+		},
+		{
+			name:                           "static_export_static_export",
+			depType:                        "static_libs",
+			depExportsFlagsFiles:           true,
+			transitiveDepType:              "static_libs",
+			transitiveDepExportsFlagsFiles: true,
+			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
+		},
+		{
+			name:                           "libs_no-export_libs_no-export",
+			depType:                        "libs",
+			depExportsFlagsFiles:           false,
+			transitiveDepType:              "libs",
+			transitiveDepExportsFlagsFiles: false,
+			expectedFlagsFiles:             []string{},
+		},
+		{
+			name:                           "static_no-export_libs_no-export",
+			depType:                        "static_libs",
+			depExportsFlagsFiles:           false,
+			transitiveDepType:              "libs",
+			transitiveDepExportsFlagsFiles: false,
+			expectedFlagsFiles:             []string{directDepFlagsFileName},
+		},
+		{
+			name:                           "libs_export_static_no-export",
+			depType:                        "libs",
+			depExportsFlagsFiles:           true,
+			transitiveDepType:              "static_libs",
+			transitiveDepExportsFlagsFiles: false,
+			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
+		},
+		{
+			name:                           "static_export_static_no-export",
+			depType:                        "static_libs",
+			depExportsFlagsFiles:           true,
+			transitiveDepType:              "static_libs",
+			transitiveDepExportsFlagsFiles: false,
+			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
+		},
+	}
+
+	for _, tc := range testcases {
+		t.Run(tc.name, func(t *testing.T) {
+			result := android.GroupFixturePreparers(
+				PrepareForTestWithJavaDefaultModules,
+				android.FixtureMergeMockFs(android.MockFS{
+					directDepFlagsFileName:     nil,
+					transitiveDepFlagsFileName: nil,
+				}),
+			).RunTestWithBp(t,
+				fmt.Sprintf(
+					bp,
+					tc.depType,
+					tc.transitiveDepType,
+					tc.depExportsFlagsFiles,
+					tc.transitiveDepExportsFlagsFiles,
+				),
+			)
+			appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
+
+			shouldHaveDepFlags := android.InList(directDepFlagsFileName, tc.expectedFlagsFiles)
+			if shouldHaveDepFlags {
+				android.AssertStringDoesContain(t, "expected deps's proguard flags",
+					appR8.Args["r8Flags"], directDepFlagsFileName)
+			} else {
+				android.AssertStringDoesNotContain(t, "app did not expect deps's proguard flags",
+					appR8.Args["r8Flags"], directDepFlagsFileName)
+			}
+
+			shouldHaveTransitiveDepFlags := android.InList(transitiveDepFlagsFileName, tc.expectedFlagsFiles)
+			if shouldHaveTransitiveDepFlags {
+				android.AssertStringDoesContain(t, "expected transitive deps's proguard flags",
+					appR8.Args["r8Flags"], transitiveDepFlagsFileName)
+			} else {
+				android.AssertStringDoesNotContain(t, "app did not expect transitive deps's proguard flags",
+					appR8.Args["r8Flags"], transitiveDepFlagsFileName)
+			}
+		})
+	}
+}
+
+func TestProguardFlagsInheritanceAppImport(t *testing.T) {
+	bp := `
+		android_app {
+			name: "app",
+			static_libs: ["aarimport"], // this must be static_libs to initate dexing
+			platform_apis: true,
+		}
+
+		android_library {
+			name: "androidlib",
+			static_libs: ["aarimport"],
+		}
+
+		android_library_import {
+			name: "aarimport",
+			aars: ["import.aar"],
+		}
+	`
+	result := android.GroupFixturePreparers(
+		PrepareForTestWithJavaDefaultModules,
+	).RunTestWithBp(t, bp)
+
+	appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
+	android.AssertStringDoesContain(t, "expected aarimports's proguard flags",
+		appR8.Args["r8Flags"], "proguard.txt")
+}
diff --git a/java/generated_java_library.go b/java/generated_java_library.go
index f9baa85..1cab6ac 100644
--- a/java/generated_java_library.go
+++ b/java/generated_java_library.go
@@ -78,11 +78,6 @@
 	checkPropertyEmpty(ctx, module, "exclude_srcs", module.Library.properties.Exclude_srcs)
 	checkPropertyEmpty(ctx, module, "java_resource_dirs", module.Library.properties.Java_resource_dirs)
 	checkPropertyEmpty(ctx, module, "exclude_java_resource_dirs", module.Library.properties.Exclude_java_resource_dirs)
-	// No additional libraries. The generator should add anything necessary automatically
-	// by returning something from ____ (TODO: Additional libraries aren't needed now, so
-	// these are just blocked).
-	checkPropertyEmpty(ctx, module, "libs", module.Library.properties.Libs)
-	checkPropertyEmpty(ctx, module, "static_libs", module.Library.properties.Static_libs)
 	// Restrict these for no good reason other than to limit the surface area. If there's a
 	// good use case put them back.
 	checkPropertyEmpty(ctx, module, "plugins", module.Library.properties.Plugins)
diff --git a/java/java.go b/java/java.go
index 70aba8e..5f59fe4 100644
--- a/java/java.go
+++ b/java/java.go
@@ -225,6 +225,23 @@
 	}, "jar_name", "partition", "main_class")
 )
 
+type ProguardSpecInfo struct {
+	// If true, proguard flags files will be exported to reverse dependencies across libs edges
+	// If false, proguard flags files will only be exported to reverse dependencies across
+	// static_libs edges.
+	Export_proguard_flags_files bool
+
+	// TransitiveDepsProguardSpecFiles is a depset of paths to proguard flags files that are exported from
+	// all transitive deps. This list includes all proguard flags files from transitive static dependencies,
+	// and all proguard flags files from transitive libs dependencies which set `export_proguard_spec: true`.
+	ProguardFlagsFiles *android.DepSet[android.Path]
+
+	// implementation detail to store transitive proguard flags files from exporting shared deps
+	UnconditionallyExportedProguardFlags *android.DepSet[android.Path]
+}
+
+var ProguardSpecInfoProvider = blueprint.NewProvider(ProguardSpecInfo{})
+
 // JavaInfo contains information about a java module for use by modules that depend on it.
 type JavaInfo struct {
 	// HeaderJars is a list of jars that can be passed as the javac classpath in order to link
@@ -310,11 +327,6 @@
 	ClassLoaderContexts() dexpreopt.ClassLoaderContextMap
 }
 
-// Provides transitive Proguard flag files to downstream DEX jars.
-type LibraryDependency interface {
-	ExportedProguardFlagFiles() android.Paths
-}
-
 // TODO(jungjw): Move this to kythe.go once it's created.
 type xref interface {
 	XrefJavaFiles() android.Paths
@@ -626,12 +638,6 @@
 	InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths)
 }
 
-var _ LibraryDependency = (*Library)(nil)
-
-func (j *Library) ExportedProguardFlagFiles() android.Paths {
-	return j.exportedProguardFlagFiles
-}
-
 var _ android.ApexModule = (*Library)(nil)
 
 // Provides access to the list of permitted packages from apex boot jars.
@@ -730,15 +736,9 @@
 		j.installFile = ctx.InstallFile(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...)
 	}
 
-	j.exportedProguardFlagFiles = append(j.exportedProguardFlagFiles,
-		android.PathsForModuleSrc(ctx, j.dexProperties.Optimize.Proguard_flags_files)...)
-	ctx.VisitDirectDeps(func(m android.Module) {
-		if lib, ok := m.(LibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag {
-			j.exportedProguardFlagFiles = append(j.exportedProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
-		}
-	})
-	j.exportedProguardFlagFiles = android.FirstUniquePaths(j.exportedProguardFlagFiles)
-
+	proguardSpecInfo := j.collectProguardSpecInfo(ctx)
+	ctx.SetProvider(ProguardSpecInfoProvider, proguardSpecInfo)
+	j.exportedProguardFlagFiles = proguardSpecInfo.ProguardFlagsFiles.ToList()
 }
 
 func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
diff --git a/python/tests/runtest.sh b/python/tests/runtest.sh
index f4abae5..c44ec58 100755
--- a/python/tests/runtest.sh
+++ b/python/tests/runtest.sh
@@ -24,11 +24,16 @@
 fi
 
 if [[ ( ! -f $ANDROID_HOST_OUT/nativetest64/par_test/par_test ) ||
-      ( ! -f $ANDROID_HOST_OUT/bin/py2-cmd ) ||
       ( ! -f $ANDROID_HOST_OUT/bin/py3-cmd )]]; then
   echo "Run 'm par_test py2-cmd py3-cmd' first"
   exit 1
 fi
+if [ $(uname -s) = Linux ]; then
+  if [[ ! -f $ANDROID_HOST_OUT/bin/py2-cmd ]]; then
+    echo "Run 'm par_test py2-cmd py3-cmd' first"
+    exit 1
+  fi
+fi
 
 export LD_LIBRARY_PATH=$ANDROID_HOST_OUT/lib64
 
@@ -42,11 +47,15 @@
 
 cd $(dirname ${BASH_SOURCE[0]})
 
-PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py2-cmd py-cmd_test.py
+if [ $(uname -s) = Linux ]; then
+  PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py2-cmd py-cmd_test.py
+fi
 PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py3-cmd py-cmd_test.py
 
-ARGTEST=true PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py2-cmd py-cmd_test.py arg1 arg2
-ARGTEST2=true PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py2-cmd py-cmd_test.py --arg1 arg2
+if [ $(uname -s) = Linux ]; then
+  ARGTEST=true PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py2-cmd py-cmd_test.py arg1 arg2
+  ARGTEST2=true PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py2-cmd py-cmd_test.py --arg1 arg2
+fi
 
 ARGTEST=true PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py3-cmd py-cmd_test.py arg1 arg2
 ARGTEST2=true PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py3-cmd py-cmd_test.py --arg1 arg2
diff --git a/rust/androidmk.go b/rust/androidmk.go
index 5e680b0..c684e81 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -61,7 +61,7 @@
 				entries.AddStrings("LOCAL_RLIB_LIBRARIES", mod.Properties.AndroidMkRlibs...)
 				entries.AddStrings("LOCAL_DYLIB_LIBRARIES", mod.Properties.AndroidMkDylibs...)
 				entries.AddStrings("LOCAL_PROC_MACRO_LIBRARIES", mod.Properties.AndroidMkProcMacroLibs...)
-				entries.AddStrings("LOCAL_SHARED_LIBRARIES", mod.Properties.AndroidMkSharedLibs...)
+				entries.AddStrings("LOCAL_SHARED_LIBRARIES", mod.transitiveAndroidMkSharedLibs.ToList()...)
 				entries.AddStrings("LOCAL_STATIC_LIBRARIES", mod.Properties.AndroidMkStaticLibs...)
 				entries.AddStrings("LOCAL_SOONG_LINK_TYPE", mod.makeLinkType)
 				if mod.UseVndk() {
diff --git a/rust/binary_test.go b/rust/binary_test.go
index fc4c560..dff94ac 100644
--- a/rust/binary_test.go
+++ b/rust/binary_test.go
@@ -185,7 +185,7 @@
 	if !android.InList("libc", fizzMod.Properties.AndroidMkStaticLibs) {
 		t.Errorf("static binary not linking against libc as a static library")
 	}
-	if len(fizzMod.Properties.AndroidMkSharedLibs) > 0 {
+	if len(fizzMod.transitiveAndroidMkSharedLibs.ToList()) > 0 {
 		t.Errorf("static binary incorrectly linking against shared libraries")
 	}
 }
diff --git a/rust/config/lints.go b/rust/config/lints.go
index ef6b315..9322981 100644
--- a/rust/config/lints.go
+++ b/rust/config/lints.go
@@ -46,6 +46,7 @@
 		"-A deprecated",
 		"-D missing-docs",
 		"-D warnings",
+		"-D unsafe_op_in_unsafe_fn",
 	}
 	// Default Clippy lints. These are applied on top of defaultRustcLints.
 	// It should be assumed that any warning lint will be promoted to a
@@ -55,6 +56,7 @@
 		"-A clippy::unnecessary-wraps",
 		"-A clippy::unusual-byte-groupings",
 		"-A clippy::upper-case-acronyms",
+		"-D clippy::undocumented_unsafe_blocks",
 	}
 
 	// Rust lints for vendor code.
diff --git a/rust/library_test.go b/rust/library_test.go
index add7173..30ef333 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -196,6 +196,65 @@
 	}
 }
 
+func TestNativeDependencyOfRlib(t *testing.T) {
+	ctx := testRust(t, `
+		rust_ffi_static {
+			name: "libffi_static",
+			crate_name: "ffi_static",
+			rlibs: ["librust_rlib"],
+			srcs: ["foo.rs"],
+		}
+		rust_library_rlib {
+			name: "librust_rlib",
+			crate_name: "rust_rlib",
+			srcs: ["foo.rs"],
+			shared_libs: ["shared_cc_dep"],
+			static_libs: ["static_cc_dep"],
+		}
+		cc_library_shared {
+			name: "shared_cc_dep",
+			srcs: ["foo.cpp"],
+		}
+		cc_library_static {
+			name: "static_cc_dep",
+			srcs: ["foo.cpp"],
+		}
+		`)
+
+	rustRlibRlibStd := ctx.ModuleForTests("librust_rlib", "android_arm64_armv8-a_rlib_rlib-std")
+	rustRlibDylibStd := ctx.ModuleForTests("librust_rlib", "android_arm64_armv8-a_rlib_dylib-std")
+	ffiStatic := ctx.ModuleForTests("libffi_static", "android_arm64_armv8-a_static")
+
+	modules := []android.TestingModule{
+		rustRlibRlibStd,
+		rustRlibDylibStd,
+		ffiStatic,
+	}
+
+	// librust_rlib specifies -L flag to cc deps output directory on rustc command
+	// and re-export the cc deps to rdep libffi_static
+	// When building rlib crate, rustc doesn't link the native libraries
+	// The build system assumes the  cc deps will be at the final linkage (either a shared library or binary)
+	// Hence, these flags are no-op
+	// TODO: We could consider removing these flags
+	for _, module := range modules {
+		if !strings.Contains(module.Rule("rustc").Args["libFlags"],
+			"-L out/soong/.intermediates/shared_cc_dep/android_arm64_armv8-a_shared/") {
+			t.Errorf(
+				"missing -L flag for shared_cc_dep, rustcFlags: %#v",
+				rustRlibRlibStd.Rule("rustc").Args["libFlags"],
+			)
+		}
+		if !strings.Contains(module.Rule("rustc").Args["libFlags"],
+			"-L out/soong/.intermediates/static_cc_dep/android_arm64_armv8-a_static/") {
+			t.Errorf(
+				"missing -L flag for static_cc_dep, rustcFlags: %#v",
+				rustRlibRlibStd.Rule("rustc").Args["libFlags"],
+			)
+		}
+	}
+}
+
 // Test that variants pull in the right type of rustlib autodep
 func TestAutoDeps(t *testing.T) {
 
diff --git a/rust/rust.go b/rust/rust.go
index fc8db86..689ff38 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -66,7 +66,6 @@
 	AndroidMkRlibs         []string `blueprint:"mutated"`
 	AndroidMkDylibs        []string `blueprint:"mutated"`
 	AndroidMkProcMacroLibs []string `blueprint:"mutated"`
-	AndroidMkSharedLibs    []string `blueprint:"mutated"`
 	AndroidMkStaticLibs    []string `blueprint:"mutated"`
 
 	ImageVariationPrefix string `blueprint:"mutated"`
@@ -168,6 +167,8 @@
 
 	// For apex variants, this is set as apex.min_sdk_version
 	apexSdkVersion android.ApiLevel
+
+	transitiveAndroidMkSharedLibs *android.DepSet[string]
 }
 
 func (mod *Module) Header() bool {
@@ -1218,6 +1219,9 @@
 		})
 	}
 
+	var transitiveAndroidMkSharedLibs []*android.DepSet[string]
+	var directAndroidMkSharedLibs []string
+
 	ctx.VisitDirectDeps(func(dep android.Module) {
 		depName := ctx.OtherModuleName(dep)
 		depTag := ctx.OtherModuleDependencyTag(dep)
@@ -1261,6 +1265,8 @@
 				mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
 			}
 
+			transitiveAndroidMkSharedLibs = append(transitiveAndroidMkSharedLibs, rustDep.transitiveAndroidMkSharedLibs)
+
 			if android.IsSourceDepTagWithOutputTag(depTag, "") {
 				// Since these deps are added in path_properties.go via AddDependencies, we need to ensure the correct
 				// OS/Arch variant is used.
@@ -1388,7 +1394,7 @@
 				// Record baseLibName for snapshots.
 				mod.Properties.SnapshotSharedLibs = append(mod.Properties.SnapshotSharedLibs, cc.BaseLibName(depName))
 
-				mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, makeLibName)
+				directAndroidMkSharedLibs = append(directAndroidMkSharedLibs, makeLibName)
 				exportDep = true
 			case cc.IsHeaderDepTag(depTag):
 				exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo)
@@ -1425,6 +1431,8 @@
 		}
 	})
 
+	mod.transitiveAndroidMkSharedLibs = android.NewDepSet[string](android.PREORDER, directAndroidMkSharedLibs, transitiveAndroidMkSharedLibs)
+
 	var rlibDepFiles RustLibraries
 	for _, dep := range directRlibDeps {
 		rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 704bfe7..835114c 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -267,7 +267,7 @@
 		t.Errorf("Proc_macro dependency not detected (dependency missing from AndroidMkProcMacroLibs)")
 	}
 
-	if !android.InList("libshared", module.Properties.AndroidMkSharedLibs) {
+	if !android.InList("libshared", module.transitiveAndroidMkSharedLibs.ToList()) {
 		t.Errorf("Shared library dependency not detected (dependency missing from AndroidMkSharedLibs)")
 	}
 
diff --git a/rust/vendor_snapshot_test.go b/rust/vendor_snapshot_test.go
index 387d170..1e7e7d3 100644
--- a/rust/vendor_snapshot_test.go
+++ b/rust/vendor_snapshot_test.go
@@ -1063,7 +1063,7 @@
 		}
 	}
 
-	libclientAndroidMkSharedLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkSharedLibs
+	libclientAndroidMkSharedLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).transitiveAndroidMkSharedLibs.ToList()
 	if g, w := libclientAndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor", "lib64", "liblog.vendor", "libc.vendor", "libm.vendor", "libdl.vendor"}; !reflect.DeepEqual(g, w) {
 		t.Errorf("wanted libclient AndroidMkSharedLibs %q, got %q", w, g)
 	}
@@ -1078,7 +1078,7 @@
 		t.Errorf("wanted libclient libclientAndroidMkDylibs %q, got %q", w, libclientAndroidMkDylibs)
 	}
 
-	libclient32AndroidMkSharedLibs := ctx.ModuleForTests("libclient", shared32Variant).Module().(*Module).Properties.AndroidMkSharedLibs
+	libclient32AndroidMkSharedLibs := ctx.ModuleForTests("libclient", shared32Variant).Module().(*Module).transitiveAndroidMkSharedLibs.ToList()
 	if g, w := libclient32AndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor", "lib32", "liblog.vendor", "libc.vendor", "libm.vendor", "libdl.vendor"}; !reflect.DeepEqual(g, w) {
 		t.Errorf("wanted libclient32 AndroidMkSharedLibs %q, got %q", w, g)
 	}
diff --git a/tests/lib.sh b/tests/lib.sh
index f3db76f..0766d85 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -154,8 +154,11 @@
   symlink_directory external/bazelbuild-rules_go
   symlink_directory external/bazelbuild-rules_license
   symlink_directory external/bazelbuild-kotlin-rules
+  symlink_directory external/bazelbuild-rules_cc
   symlink_directory external/bazelbuild-rules_python
   symlink_directory external/bazelbuild-rules_java
+  symlink_directory external/bazelbuild-rules_rust
+  symlink_directory external/rust/crates/tinyjson
 
   symlink_file WORKSPACE
   symlink_file BUILD
diff --git a/tradefed/autogen_bazel.go b/tradefed/autogen_bazel.go
index d3109d9..9575f7a 100644
--- a/tradefed/autogen_bazel.go
+++ b/tradefed/autogen_bazel.go
@@ -99,7 +99,7 @@
 	}
 
 	// check for default AndroidTest.xml
-	defaultTestConfigPath := ctx.ModuleDir() + "/AndroidTest.xml"
+	defaultTestConfigPath := "AndroidTest.xml"
 	c, _ := android.BazelStringOrLabelFromProp(ctx, &defaultTestConfigPath)
 	return c.Value
 }
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index b3e871f..eba823a 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -87,7 +87,6 @@
 // run during the build. For more documentation, see path_interposer.go .
 var Configuration = map[string]PathConfig{
 	"bash":           Allowed,
-	"dd":             Allowed,
 	"diff":           Allowed,
 	"dlv":            Allowed,
 	"expr":           Allowed,
diff --git a/ui/build/soong.go b/ui/build/soong.go
index a4cf7fb..b8543d9 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -161,6 +161,14 @@
 	debugPort    string
 }
 
+func getGlobPathName(config Config) string {
+	globPathName, ok := config.TargetProductOrErr()
+	if ok != nil {
+		globPathName = soongBuildTag
+	}
+	return globPathName
+}
+
 func (pb PrimaryBuilderFactory) primaryBuilderInvocation() bootstrap.PrimaryBuilderInvocation {
 	commonArgs := make([]string, 0, 0)
 
@@ -195,9 +203,14 @@
 
 	var allArgs []string
 	allArgs = append(allArgs, pb.specificArgs...)
+	globPathName := pb.name
+	// Glob path for soong build would be separated per product target
+	if pb.name == soongBuildTag {
+		globPathName = getGlobPathName(pb.config)
+	}
 	allArgs = append(allArgs,
-		"--globListDir", pb.name,
-		"--globFile", pb.config.NamedGlobFile(pb.name))
+		"--globListDir", globPathName,
+		"--globFile", pb.config.NamedGlobFile(globPathName))
 
 	allArgs = append(allArgs, commonArgs...)
 	allArgs = append(allArgs, environmentArgs(pb.config, pb.name)...)
@@ -247,7 +260,7 @@
 
 func bootstrapGlobFileList(config Config) []string {
 	return []string{
-		config.NamedGlobFile(soongBuildTag),
+		config.NamedGlobFile(getGlobPathName(config)),
 		config.NamedGlobFile(bp2buildFilesTag),
 		config.NamedGlobFile(jsonModuleGraphTag),
 		config.NamedGlobFile(queryviewTag),