Merge "rust: Add version scripts and symbol exports" into main
diff --git a/Android.bp b/Android.bp
index 434ee9f..d78379a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -179,6 +179,7 @@
     visibility: [
         "//build/make/target/product/generic",
         "//build/make/target/product/gsi",
+        "//build/soong/fsgen",
         "//packages/modules/Virtualization/build/microdroid",
         "//frameworks/base/ravenwood",
     ],
@@ -190,7 +191,10 @@
     system_ext_specific: true,
     product_config: ":product_config",
     relative_install_path: "etc", // system_ext/etc/build.prop
-    visibility: ["//build/make/target/product/gsi"],
+    visibility: [
+        "//build/make/target/product/gsi",
+        "//build/soong/fsgen",
+    ],
 }
 
 build_prop {
@@ -199,7 +203,10 @@
     product_specific: true,
     product_config: ":product_config",
     relative_install_path: "etc", // product/etc/build.prop
-    visibility: ["//build/make/target/product/gsi"],
+    visibility: [
+        "//build/make/target/product/gsi",
+        "//build/soong/fsgen",
+    ],
 }
 
 build_prop {
@@ -208,7 +215,7 @@
     device_specific: true,
     product_config: ":product_config",
     relative_install_path: "etc", // odm/etc/build.prop
-    visibility: ["//visibility:private"],
+    visibility: ["//build/soong/fsgen"],
 }
 
 build_prop {
diff --git a/android/Android.bp b/android/Android.bp
index 20cd28b..79969a8 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -95,6 +95,7 @@
         "proto.go",
         "provider.go",
         "raw_files.go",
+        "recovery_build_prop.go",
         "register.go",
         "rule_builder.go",
         "sandbox.go",
diff --git a/android/config.go b/android/config.go
index b811c55..d78bbf7 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1320,6 +1320,10 @@
 	return c.IsEnvTrue("RUN_ERROR_PRONE")
 }
 
+func (c *config) RunErrorProneInline() bool {
+	return c.IsEnvTrue("RUN_ERROR_PRONE_INLINE")
+}
+
 // XrefCorpusName returns the Kythe cross-reference corpus name.
 func (c *config) XrefCorpusName() string {
 	return c.Getenv("XREF_CORPUS")
diff --git a/android/container.go b/android/container.go
index 27b17ed..99e6a30 100644
--- a/android/container.go
+++ b/android/container.go
@@ -197,7 +197,10 @@
 
 func determineUnstableModule(mctx ModuleContext) bool {
 	module := mctx.Module()
-	unstableModule := module.Name() == "framework-minus-apex"
+
+	// TODO(b/383559945) Remove "framework-minus-apex_jarjar-sharded" once
+	// we remove this module.
+	unstableModule := module.Name() == "framework-minus-apex" || module.Name() == "framework-minus-apex_jarjar-sharded"
 	if installable, ok := module.(InstallableModule); ok {
 		for _, staticDepTag := range installable.StaticDependencyTags() {
 			mctx.VisitDirectDepsWithTag(staticDepTag, func(dep Module) {
diff --git a/android/container_violations.go b/android/container_violations.go
index cfee562..d7c82b4 100644
--- a/android/container_violations.go
+++ b/android/container_violations.go
@@ -15,6 +15,10 @@
 package android
 
 var ContainerDependencyViolationAllowlist = map[string][]string{
+	"adservices-service-core": {
+		"gson", // apex [com.android.adservices, com.android.extservices] -> apex [com.android.virt]
+	},
+
 	"android.car-module.impl": {
 		"modules-utils-preconditions", // apex [com.android.car.framework] -> apex [com.android.adservices, com.android.appsearch, com.android.cellbroadcast, com.android.extservices, com.android.ondevicepersonalization, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.cellbroadcast, test_com.android.wifi]
 	},
@@ -46,6 +50,11 @@
 		"modules-utils-shell-command-handler", // apex [com.android.car.framework] -> apex [com.android.adservices, com.android.art, com.android.art.debug, com.android.art.testing, com.android.btservices, com.android.configinfrastructure, com.android.mediaprovider, com.android.nfcservices, com.android.permission, com.android.scheduling, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.mediaprovider, test_com.android.permission, test_com.android.wifi, test_imgdiag_com.android.art, test_jitzygote_com.android.art]
 	},
 
+	"cellbroadcastreceiver_aconfig_flags_lib": {
+		"ext",       // apex [com.android.cellbroadcast, test_com.android.cellbroadcast] -> system
+		"framework", // apex [com.android.cellbroadcast, test_com.android.cellbroadcast] -> system
+	},
+
 	"connectivity-net-module-utils-bpf": {
 		"net-utils-device-common-struct-base", // apex [com.android.tethering] -> system
 	},
@@ -161,6 +170,10 @@
 		"framework", // cts -> unstable
 	},
 
+	"CtsAppFunctionTestCases": {
+		"framework", // cts -> unstable
+	},
+
 	"CtsAppOpsTestCases": {
 		"framework", // cts -> unstable
 	},
@@ -701,6 +714,10 @@
 		"framework", // cts -> unstable
 	},
 
+	"CtsTvInputTestCases": {
+		"framework", // cts -> unstable
+	},
+
 	"CtsTvTunerTestCases": {
 		"framework", // cts -> unstable
 	},
@@ -822,6 +839,10 @@
 		"app-compat-annotations", // apex [com.android.btservices] -> system
 	},
 
+	"framework-configinfrastructure.impl": {
+		"configinfra_framework_flags_java_lib", // apex [com.android.configinfrastructure] -> system
+	},
+
 	"framework-connectivity-t.impl": {
 		"app-compat-annotations",            // apex [com.android.tethering] -> system
 		"framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system
@@ -839,6 +860,7 @@
 	},
 
 	"framework-ondevicepersonalization.impl": {
+		"app-compat-annotations",            // apex [com.android.ondevicepersonalization] -> system
 		"ondevicepersonalization_flags_lib", // apex [com.android.ondevicepersonalization] -> system
 	},
 
diff --git a/android/logtags.go b/android/logtags.go
index 1e92dad..abc37f9 100644
--- a/android/logtags.go
+++ b/android/logtags.go
@@ -14,10 +14,56 @@
 
 package android
 
-import "github.com/google/blueprint"
+import (
+	"strings"
+
+	"github.com/google/blueprint"
+)
+
+func init() {
+	RegisterParallelSingletonType("logtags", LogtagsSingleton)
+}
 
 type LogtagsInfo struct {
 	Logtags Paths
 }
 
 var LogtagsProviderKey = blueprint.NewProvider[*LogtagsInfo]()
+
+func LogtagsSingleton() Singleton {
+	return &logtagsSingleton{}
+}
+
+type logtagsSingleton struct{}
+
+func MergedLogtagsPath(ctx PathContext) OutputPath {
+	return PathForIntermediates(ctx, "all-event-log-tags.txt")
+}
+
+func (l *logtagsSingleton) GenerateBuildActions(ctx SingletonContext) {
+	var allLogtags Paths
+	ctx.VisitAllModules(func(module Module) {
+		if !module.ExportedToMake() {
+			return
+		}
+		if logtagsInfo, ok := OtherModuleProvider(ctx, module, LogtagsProviderKey); ok {
+			allLogtags = append(allLogtags, logtagsInfo.Logtags...)
+		}
+	})
+	allLogtags = SortedUniquePaths(allLogtags)
+	filteredLogTags := make([]Path, 0, len(allLogtags))
+	for _, p := range allLogtags {
+		// Logic copied from make:
+		// https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=987;drc=0585bb1bcf4c89065adaf709f48acc8b869fd3ce
+		if !strings.HasPrefix(p.String(), "vendor/") && !strings.HasPrefix(p.String(), "device/") && !strings.HasPrefix(p.String(), "out/") {
+			filteredLogTags = append(filteredLogTags, p)
+		}
+	}
+
+	builder := NewRuleBuilder(pctx, ctx)
+	builder.Command().
+		BuiltTool("merge-event-log-tags").
+		FlagWithOutput("-o ", MergedLogtagsPath(ctx)).
+		Inputs(filteredLogTags)
+	builder.Build("all-event-log-tags.txt", "merge logtags")
+}
diff --git a/android/module_context.go b/android/module_context.go
index ae7b54f..b097117 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -623,8 +623,10 @@
 
 	if m.requiresFullInstall() {
 		deps = append(deps, InstallPaths(m.TransitiveInstallFiles.ToList())...)
-		deps = append(deps, m.installedInitRcPaths...)
-		deps = append(deps, m.installedVintfFragmentsPaths...)
+		if m.config.KatiEnabled() {
+			deps = append(deps, m.installedInitRcPaths...)
+			deps = append(deps, m.installedVintfFragmentsPaths...)
+		}
 
 		var implicitDeps, orderOnlyDeps Paths
 
diff --git a/android/recovery_build_prop.go b/android/recovery_build_prop.go
new file mode 100644
index 0000000..91d1904
--- /dev/null
+++ b/android/recovery_build_prop.go
@@ -0,0 +1,111 @@
+// Copyright 2024 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import "github.com/google/blueprint/proptools"
+
+func init() {
+	RegisterModuleType("recovery_build_prop", RecoveryBuildPropModuleFactory)
+}
+
+type recoveryBuildPropProperties struct {
+	// Path to the system build.prop file
+	System_build_prop *string `android:"path"`
+
+	// Path to the vendor build.prop file
+	Vendor_build_prop *string `android:"path"`
+
+	// Path to the odm build.prop file
+	Odm_build_prop *string `android:"path"`
+
+	// Path to the product build.prop file
+	Product_build_prop *string `android:"path"`
+
+	// Path to the system_ext build.prop file
+	System_ext_build_prop *string `android:"path"`
+}
+
+type recoveryBuildPropModule struct {
+	ModuleBase
+	properties recoveryBuildPropProperties
+
+	outputFilePath ModuleOutPath
+
+	installPath InstallPath
+}
+
+func RecoveryBuildPropModuleFactory() Module {
+	module := &recoveryBuildPropModule{}
+	module.AddProperties(&module.properties)
+	InitAndroidArchModule(module, DeviceSupported, MultilibCommon)
+	return module
+}
+
+// Overrides ctx.Module().InstallInRoot().
+// recovery_build_prop module always installs in root so that the prop.default
+// file is installed in recovery/root instead of recovery/root/system
+func (r *recoveryBuildPropModule) InstallInRoot() bool {
+	return true
+}
+
+func (r *recoveryBuildPropModule) appendRecoveryUIProperties(ctx ModuleContext, rule *RuleBuilder) {
+	rule.Command().Text("echo '#' >>").Output(r.outputFilePath)
+	rule.Command().Text("echo '# RECOVERY UI BUILD PROPERTIES' >>").Output(r.outputFilePath)
+	rule.Command().Text("echo '#' >>").Output(r.outputFilePath)
+
+	for propName, val := range ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.PrivateRecoveryUiProperties {
+		if len(val) > 0 {
+			rule.Command().
+				Textf("echo ro.recovery.ui.%s=%s >>", propName, val).
+				Output(r.outputFilePath)
+		}
+	}
+}
+
+func (r *recoveryBuildPropModule) getBuildProps(ctx ModuleContext) Paths {
+	var buildProps Paths
+	for _, buildProp := range []*string{
+		r.properties.System_build_prop,
+		r.properties.Vendor_build_prop,
+		r.properties.Odm_build_prop,
+		r.properties.Product_build_prop,
+		r.properties.System_ext_build_prop,
+	} {
+		if buildPropPath := PathForModuleSrc(ctx, proptools.String(buildProp)); buildPropPath != nil {
+			buildProps = append(buildProps, buildPropPath)
+		}
+	}
+	return buildProps
+}
+
+func (r *recoveryBuildPropModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+	if !r.InstallInRecovery() {
+		ctx.ModuleErrorf("recovery_build_prop module must set `recovery` property to true")
+	}
+	r.outputFilePath = PathForModuleOut(ctx, ctx.ModuleName(), "prop.default")
+
+	// Replicates the logic in https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=2733;drc=0585bb1bcf4c89065adaf709f48acc8b869fd3ce
+	rule := NewRuleBuilder(pctx, ctx)
+	rule.Command().Text("rm").FlagWithOutput("-f ", r.outputFilePath)
+	rule.Command().Text("cat").
+		Inputs(r.getBuildProps(ctx)).
+		Text(">>").
+		Output(r.outputFilePath)
+	r.appendRecoveryUIProperties(ctx, rule)
+
+	rule.Build(ctx.ModuleName(), "generating recovery prop.default")
+	r.installPath = PathForModuleInstall(ctx)
+	ctx.InstallFile(r.installPath, "prop.default", r.outputFilePath)
+}
diff --git a/android/variable.go b/android/variable.go
index 19f63e3..3cf66ea 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -617,7 +617,11 @@
 	ProductUseDynamicPartitionSize bool   `json:",omitempty"`
 	CopyImagesForTargetFilesZip    bool   `json:",omitempty"`
 
-	VendorSecurityPatch string `json:",omitempty"`
+	VendorSecurityPatch     string `json:",omitempty"`
+	OdmSecurityPatch        string `json:",omitempty"`
+	SystemDlkmSecurityPatch string `json:",omitempty"`
+	VendorDlkmSecurityPatch string `json:",omitempty"`
+	OdmDlkmSecurityPatch    string `json:",omitempty"`
 
 	// Boot image stuff
 	BuildingRamdiskImage            bool     `json:",omitempty"`
@@ -688,6 +692,8 @@
 	ProductFsverityGenerateMetadata bool `json:",omitempty"`
 
 	TargetScreenDensity string `json:",omitempty"`
+
+	PrivateRecoveryUiProperties map[string]string `json:",omitempty"`
 }
 
 func boolPtr(v bool) *bool {
diff --git a/apex/apex.go b/apex/apex.go
index fb0d730..b0d2b54 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -147,9 +147,6 @@
 	// Default: true.
 	Installable *bool
 
-	// Deprecated. Do not use. TODO(b/350644693) remove this after removing all usage
-	Use_vndk_as_stable *bool
-
 	// The type of filesystem to use. Either 'ext4', 'f2fs' or 'erofs'. Default 'ext4'.
 	Payload_fs_type *string
 
@@ -157,10 +154,6 @@
 	// Default is false.
 	Ignore_system_library_special_case *bool
 
-	// Whenever apex_payload.img of the APEX should include dm-verity hashtree.
-	// Default value is true.
-	Generate_hashtree *bool
-
 	// Whenever apex_payload.img of the APEX should not be dm-verity signed. Should be only
 	// used in tests.
 	Test_only_unsigned_payload *bool
@@ -1326,11 +1319,6 @@
 	return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
 }
 
-// See the generate_hashtree property
-func (a *apexBundle) shouldGenerateHashtree() bool {
-	return proptools.BoolDefault(a.properties.Generate_hashtree, true)
-}
-
 // See the test_only_unsigned_payload property
 func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
 	return proptools.Bool(a.properties.Test_only_unsigned_payload)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index ced3c46..81a62d9 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -7431,7 +7431,6 @@
 	module := ctx.ModuleForTests("myapex", "android_common_myapex")
 	args := module.Rule("apexRule").Args
 	ensureContains(t, args["opt_flags"], "--manifest_json "+module.Output("apex_manifest.json").Output.String())
-	ensureNotContains(t, args["opt_flags"], "--no_hashtree")
 
 	// The copies of the libraries in the apex should have one more dependency than
 	// the ones outside the apex, namely the unwinder. Ideally we should check
diff --git a/apex/builder.go b/apex/builder.go
index 45608c9..4c91dd0 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -544,7 +544,7 @@
 
 	imageDir := android.PathForModuleOut(ctx, "image"+suffix)
 
-	installSymbolFiles := (!ctx.Config().KatiEnabled() || a.ExportedToMake()) && a.installable()
+	installSymbolFiles := (ctx.Config().KatiEnabled() && a.ExportedToMake()) && a.installable()
 
 	// set of dependency module:location mappings
 	installMapSet := make(map[string]bool)
@@ -764,18 +764,6 @@
 	implicitInputs = append(implicitInputs, noticeAssetPath)
 	optFlags = append(optFlags, "--assets_dir "+filepath.Dir(noticeAssetPath.String()))
 
-	// Apexes which are supposed to be installed in builtin dirs(/system, etc)
-	// don't need hashtree for activation. Therefore, by removing hashtree from
-	// apex bundle (filesystem image in it, to be specific), we can save storage.
-	needHashTree := moduleMinSdkVersion.LessThanOrEqualTo(android.SdkVersion_Android10) ||
-		a.shouldGenerateHashtree()
-	if ctx.Config().ApexCompressionEnabled() && a.isCompressable() {
-		needHashTree = true
-	}
-	if !needHashTree {
-		optFlags = append(optFlags, "--no_hashtree")
-	}
-
 	if a.testOnlyShouldSkipPayloadSign() {
 		optFlags = append(optFlags, "--unsigned_payload")
 	}
diff --git a/cc/cc.go b/cc/cc.go
index 04b66d4..284ab8b 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -731,9 +731,6 @@
 	Kind  libraryDependencyKind
 	Order libraryDependencyOrder
 
-	// fromStatic is true when the parent module is a static library or binary
-	fromStatic bool
-
 	wholeStatic bool
 
 	reexportFlags       bool
@@ -2555,7 +2552,7 @@
 	}
 
 	for _, lib := range deps.HeaderLibs {
-		depTag := libraryDependencyTag{Kind: headerLibraryDependency, fromStatic: c.static()}
+		depTag := libraryDependencyTag{Kind: headerLibraryDependency}
 		if inList(lib, deps.ReexportHeaderLibHeaders) {
 			depTag.reexportFlags = true
 		}
@@ -2597,7 +2594,7 @@
 	}
 
 	for _, lib := range deps.WholeStaticLibs {
-		depTag := libraryDependencyTag{Kind: staticLibraryDependency, wholeStatic: true, reexportFlags: true, fromStatic: c.static()}
+		depTag := libraryDependencyTag{Kind: staticLibraryDependency, wholeStatic: true, reexportFlags: true}
 
 		actx.AddVariationDependencies([]blueprint.Variation{
 			{Mutator: "link", Variation: "static"},
@@ -2606,7 +2603,7 @@
 
 	for _, lib := range deps.StaticLibs {
 		// Some dependencies listed in static_libs might actually be rust_ffi rlib variants.
-		depTag := libraryDependencyTag{Kind: staticLibraryDependency, fromStatic: c.static()}
+		depTag := libraryDependencyTag{Kind: staticLibraryDependency}
 
 		if inList(lib, deps.ReexportStaticLibHeaders) {
 			depTag.reexportFlags = true
@@ -2623,7 +2620,7 @@
 	// so that native libraries/binaries are linked with static unwinder
 	// because Q libc doesn't have unwinder APIs
 	if deps.StaticUnwinderIfLegacy {
-		depTag := libraryDependencyTag{Kind: staticLibraryDependency, staticUnwinder: true, fromStatic: c.static()}
+		depTag := libraryDependencyTag{Kind: staticLibraryDependency, staticUnwinder: true}
 		actx.AddVariationDependencies([]blueprint.Variation{
 			{Mutator: "link", Variation: "static"},
 		}, depTag, staticUnwinder(actx))
@@ -2633,7 +2630,7 @@
 	var sharedLibNames []string
 
 	for _, lib := range deps.SharedLibs {
-		depTag := libraryDependencyTag{Kind: sharedLibraryDependency, fromStatic: c.static()}
+		depTag := libraryDependencyTag{Kind: sharedLibraryDependency}
 		if inList(lib, deps.ReexportSharedLibHeaders) {
 			depTag.reexportFlags = true
 		}
@@ -2654,14 +2651,14 @@
 	}
 
 	for _, lib := range deps.LateStaticLibs {
-		depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency, fromStatic: c.static()}
+		depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency}
 		actx.AddVariationDependencies([]blueprint.Variation{
 			{Mutator: "link", Variation: "static"},
 		}, depTag, lib)
 	}
 
 	for _, lib := range deps.UnexportedStaticLibs {
-		depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency, unexportedSymbols: true, fromStatic: c.static()}
+		depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency, unexportedSymbols: true}
 		actx.AddVariationDependencies([]blueprint.Variation{
 			{Mutator: "link", Variation: "static"},
 		}, depTag, lib)
@@ -2674,7 +2671,7 @@
 			// linking against both the stubs lib and the non-stubs lib at the same time.
 			continue
 		}
-		depTag := libraryDependencyTag{Kind: sharedLibraryDependency, Order: lateLibraryDependency, fromStatic: c.static()}
+		depTag := libraryDependencyTag{Kind: sharedLibraryDependency, Order: lateLibraryDependency}
 		variations := []blueprint.Variation{
 			{Mutator: "link", Variation: "shared"},
 		}
@@ -2722,7 +2719,7 @@
 
 	version := ctx.sdkVersion()
 
-	ndkStubDepTag := libraryDependencyTag{Kind: sharedLibraryDependency, ndk: true, makeSuffix: "." + version, fromStatic: c.static()}
+	ndkStubDepTag := libraryDependencyTag{Kind: sharedLibraryDependency, ndk: true, makeSuffix: "." + version}
 	actx.AddVariationDependencies([]blueprint.Variation{
 		{Mutator: "version", Variation: version},
 		{Mutator: "link", Variation: "shared"},
@@ -2732,7 +2729,7 @@
 		{Mutator: "link", Variation: "shared"},
 	}, ndkStubDepTag, apiNdkLibs...)
 
-	ndkLateStubDepTag := libraryDependencyTag{Kind: sharedLibraryDependency, Order: lateLibraryDependency, ndk: true, makeSuffix: "." + version, fromStatic: c.static()}
+	ndkLateStubDepTag := libraryDependencyTag{Kind: sharedLibraryDependency, Order: lateLibraryDependency, ndk: true, makeSuffix: "." + version}
 	actx.AddVariationDependencies([]blueprint.Variation{
 		{Mutator: "version", Variation: version},
 		{Mutator: "link", Variation: "shared"},
@@ -3772,12 +3769,23 @@
 		// APEX.
 		return false
 	}
+
+	libDepTag, isLibDepTag := depTag.(libraryDependencyTag)
+	if isLibDepTag && c.static() && libDepTag.shared() {
+		// shared_lib dependency from a static lib is considered as crossing
+		// the APEX boundary because the dependency doesn't actually is
+		// linked; the dependency is used only during the compilation phase.
+		return false
+	}
+
+	if isLibDepTag && libDepTag.excludeInApex {
+		return false
+	}
+
 	return true
 }
 
 func (c *Module) IncomingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
-	libDepTag, isLibDepTag := depTag.(libraryDependencyTag)
-
 	if c.HasStubsVariants() {
 		if IsSharedDepTag(depTag) {
 			// dynamic dep to a stubs lib crosses APEX boundary
@@ -3794,16 +3802,6 @@
 	if c.IsLlndk() {
 		return false
 	}
-	if isLibDepTag && libDepTag.fromStatic && libDepTag.shared() {
-		// shared_lib dependency from a static lib is considered as crossing
-		// the APEX boundary because the dependency doesn't actually is
-		// linked; the dependency is used only during the compilation phase.
-		return false
-	}
-
-	if isLibDepTag && libDepTag.excludeInApex {
-		return false
-	}
 
 	return true
 }
diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go
index a4d43b9..1f6cf23 100644
--- a/cc/config/x86_windows_host.go
+++ b/cc/config/x86_windows_host.go
@@ -106,6 +106,8 @@
 	}
 
 	windowsAvailableLibraries = addPrefix([]string{
+		"bcrypt",
+		"dbghelp",
 		"gdi32",
 		"imagehlp",
 		"iphlpapi",
diff --git a/cc/library.go b/cc/library.go
index ebc65ef..a3a2f5c 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -34,6 +34,8 @@
 
 // LibraryProperties is a collection of properties shared by cc library rules/cc.
 type LibraryProperties struct {
+	// local file name to pass to the linker as -exported_symbols_list
+	Exported_symbols_list *string `android:"path,arch_variant"`
 	// local file name to pass to the linker as -unexported_symbols_list
 	Unexported_symbols_list *string `android:"path,arch_variant"`
 	// local file name to pass to the linker as -force_symbols_not_weak_list
@@ -1049,10 +1051,14 @@
 	linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
 	linkerDeps = append(linkerDeps, ndkSharedLibDeps(ctx)...)
 
+	exportedSymbols := ctx.ExpandOptionalSource(library.Properties.Exported_symbols_list, "exported_symbols_list")
 	unexportedSymbols := ctx.ExpandOptionalSource(library.Properties.Unexported_symbols_list, "unexported_symbols_list")
 	forceNotWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_not_weak_list, "force_symbols_not_weak_list")
 	forceWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_weak_list, "force_symbols_weak_list")
 	if !ctx.Darwin() {
+		if exportedSymbols.Valid() {
+			ctx.PropertyErrorf("exported_symbols_list", "Only supported on Darwin")
+		}
 		if unexportedSymbols.Valid() {
 			ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
 		}
@@ -1063,6 +1069,10 @@
 			ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
 		}
 	} else {
+		if exportedSymbols.Valid() {
+			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-exported_symbols_list,"+exportedSymbols.String())
+			linkerDeps = append(linkerDeps, exportedSymbols.Path())
+		}
 		if unexportedSymbols.Valid() {
 			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
 			linkerDeps = append(linkerDeps, unexportedSymbols.Path())
diff --git a/cc/linkable.go b/cc/linkable.go
index 1fade71..1a9a9ab 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -294,8 +294,8 @@
 }
 
 // SharedDepTag returns the dependency tag for any C++ shared libraries.
-func SharedDepTag(fromStatic bool) blueprint.DependencyTag {
-	return libraryDependencyTag{Kind: sharedLibraryDependency, fromStatic: fromStatic}
+func SharedDepTag() blueprint.DependencyTag {
+	return libraryDependencyTag{Kind: sharedLibraryDependency}
 }
 
 // StaticDepTag returns the dependency tag for any C++ static libraries.
diff --git a/cmd/release_config/release_config/main.go b/cmd/release_config/release_config/main.go
index d06b2b7..7013d6b 100644
--- a/cmd/release_config/release_config/main.go
+++ b/cmd/release_config/release_config/main.go
@@ -95,7 +95,7 @@
 	if allMake {
 		// Write one makefile per release config, using the canonical release name.
 		for _, c := range configs.GetSortedReleaseConfigs() {
-			if c.Name != targetRelease {
+			if c.Name != targetRelease && !c.DisallowLunchUse {
 				makefilePath = filepath.Join(outputDir, fmt.Sprintf("release_config-%s-%s.varmk", product, c.Name))
 				err = config.WriteMakefile(makefilePath, c.Name, configs)
 				if err != nil {
diff --git a/cmd/release_config/release_config_lib/release_config.go b/cmd/release_config/release_config_lib/release_config.go
index 719ddc0..873f2fc 100644
--- a/cmd/release_config/release_config_lib/release_config.go
+++ b/cmd/release_config/release_config_lib/release_config.go
@@ -67,6 +67,9 @@
 	// overrides. Build flag value overrides are an error.
 	AconfigFlagsOnly bool
 
+	// True if this release config is not allowed as TARGET_RELEASE.
+	DisallowLunchUse bool
+
 	// Unmarshalled flag artifacts
 	FlagArtifacts FlagArtifacts
 
@@ -93,6 +96,11 @@
 
 // If true, this is a proper release config that can be used in "lunch".
 func (config *ReleaseConfig) isConfigListable() bool {
+	// Do not list disallowed release configs.
+	if config.DisallowLunchUse {
+		return false
+	}
+	// Logic based on ReleaseConfigType.
 	switch config.ReleaseConfigType {
 	case rc_proto.ReleaseConfigType_RELEASE_CONFIG:
 		return true
@@ -405,6 +413,7 @@
 		ValueDirectories:  valueDirectories,
 		PriorStages:       SortedMapKeys(config.PriorStagesMap),
 		ReleaseConfigType: config.ReleaseConfigType.Enum(),
+		DisallowLunchUse:  proto.Bool(config.DisallowLunchUse),
 	}
 
 	config.compileInProgress = false
@@ -481,6 +490,9 @@
 	}
 	// As it stands this list is not per-product, but conceptually it is, and will be.
 	data += fmt.Sprintf("ALL_RELEASE_CONFIGS_FOR_PRODUCT :=$= %s\n", strings.Join(configs.GetAllReleaseNames(), " "))
+	if config.DisallowLunchUse {
+		data += fmt.Sprintf("_disallow_lunch_use :=$= true\n")
+	}
 	data += fmt.Sprintf("_used_files := %s\n", strings.Join(config.GetSortedFileList(), " "))
 	data += fmt.Sprintf("_ALL_RELEASE_FLAGS :=$= %s\n", strings.Join(names, " "))
 	for _, pName := range pNames {
diff --git a/cmd/release_config/release_config_lib/release_configs.go b/cmd/release_config/release_config_lib/release_configs.go
index 4f621c7..b0f8cb7 100644
--- a/cmd/release_config/release_config_lib/release_configs.go
+++ b/cmd/release_config/release_config_lib/release_configs.go
@@ -378,6 +378,7 @@
 			return fmt.Errorf("%s mismatching ReleaseConfigType value %s", path, *releaseConfigType)
 		}
 		config.FilesUsedMap[path] = true
+		config.DisallowLunchUse = config.DisallowLunchUse || releaseConfigContribution.proto.GetDisallowLunchUse()
 		inheritNames := make(map[string]bool)
 		for _, inh := range config.InheritNames {
 			inheritNames[inh] = true
diff --git a/filesystem/aconfig_files.go b/filesystem/aconfig_files.go
index c80ae03..492ec69 100644
--- a/filesystem/aconfig_files.go
+++ b/filesystem/aconfig_files.go
@@ -17,26 +17,55 @@
 import (
 	"android/soong/android"
 
+	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 )
 
-func (f *filesystem) buildAconfigFlagsFiles(ctx android.ModuleContext, builder *android.RuleBuilder, specs map[string]android.PackagingSpec, dir android.OutputPath) {
-	if !proptools.Bool(f.properties.Gen_aconfig_flags_pb) {
-		return
-	}
+type installedAconfigFlagsInfo struct {
+	aconfigFiles android.Paths
+}
 
+var installedAconfigFlagsProvider = blueprint.NewProvider[installedAconfigFlagsInfo]()
+
+type importAconfigDepDag struct {
+	blueprint.BaseDependencyTag
+}
+
+var importAconfigDependencyTag = interPartitionDepTag{}
+
+func (f *filesystem) buildAconfigFlagsFiles(ctx android.ModuleContext, builder *android.RuleBuilder, specs map[string]android.PackagingSpec, dir android.OutputPath) {
 	var caches []android.Path
 	for _, ps := range specs {
 		caches = append(caches, ps.GetAconfigPaths()...)
 	}
+
+	ctx.VisitDirectDepsWithTag(importAconfigDependencyTag, func(m android.Module) {
+		info, ok := android.OtherModuleProvider(ctx, m, installedAconfigFlagsProvider)
+		if !ok {
+			ctx.ModuleErrorf("expected dependency %s to have an installedAconfigFlagsProvider", m.Name())
+			return
+		}
+		caches = append(caches, info.aconfigFiles...)
+	})
 	caches = android.SortedUniquePaths(caches)
 
+	android.SetProvider(ctx, installedAconfigFlagsProvider, installedAconfigFlagsInfo{
+		aconfigFiles: caches,
+	})
+
+	if !proptools.Bool(f.properties.Gen_aconfig_flags_pb) {
+		return
+	}
+
+	container := f.PartitionType()
+
 	installAconfigFlagsPath := dir.Join(ctx, "etc", "aconfig_flags.pb")
 	cmd := builder.Command().
 		BuiltTool("aconfig").
 		Text(" dump-cache --dedup --format protobuf --out").
 		Output(installAconfigFlagsPath).
-		Textf("--filter container:%s", f.PartitionType())
+		Textf("--filter container:%s+state:ENABLED", container).
+		Textf("--filter container:%s+permission:READ_WRITE", container)
 	for _, cache := range caches {
 		cmd.FlagWithInput("--cache ", cache)
 	}
@@ -49,7 +78,7 @@
 		outputPath := installAconfigStorageDir.Join(ctx, fileName)
 		builder.Command().
 			BuiltTool("aconfig").
-			FlagWithArg("create-storage --container ", f.PartitionType()).
+			FlagWithArg("create-storage --container ", container).
 			FlagWithArg("--file ", fileType).
 			FlagWithOutput("--out ", outputPath).
 			FlagWithArg("--cache ", installAconfigFlagsPath.String())
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index 0ffec26..36b1a18 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -391,15 +391,6 @@
 	return output
 }
 
-// Calculates avb_salt from some input for deterministic output.
-func (b *bootimg) salt() string {
-	var input []string
-	input = append(input, b.properties.Cmdline...)
-	input = append(input, proptools.StringDefault(b.properties.Partition_name, b.Name()))
-	input = append(input, proptools.String(b.properties.Header_version))
-	return sha1sum(input)
-}
-
 func (b *bootimg) buildPropFile(ctx android.ModuleContext) (android.Path, android.Paths) {
 	var sb strings.Builder
 	var deps android.Paths
@@ -420,7 +411,6 @@
 	addStr("avb_add_hash_footer_args", "") // TODO(jiyong): add --rollback_index
 	partitionName := proptools.StringDefault(b.properties.Partition_name, b.Name())
 	addStr("partition_name", partitionName)
-	addStr("avb_salt", b.salt())
 
 	propFile := android.PathForModuleOut(ctx, "prop")
 	android.WriteFileRule(ctx, propFile, sb.String())
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 1d32b8f..4799d0d 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -121,6 +121,9 @@
 	// avbtool. Default used by avbtool is sha1.
 	Avb_hash_algorithm *string
 
+	// The security patch passed to as the com.android.build.<type>.security_patch avb property.
+	Security_patch *string
+
 	// Whether or not to use forward-error-correction codes when signing with AVB. Defaults to true.
 	Use_fec *bool
 
@@ -178,6 +181,11 @@
 	// Install aconfig_flags.pb file for the modules installed in this partition.
 	Gen_aconfig_flags_pb *bool
 
+	// List of names of other filesystem partitions to import their aconfig flags from.
+	// This is used for the system partition to import system_ext's aconfig flags, as currently
+	// those are considered one "container": aosp/3261300
+	Import_aconfig_flags_from []string
+
 	Fsverity fsverityProperties
 
 	// If this property is set to true, the filesystem will call ctx.UncheckedModule(), causing
@@ -306,6 +314,9 @@
 	if f.properties.Android_filesystem_deps.System_ext != nil {
 		ctx.AddDependency(ctx.Module(), interPartitionDependencyTag, proptools.String(f.properties.Android_filesystem_deps.System_ext))
 	}
+	for _, partition := range f.properties.Import_aconfig_flags_from {
+		ctx.AddDependency(ctx.Module(), importAconfigDependencyTag, partition)
+	}
 }
 
 type fsType int
@@ -465,7 +476,7 @@
 }
 
 func (f *filesystem) appendToEntry(ctx android.ModuleContext, installedFile android.Path) {
-	partitionBaseDir := android.PathForModuleOut(ctx, "root", proptools.String(f.properties.Base_dir)).String() + "/"
+	partitionBaseDir := android.PathForModuleOut(ctx, f.rootDirString(), proptools.String(f.properties.Base_dir)).String() + "/"
 
 	relPath, inTargetPartition := strings.CutPrefix(installedFile.String(), partitionBaseDir)
 	if inTargetPartition {
@@ -555,8 +566,12 @@
 	builder.Command().Textf("cp -prf %s/* %s", rebasedDir, installPath)
 }
 
+func (f *filesystem) rootDirString() string {
+	return f.partitionName()
+}
+
 func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) android.Path {
-	rootDir := android.PathForModuleOut(ctx, "root").OutputPath
+	rootDir := android.PathForModuleOut(ctx, f.rootDirString()).OutputPath
 	rebasedDir := rootDir
 	if f.properties.Base_dir != nil {
 		rebasedDir = rootDir.Join(ctx, *f.properties.Base_dir)
@@ -599,6 +614,7 @@
 		Input(propFile).
 		Implicits(toolDeps).
 		Implicit(fec).
+		FlagWithArg("--build_datetime_file ", ctx.Config().Getenv("BUILD_DATETIME_FILE")).
 		Output(output).
 		Text(rootDir.String()) // directory where to find fs_config_files|dirs
 
@@ -618,11 +634,6 @@
 	return fcBin
 }
 
-// Calculates avb_salt from entry list (sorted) for deterministic output.
-func (f *filesystem) salt() string {
-	return sha1sum(f.entries)
-}
-
 func (f *filesystem) buildPropFile(ctx android.ModuleContext) (android.Path, android.Paths) {
 	var deps android.Paths
 	var propFileString strings.Builder
@@ -686,9 +697,10 @@
 		}
 		avb_add_hashtree_footer_args += fmt.Sprintf(" --prop com.android.build.%s.os_version:%s", f.partitionName(), ctx.Config().PlatformVersionLastStable())
 		avb_add_hashtree_footer_args += fmt.Sprintf(" --prop com.android.build.%s.fingerprint:{CONTENTS_OF:%s}", f.partitionName(), ctx.Config().BuildFingerprintFile(ctx))
-		avb_add_hashtree_footer_args += fmt.Sprintf(" --prop com.android.build.%s.security_patch:%s", f.partitionName(), ctx.Config().PlatformSecurityPatch())
+		if f.properties.Security_patch != nil && proptools.String(f.properties.Security_patch) != "" {
+			avb_add_hashtree_footer_args += fmt.Sprintf(" --prop com.android.build.%s.security_patch:%s", f.partitionName(), proptools.String(f.properties.Security_patch))
+		}
 		addStr("avb_add_hashtree_footer_args", avb_add_hashtree_footer_args)
-		addStr("avb_salt", f.salt())
 	}
 
 	if f.properties.File_contexts != nil && f.properties.Precompiled_file_contexts != nil {
@@ -783,7 +795,7 @@
 		ctx.PropertyErrorf("include_make_built_files", "include_make_built_files is not supported for compressed cpio image.")
 	}
 
-	rootDir := android.PathForModuleOut(ctx, "root").OutputPath
+	rootDir := android.PathForModuleOut(ctx, f.rootDirString()).OutputPath
 	rebasedDir := rootDir
 	if f.properties.Base_dir != nil {
 		rebasedDir = rootDir.Join(ctx, *f.properties.Base_dir)
@@ -868,29 +880,10 @@
 		return
 	}
 
-	logtagsFilePaths := make(map[string]bool)
-	ctx.WalkDeps(func(child, parent android.Module) bool {
-		if logtagsInfo, ok := android.OtherModuleProvider(ctx, child, android.LogtagsProviderKey); ok {
-			for _, path := range logtagsInfo.Logtags {
-				logtagsFilePaths[path.String()] = true
-			}
-		}
-		return true
-	})
-
-	if len(logtagsFilePaths) == 0 {
-		return
-	}
-
 	etcPath := rebasedDir.Join(ctx, "etc")
 	eventLogtagsPath := etcPath.Join(ctx, "event-log-tags")
 	builder.Command().Text("mkdir").Flag("-p").Text(etcPath.String())
-	cmd := builder.Command().BuiltTool("merge-event-log-tags").
-		FlagWithArg("-o ", eventLogtagsPath.String())
-
-	for _, path := range android.SortedKeys(logtagsFilePaths) {
-		cmd.Text(path)
-	}
+	builder.Command().Text("cp").Input(android.MergedLogtagsPath(ctx)).Text(eventLogtagsPath.String())
 
 	f.appendToEntry(ctx, eventLogtagsPath)
 }
@@ -901,8 +894,10 @@
 	}
 
 	provideModules, _ := f.getLibsForLinkerConfig(ctx)
+	intermediateOutput := android.PathForModuleOut(ctx, "linker.config.pb")
+	linkerconfig.BuildLinkerConfig(ctx, android.PathsForModuleSrc(ctx, f.properties.Linker_config.Linker_config_srcs), provideModules, nil, intermediateOutput)
 	output := rebasedDir.Join(ctx, "etc", "linker.config.pb")
-	linkerconfig.BuildLinkerConfig(ctx, builder, android.PathsForModuleSrc(ctx, f.properties.Linker_config.Linker_config_srcs), provideModules, nil, output)
+	builder.Command().Text("cp").Input(intermediateOutput).Output(output)
 
 	f.appendToEntry(ctx, output)
 }
@@ -1092,6 +1087,12 @@
 	}
 	thisPartition := f.PartitionType()
 	if thisPartition != "vendor" && thisPartition != "product" {
+		if f.properties.Android_filesystem_deps.System != nil {
+			ctx.PropertyErrorf("android_filesystem_deps.system", "only vendor or product partitions can use android_filesystem_deps")
+		}
+		if f.properties.Android_filesystem_deps.System_ext != nil {
+			ctx.PropertyErrorf("android_filesystem_deps.system_ext", "only vendor or product partitions can use android_filesystem_deps")
+		}
 		return
 	}
 	ctx.WalkDeps(func(child, parent android.Module) bool {
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index 0ed3870..33cddf8 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -16,7 +16,6 @@
 
 import (
 	"os"
-	"strings"
 	"testing"
 
 	"android/soong/android"
@@ -181,11 +180,9 @@
 	`)
 
 	module := result.ModuleForTests("myfilesystem", "android_common")
-	output := module.Output("out/soong/.intermediates/myfilesystem/android_common/root/system/etc/linker.config.pb")
+	output := module.Output("out/soong/.intermediates/myfilesystem/android_common/linker.config.pb")
 
-	fullCommand := output.RuleParams.Command
-	startIndex := strings.Index(fullCommand, "conv_linker_config")
-	linkerConfigCommand := fullCommand[startIndex:]
+	linkerConfigCommand := output.RuleParams.Command
 
 	android.AssertStringDoesContain(t, "linker.config.pb should have libfoo",
 		linkerConfigCommand, "libfoo.so")
@@ -735,7 +732,7 @@
 }
 	`)
 
-	linkerConfigCmd := result.ModuleForTests("myfilesystem", "android_common").Rule("build_filesystem_image").RuleParams.Command
+	linkerConfigCmd := result.ModuleForTests("myfilesystem", "android_common").Output("out/soong/.intermediates/myfilesystem/android_common/linker.config.pb").RuleParams.Command
 	android.AssertStringDoesContain(t, "Could not find linker.config.json file in cmd", linkerConfigCmd, "conv_linker_config proto --force -s linker.config.json")
 	android.AssertStringDoesContain(t, "Could not find stub in `provideLibs`", linkerConfigCmd, "--key provideLibs --value libfoo_has_stubs.so")
 }
diff --git a/filesystem/fsverity_metadata.go b/filesystem/fsverity_metadata.go
index 6372c5e..91b8c57 100644
--- a/filesystem/fsverity_metadata.go
+++ b/filesystem/fsverity_metadata.go
@@ -85,6 +85,18 @@
 		f.appendToEntry(ctx, destPath)
 	}
 
+	fsVerityBaseDir := rootDir.String()
+	if f.PartitionType() == "system_ext" {
+		// Use the equivalent of $PRODUCT_OUT as the base dir.
+		// This ensures that the paths in build_manifest.pb contain on-device paths
+		// e.g. system_ext/framework/javalib.jar
+		// and not framework/javalib.jar.
+		//
+		// Although base-dir is outside the rootdir provided for packaging, this action
+		// is hermetic since it uses `manifestGeneratorListPath` to filter the files to be written to build_manifest.pb
+		fsVerityBaseDir = filepath.Dir(rootDir.String())
+	}
+
 	// STEP 2: generate signed BuildManifest.apk
 	// STEP 2-1: generate build_manifest.pb
 	manifestGeneratorListPath := android.PathForModuleOut(ctx, "fsverity_manifest.list")
@@ -96,7 +108,7 @@
 	builder.Command().
 		BuiltTool("fsverity_manifest_generator").
 		FlagWithInput("--fsverity-path ", fsverityPath).
-		FlagWithArg("--base-dir ", rootDir.String()).
+		FlagWithArg("--base-dir ", fsVerityBaseDir).
 		FlagWithArg("--output ", manifestPbPath.String()).
 		FlagWithInput("@", manifestGeneratorListPath)
 
diff --git a/filesystem/system_image.go b/filesystem/system_image.go
index 60a5133..57ce10f 100644
--- a/filesystem/system_image.go
+++ b/filesystem/system_image.go
@@ -49,8 +49,10 @@
 	}
 
 	provideModules, requireModules := s.getLibsForLinkerConfig(ctx)
+	intermediateOutput := android.PathForModuleOut(ctx, "linker.config.pb")
+	linkerconfig.BuildLinkerConfig(ctx, android.PathsForModuleSrc(ctx, s.filesystem.properties.Linker_config.Linker_config_srcs), provideModules, requireModules, intermediateOutput)
 	output := rebasedDir.Join(ctx, "etc", "linker.config.pb")
-	linkerconfig.BuildLinkerConfig(ctx, builder, android.PathsForModuleSrc(ctx, s.filesystem.properties.Linker_config.Linker_config_srcs), provideModules, requireModules, output)
+	builder.Command().Text("cp").Input(intermediateOutput).Output(output)
 
 	s.appendToEntry(ctx, output)
 }
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index b9fddca..4e1ca9e 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -266,6 +266,11 @@
 		)
 		fsProps.Base_dir = proptools.StringPtr("system")
 		fsProps.Dirs = proptools.NewSimpleConfigurable(commonPartitionDirs)
+		fsProps.Security_patch = proptools.StringPtr(ctx.Config().PlatformSecurityPatch())
+
+		if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
+			fsProps.Import_aconfig_flags_from = []string{generatedModuleNameForPartition(ctx.Config(), "system_ext")}
+		}
 	case "system_ext":
 		if partitionVars.ProductFsverityGenerateMetadata {
 			fsProps.Fsverity.Inputs = []string{
@@ -275,12 +280,14 @@
 			}
 			fsProps.Fsverity.Libs = []string{":framework-res{.export-package.apk}"}
 		}
+		fsProps.Security_patch = proptools.StringPtr(ctx.Config().PlatformSecurityPatch())
 	case "product":
 		fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
 		fsProps.Android_filesystem_deps.System = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system"))
 		if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
 			fsProps.Android_filesystem_deps.System_ext = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
 		}
+		fsProps.Security_patch = proptools.StringPtr(ctx.Config().PlatformSecurityPatch())
 	case "vendor":
 		fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
 		fsProps.Symlinks = []filesystem.SymlinkDefinition{
@@ -297,6 +304,7 @@
 		if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
 			fsProps.Android_filesystem_deps.System_ext = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
 		}
+		fsProps.Security_patch = proptools.StringPtr(partitionVars.VendorSecurityPatch)
 	case "odm":
 		fsProps.Symlinks = []filesystem.SymlinkDefinition{
 			filesystem.SymlinkDefinition{
@@ -304,6 +312,7 @@
 				Name:   proptools.StringPtr("lib/modules"),
 			},
 		}
+		fsProps.Security_patch = proptools.StringPtr(partitionVars.OdmSecurityPatch)
 	case "userdata":
 		fsProps.Base_dir = proptools.StringPtr("data")
 	case "ramdisk":
@@ -358,6 +367,12 @@
 			Target: proptools.StringPtr("prop.default"),
 			Name:   proptools.StringPtr("default.prop"),
 		}), "root")
+	case "system_dlkm":
+		fsProps.Security_patch = proptools.StringPtr(partitionVars.SystemDlkmSecurityPatch)
+	case "vendor_dlkm":
+		fsProps.Security_patch = proptools.StringPtr(partitionVars.VendorDlkmSecurityPatch)
+	case "odm_dlkm":
+		fsProps.Security_patch = proptools.StringPtr(partitionVars.OdmDlkmSecurityPatch)
 	}
 }
 
@@ -562,9 +577,11 @@
 		Name                  *string
 		Board_info_files      []string
 		Bootloader_board_name *string
+		Stem                  *string
 	}{
-		Name:             proptools.StringPtr(generatedModuleName(ctx.Config(), "android-info.prop")),
+		Name:             proptools.StringPtr(generatedModuleName(ctx.Config(), "android_info.prop")),
 		Board_info_files: partitionVars.BoardInfoFiles,
+		Stem:             proptools.StringPtr("android_info.txt"),
 	}
 	if len(androidInfoProps.Board_info_files) == 0 {
 		androidInfoProps.Bootloader_board_name = proptools.StringPtr(partitionVars.BootLoaderBoardName)
@@ -596,6 +613,43 @@
 	vendorBuildProp.HideFromMake()
 }
 
+func createRecoveryBuildProp(ctx android.LoadHookContext) string {
+	moduleName := generatedModuleName(ctx.Config(), "recovery-prop.default")
+
+	var vendorBuildProp *string
+	if android.InList("vendor", generatedPartitions(ctx)) {
+		vendorBuildProp = proptools.StringPtr(":" + generatedModuleName(ctx.Config(), "vendor-build.prop"))
+	}
+
+	recoveryBuildProps := &struct {
+		Name                  *string
+		System_build_prop     *string
+		Vendor_build_prop     *string
+		Odm_build_prop        *string
+		Product_build_prop    *string
+		System_ext_build_prop *string
+
+		Recovery        *bool
+		No_full_install *bool
+		Visibility      []string
+	}{
+		Name:                  proptools.StringPtr(moduleName),
+		System_build_prop:     proptools.StringPtr(":system-build.prop"),
+		Vendor_build_prop:     vendorBuildProp,
+		Odm_build_prop:        proptools.StringPtr(":odm-build.prop"),
+		Product_build_prop:    proptools.StringPtr(":product-build.prop"),
+		System_ext_build_prop: proptools.StringPtr(":system_ext-build.prop"),
+
+		Recovery:        proptools.BoolPtr(true),
+		No_full_install: proptools.BoolPtr(true),
+		Visibility:      []string{"//visibility:public"},
+	}
+
+	ctx.CreateModule(android.RecoveryBuildPropModuleFactory, recoveryBuildProps)
+
+	return moduleName
+}
+
 // createLinkerConfigSourceFilegroups creates filegroup modules to generate linker.config.pb for the following partitions
 // 1. vendor: Using PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS (space separated file list)
 // 1. product: Using PRODUCT_PRODUCT_LINKER_CONFIG_FRAGMENTS (space separated file list)
@@ -709,6 +763,8 @@
 	}
 
 	fsProps.Is_auto_generated = proptools.BoolPtr(true)
+	// TODO(b/381120092): Verify mount_point for system partition
+	fsProps.Mount_point = proptools.StringPtr(partitionType)
 
 	partitionSpecificFsProps(ctx, fsProps, partitionVars, partitionType)
 
diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go
index 20e4c3e..de0a1cb 100644
--- a/fsgen/fsgen_mutators.go
+++ b/fsgen/fsgen_mutators.go
@@ -165,6 +165,7 @@
 		// Add common resources `prebuilt_res` module as dep of recovery partition
 		(*fsGenState.fsDeps["recovery"])[fmt.Sprintf("recovery-resources-common-%s", getDpi(ctx))] = defaultDepCandidateProps(ctx.Config())
 		(*fsGenState.fsDeps["recovery"])[getRecoveryFontModuleName(ctx)] = defaultDepCandidateProps(ctx.Config())
+		(*fsGenState.fsDeps["recovery"])[createRecoveryBuildProp(ctx)] = defaultDepCandidateProps(ctx.Config())
 
 		return &fsGenState
 	}).(*FsGenState)
diff --git a/java/base.go b/java/base.go
index 215285f..18a875b 100644
--- a/java/base.go
+++ b/java/base.go
@@ -109,6 +109,10 @@
 	// if not blank, used as prefix to generate repackage rule
 	Jarjar_prefix *string
 
+	// Number of shards for jarjar. It needs to be an integer represented as a string.
+	// TODO(b/383559945) change it to int, once Configurable supports the type.
+	Jarjar_shards proptools.Configurable[string]
+
 	// If not blank, set the java version passed to javac as -source and -target
 	Java_version *string
 
@@ -1273,7 +1277,7 @@
 		localHeaderJars, combinedHeaderJarFile := j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName,
 			extraCombinedJars)
 
-		combinedHeaderJarFile, jarjared := j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
+		combinedHeaderJarFile, jarjared := j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine", false)
 		if jarjared {
 			localHeaderJars = android.Paths{combinedHeaderJarFile}
 			transitiveStaticLibsHeaderJars = nil
@@ -1409,7 +1413,7 @@
 		shardingHeaderJars = localHeaderJars
 
 		var jarjared bool
-		j.headerJarFile, jarjared = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
+		j.headerJarFile, jarjared = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine", false)
 		if jarjared {
 			// jarjar modifies transitive static dependencies, use the combined header jar and drop the transitive
 			// static libs header jars.
@@ -1442,20 +1446,27 @@
 			// build.
 			flags = enableErrorproneFlags(flags)
 		} else if hasErrorproneableFiles && ctx.Config().RunErrorProne() && j.properties.Errorprone.Enabled == nil {
-			// Otherwise, if the RUN_ERROR_PRONE environment variable is set, create
-			// a new jar file just for compiling with the errorprone compiler to.
-			// This is because we don't want to cause the java files to get completely
-			// rebuilt every time the state of the RUN_ERROR_PRONE variable changes.
-			// We also don't want to run this if errorprone is enabled by default for
-			// this module, or else we could have duplicated errorprone messages.
-			errorproneFlags := enableErrorproneFlags(flags)
-			errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
-			errorproneAnnoSrcJar := android.PathForModuleOut(ctx, "errorprone", "anno.srcjar")
+			if ctx.Config().RunErrorProneInline() {
+				// On CI, we're not going to toggle back/forth between errorprone and non-errorprone
+				// builds, so it's faster if we don't compile the module twice and instead always
+				// compile the module with errorprone.
+				flags = enableErrorproneFlags(flags)
+			} else {
+				// Otherwise, if the RUN_ERROR_PRONE environment variable is set, create
+				// a new jar file just for compiling with the errorprone compiler to.
+				// This is because we don't want to cause the java files to get completely
+				// rebuilt every time the state of the RUN_ERROR_PRONE variable changes.
+				// We also don't want to run this if errorprone is enabled by default for
+				// this module, or else we could have duplicated errorprone messages.
+				errorproneFlags := enableErrorproneFlags(flags)
+				errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
+				errorproneAnnoSrcJar := android.PathForModuleOut(ctx, "errorprone", "anno.srcjar")
 
-			transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneAnnoSrcJar, errorproneFlags, nil,
-				"errorprone", "errorprone")
+				transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneAnnoSrcJar, errorproneFlags, nil,
+					"errorprone", "errorprone")
 
-			extraJarDeps = append(extraJarDeps, errorprone)
+				extraJarDeps = append(extraJarDeps, errorprone)
+			}
 		}
 
 		if enableSharding {
@@ -1636,7 +1647,7 @@
 	}
 
 	// jarjar implementation jar if necessary
-	jarjarFile, jarjarred := j.jarjarIfNecessary(ctx, outputFile, jarName, "")
+	jarjarFile, jarjarred := j.jarjarIfNecessary(ctx, outputFile, jarName, "", true)
 	if jarjarred {
 		localImplementationJars = android.Paths{jarjarFile}
 		completeStaticLibsImplementationJars = depset.New(depset.PREORDER, localImplementationJars, nil)
@@ -1645,7 +1656,7 @@
 
 	// jarjar resource jar if necessary
 	if combinedResourceJar != nil {
-		resourceJarJarFile, jarjarred := j.jarjarIfNecessary(ctx, combinedResourceJar, jarName, "resource")
+		resourceJarJarFile, jarjarred := j.jarjarIfNecessary(ctx, combinedResourceJar, jarName, "resource", false)
 		combinedResourceJar = resourceJarJarFile
 		if jarjarred {
 			localResourceJars = android.Paths{resourceJarJarFile}
@@ -2934,12 +2945,23 @@
 	return repackagedJarjarFile, true
 }
 
-func (j *Module) jarjarIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string) (android.Path, bool) {
+func (j *Module) jarjarIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string, useShards bool) (android.Path, bool) {
 	if j.expandJarjarRules == nil {
 		return infile, false
 	}
 	jarjarFile := android.PathForModuleOut(ctx, "jarjar", info, jarName)
-	TransformJarJar(ctx, jarjarFile, infile, j.expandJarjarRules)
+
+	totalShards := 1
+	if useShards {
+		totalShardsStr := j.properties.Jarjar_shards.GetOrDefault(ctx, "1")
+		ts, err := strconv.Atoi(totalShardsStr)
+		if err != nil {
+			ctx.PropertyErrorf("jarjar_shards", "jarjar_shards must be an integer represented as a string")
+			return infile, false
+		}
+		totalShards = ts
+	}
+	TransformJarJarWithShards(ctx, jarjarFile, infile, j.expandJarjarRules, totalShards)
 	return jarjarFile, true
 
 }
diff --git a/java/builder.go b/java/builder.go
index 01fbbdd..88058e0 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -168,7 +168,7 @@
 				"${config.JavaCmd}",
 			},
 			Rspfile:        "$out.rsp",
-			RspfileContent: "$in",
+			RspfileContent: "$in_newline",
 			Restat:         true,
 		},
 		&remoteexec.REParams{Labels: map[string]string{"type": "tool", "name": "turbine"},
@@ -238,12 +238,12 @@
 				// for newly repackaged classes. Dropping @UnsupportedAppUsage on repackaged classes
 				// avoids adding new hiddenapis after jarjar'ing.
 				" -DremoveAndroidCompatAnnotations=true" +
-				" -jar ${config.JarjarCmd} process $rulesFile $in $out && " +
+				" -jar ${config.JarjarCmd} process $rulesFile $in $out $total_shards $shard_index && " +
 				// Turn a missing output file into a ninja error
 				`[ -e ${out} ] || (echo "Missing output file"; exit 1)`,
 			CommandDeps: []string{"${config.JavaCmd}", "${config.JarjarCmd}", "$rulesFile"},
 		},
-		"rulesFile")
+		"rulesFile", "total_shards", "shard_index")
 
 	packageCheck = pctx.AndroidStaticRule("packageCheck",
 		blueprint.RuleParams{
@@ -459,7 +459,7 @@
 	const srcJarArgsLimit = 32 * 1024
 	if len(srcJarArgs) > srcJarArgsLimit {
 		srcJarRspFile := android.PathForModuleOut(ctx, "turbine", "srcjars.rsp")
-		android.WriteFileRule(ctx, srcJarRspFile, srcJarArgs)
+		android.WriteFileRule(ctx, srcJarRspFile, strings.Join(srcJars.Strings(), "\n"))
 		srcJarArgs = "@" + srcJarRspFile.String()
 		implicits = append(implicits, srcJarRspFile)
 		rbeInputs = append(rbeInputs, srcJarRspFile)
@@ -491,7 +491,7 @@
 	const classpathLimit = 32 * 1024
 	if len(classpathFlags) > classpathLimit {
 		classpathRspFile := android.PathForModuleOut(ctx, dir, "classpath.rsp")
-		android.WriteFileRule(ctx, classpathRspFile, classpathFlags)
+		android.WriteFileRule(ctx, classpathRspFile, strings.Join(classpath.Strings(), "\n"))
 		classpathFlags = "@" + classpathRspFile.String()
 		implicits = append(implicits, classpathRspFile)
 		rspFiles = append(rspFiles, classpathRspFile)
@@ -750,16 +750,58 @@
 
 func TransformJarJar(ctx android.ModuleContext, outputFile android.WritablePath,
 	classesJar android.Path, rulesFile android.Path) {
+	TransformJarJarWithShards(ctx, outputFile, classesJar, rulesFile, 1)
+}
+
+func TransformJarJarWithShards(ctx android.ModuleContext, outputFile android.WritablePath,
+	classesJar android.Path, rulesFile android.Path, totalShards int) {
+
+	// If the total number of shards is 1, just run jarjar as-is, with `total_shards` = 1
+	// and `shard_index` == 0, which effectively disables sharding
+	if totalShards == 1 {
+		ctx.Build(pctx, android.BuildParams{
+			Rule:        jarjar,
+			Description: "jarjar",
+			Output:      outputFile,
+			Input:       classesJar,
+			Implicit:    rulesFile,
+			Args: map[string]string{
+				"rulesFile":    rulesFile.String(),
+				"total_shards": "1",
+				"shard_index":  "0",
+			},
+		})
+		return
+	}
+
+	// Otherwise, run multiple jarjar instances and use merge_zips to combine the output.
+	tempJars := make([]android.Path, 0)
+	totalStr := strconv.Itoa(totalShards)
+	for i := 0; i < totalShards; i++ {
+		iStr := strconv.Itoa(i)
+		tempOut := android.PathForOutput(ctx, outputFile.String()+"-"+iStr+".jar")
+		ctx.Build(pctx, android.BuildParams{
+			Rule:        jarjar,
+			Description: "jarjar (" + iStr + "/" + totalStr + ")",
+			Output:      tempOut,
+			Input:       classesJar,
+			Implicit:    rulesFile,
+			Args: map[string]string{
+				"rulesFile":    rulesFile.String(),
+				"total_shards": totalStr,
+				"shard_index":  iStr,
+			},
+		})
+		tempJars = append(tempJars, tempOut)
+	}
+
 	ctx.Build(pctx, android.BuildParams{
-		Rule:        jarjar,
-		Description: "jarjar",
+		Rule:        combineJar,
+		Description: "merge jarjar shards",
 		Output:      outputFile,
-		Input:       classesJar,
-		Implicit:    rulesFile,
-		Args: map[string]string{
-			"rulesFile": rulesFile.String(),
-		},
+		Inputs:      tempJars,
 	})
+
 }
 
 func CheckJarPackages(ctx android.ModuleContext, outputFile android.WritablePath,
diff --git a/java/config/config.go b/java/config/config.go
index 7c29722..19d6952 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -42,6 +42,9 @@
 	InstrumentFrameworkModules = []string{
 		"framework",
 		"framework-minus-apex",
+		// TODO(b/383559945) Remove "framework-minus-apex_jarjar-sharded" once
+		// we remove this module.
+		"framework-minus-apex_jarjar-sharded",
 		"ims-common",
 		"telephony-common",
 		"services",
diff --git a/java/legacy_core_platform_api_usage.go b/java/legacy_core_platform_api_usage.go
index 4be7d04..6128ce3 100644
--- a/java/legacy_core_platform_api_usage.go
+++ b/java/legacy_core_platform_api_usage.go
@@ -28,6 +28,9 @@
 	"FloralClocks",
 	"framework-jobscheduler",
 	"framework-minus-apex",
+	// TODO(b/383559945) Remove "framework-minus-apex_jarjar-sharded" once
+	// we remove this module.
+	"framework-minus-apex_jarjar-sharded",
 	"framework-minus-apex-headers",
 	"framework-minus-apex-intdefs",
 	"FrameworksCoreTests",
diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go
index d422871..7684db2 100644
--- a/linkerconfig/linkerconfig.go
+++ b/linkerconfig/linkerconfig.go
@@ -76,9 +76,7 @@
 	input := android.PathForModuleSrc(ctx, android.String(l.properties.Src))
 	output := android.PathForModuleOut(ctx, "linker.config.pb").OutputPath
 
-	builder := android.NewRuleBuilder(pctx, ctx)
-	BuildLinkerConfig(ctx, builder, android.Paths{input}, nil, nil, output)
-	builder.Build("conv_linker_config", "Generate linker config protobuf "+output.String())
+	BuildLinkerConfig(ctx, android.Paths{input}, nil, nil, output)
 
 	l.outputFilePath = output
 	l.installDirPath = android.PathForModuleInstall(ctx, "etc")
@@ -90,10 +88,15 @@
 	ctx.SetOutputFiles(android.Paths{l.outputFilePath}, "")
 }
 
-func BuildLinkerConfig(ctx android.ModuleContext, builder *android.RuleBuilder,
-	inputs android.Paths, provideModules []android.Module, requireModules []android.Module, output android.OutputPath) {
-
+func BuildLinkerConfig(
+	ctx android.ModuleContext,
+	inputs android.Paths,
+	provideModules []android.Module,
+	requireModules []android.Module,
+	output android.WritablePath,
+) {
 	// First, convert the input json to protobuf format
+	builder := android.NewRuleBuilder(pctx, ctx)
 	interimOutput := android.PathForModuleOut(ctx, "temp.pb")
 	cmd := builder.Command().
 		BuiltTool("conv_linker_config").
@@ -157,6 +160,7 @@
 
 	builder.Temporary(interimOutput)
 	builder.DeleteTemporaryFiles()
+	builder.Build("conv_linker_config_"+output.String(), "Generate linker config protobuf "+output.String())
 }
 
 // linker_config generates protobuf file from json file. This protobuf file will be used from
diff --git a/rust/proc_macro.go b/rust/proc_macro.go
index 1ff6637..28ed68b 100644
--- a/rust/proc_macro.go
+++ b/rust/proc_macro.go
@@ -67,6 +67,7 @@
 func (procMacro *procMacroDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
 	flags = procMacro.baseCompiler.compilerFlags(ctx, flags)
 	flags.RustFlags = append(flags.RustFlags, "--extern proc_macro")
+	flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName())
 	return flags
 }
 
diff --git a/rust/rust.go b/rust/rust.go
index a7ad294..6fc682f 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -1684,7 +1684,7 @@
 	}
 
 	for _, lib := range deps.SharedLibs {
-		depTag := cc.SharedDepTag(mod.Static())
+		depTag := cc.SharedDepTag()
 		name, version := cc.StubsLibNameAndVersion(lib)
 
 		variations := []blueprint.Variation{
@@ -1830,6 +1830,13 @@
 		return false
 	}
 
+	if mod.Static() && cc.IsSharedDepTag(depTag) {
+		// shared_lib dependency from a static lib is considered as crossing
+		// the APEX boundary because the dependency doesn't actually is
+		// linked; the dependency is used only during the compilation phase.
+		return false
+	}
+
 	return true
 }
 
diff --git a/rust/sanitize.go b/rust/sanitize.go
index 4c82de5..b8f922f 100644
--- a/rust/sanitize.go
+++ b/rust/sanitize.go
@@ -281,7 +281,7 @@
 			} else {
 				variations = append(variations,
 					blueprint.Variation{Mutator: "link", Variation: "shared"})
-				depTag = cc.SharedDepTag(mod.Static())
+				depTag = cc.SharedDepTag()
 				deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan")}
 			}
 		} else if mod.IsSanitizerEnabled(cc.Hwasan) {
@@ -296,7 +296,7 @@
 			// library during final link if necessary
 			variations = append(variations,
 				blueprint.Variation{Mutator: "link", Variation: "shared"})
-			depTag = cc.SharedDepTag(mod.Static())
+			depTag = cc.SharedDepTag()
 			deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "hwasan")}
 		}
 
diff --git a/scripts/gen_build_prop.py b/scripts/gen_build_prop.py
index 47bbf59..430e613 100644
--- a/scripts/gen_build_prop.py
+++ b/scripts/gen_build_prop.py
@@ -108,7 +108,7 @@
 
 def generate_common_build_props(args):
   print("####################################")
-  print("# from generate_common_build_props")
+  print("# from generate-common-build-props")
   print("# These properties identify this partition image.")
   print("####################################")
 
@@ -243,9 +243,15 @@
   print(f"# end build properties")
 
 def write_properties_from_file(file):
+  # Make and Soong use different intermediate files to build vendor/build.prop.
+  # Although the sysprop contents are same, the absolute paths of these
+  # intermediate files are different.
+  # Print the filename for the intermediate files (files in OUT_DIR).
+  # This helps with validating mk->soong migration of android partitions.
+  filename = os.path.basename(file.name) if file.name.startswith(os.environ.get("OUT_DIR")) else file.name
   print()
   print("####################################")
-  print(f"# from {file.name}")
+  print(f"# from {filename}")
   print("####################################")
   print(file.read(), end="")
 
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index 84f20c5..77d5853 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -680,7 +680,7 @@
 		Sysprop_srcs: m.properties.Srcs,
 		Scope:        scope,
 		Check_api:    proptools.StringPtr(ctx.ModuleName()),
-		Installable:  proptools.BoolPtr(false),
+		Installable:  m.properties.Installable,
 		Crate_name:   m.rustCrateName(),
 		Rustlibs: []string{
 			"liblog_rust",