Merge "Allow profiling Soong from the full build"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index bf39404..2e4068d 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -166,6 +166,7 @@
 		"external/minijail":                      Bp2BuildDefaultTrueRecursively,
 		"external/objenesis":                     Bp2BuildDefaultTrueRecursively,
 		"external/openscreen":                    Bp2BuildDefaultTrueRecursively,
+		"external/ow2-asm":                       Bp2BuildDefaultTrueRecursively,
 		"external/pcre":                          Bp2BuildDefaultTrueRecursively,
 		"external/protobuf":                      Bp2BuildDefaultTrueRecursively,
 		"external/python/six":                    Bp2BuildDefaultTrueRecursively,
diff --git a/android/bazel.go b/android/bazel.go
index d30cb80..60989f6 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -341,16 +341,19 @@
 		// Exact dir match
 		return true
 	}
+	var i int
 	// Check if subtree match
-	for prefix, recursive := range a.keepExistingBuildFile {
-		if recursive {
-			if strings.HasPrefix(dir, prefix+"/") {
-				return true
-			}
+	for {
+		j := strings.Index(dir[i:], "/")
+		if j == -1 {
+			return false //default
+		}
+		prefix := dir[0 : i+j]
+		i = i + j + 1 // skip the "/"
+		if recursive, ok := a.keepExistingBuildFile[prefix]; ok && recursive {
+			return true
 		}
 	}
-	// Default
-	return false
 }
 
 var bp2BuildAllowListKey = NewOnceKey("Bp2BuildAllowlist")
diff --git a/android/filegroup.go b/android/filegroup.go
index af4d89a..d21d146 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -122,16 +122,18 @@
 		if fg.ShouldConvertToProtoLibrary(ctx) {
 			// TODO(b/246997908): we can remove this tag if we could figure out a
 			// solution for this bug.
-			tags := []string{"manual"}
 			attrs := &ProtoAttrs{
 				Srcs:                srcs,
 				Strip_import_prefix: fg.properties.Path,
-				Tags:                tags,
 			}
 
+			tags := []string{"manual"}
 			ctx.CreateBazelTargetModule(
 				bazel.BazelTargetModuleProperties{Rule_class: "proto_library"},
-				CommonAttributes{Name: fg.Name() + convertedProtoLibrarySuffix},
+				CommonAttributes{
+					Name: fg.Name() + convertedProtoLibrarySuffix,
+					Tags: bazel.MakeStringListAttribute(tags),
+				},
 				attrs)
 		}
 
diff --git a/android/proto.go b/android/proto.go
index 3cac9a1..8204f77 100644
--- a/android/proto.go
+++ b/android/proto.go
@@ -164,7 +164,6 @@
 	Srcs                bazel.LabelListAttribute
 	Strip_import_prefix *string
 	Deps                bazel.LabelListAttribute
-	Tags                []string
 }
 
 // For each package in the include_dirs property a proto_library target should
diff --git a/android/sdk.go b/android/sdk.go
index fc0a84e..bd2f5d1 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -232,6 +232,12 @@
 	// relative path) and add the dest to the zip.
 	CopyToSnapshot(src Path, dest string)
 
+	// EmptyFile returns the path to an empty file.
+	//
+	// This can be used by sdk member types that need to create an empty file in the snapshot, simply
+	// pass the value returned from this to the CopyToSnapshot() method.
+	EmptyFile() Path
+
 	// UnzipToSnapshot generates a rule that will unzip the supplied zip into the snapshot relative
 	// directory destDir.
 	UnzipToSnapshot(zipPath Path, destDir string)
@@ -258,14 +264,6 @@
 	// See sdk/update.go for more information.
 	AddPrebuiltModule(member SdkMember, moduleType string) BpModule
 
-	// AddInternalModule creates a new module in the generated Android.bp file that can only be
-	// referenced by one of the other modules in the snapshot.
-	//
-	// The created module's name is constructed by concatenating the name of this member and the
-	// nameSuffix, separated by "-". It also has the visibility property set to "//visibility:private"
-	// to prevent it from being inadvertently accessed from outside the snapshot.
-	AddInternalModule(properties SdkMemberProperties, moduleType string, nameSuffix string) BpModule
-
 	// SdkMemberReferencePropertyTag returns a property tag to use when adding a property to a
 	// BpModule that contains references to other sdk members.
 	//
@@ -924,12 +922,6 @@
 //
 // Contains common properties that apply across many different member types.
 type SdkMemberPropertiesBase struct {
-	// The name of the member.
-	//
-	// Ignore this property during optimization. This is needed because this property is the same for
-	// all variants of a member and so would be optimized away if it was not ignored.
-	MemberName string `sdk:"ignore"`
-
 	// The number of unique os types supported by the member variants.
 	//
 	// If a member has a variant with more than one os type then it will need to differentiate
@@ -953,10 +945,6 @@
 	Compile_multilib string `android:"arch_variant"`
 }
 
-func (b *SdkMemberPropertiesBase) Name() string {
-	return b.MemberName
-}
-
 // OsPrefix returns the os prefix to use for any file paths in the sdk.
 //
 // Is an empty string if the member only provides variants for a single os type, otherwise
@@ -982,8 +970,6 @@
 	// Base returns the base structure.
 	Base() *SdkMemberPropertiesBase
 
-	Name() string
-
 	// PopulateFromVariant populates this structure with information from a module variant.
 	//
 	// It will typically be called once for each variant of a member module that the SDK depends upon.
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index eefda19..609a29c 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -96,6 +96,8 @@
 	// quickly silence build errors. This flag should be used with caution and only as a temporary
 	// measure, as it masks real errors and affects performance.
 	RelaxUsesLibraryCheck bool
+
+	EnableUffdGc bool // preopt with the assumption that userfaultfd GC will be used on device.
 }
 
 var allPlatformSystemServerJarsKey = android.NewOnceKey("allPlatformSystemServerJars")
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index fdfd22e..e3404a5 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -495,6 +495,10 @@
 		cmd.FlagWithInput("--profile-file=", profile)
 	}
 
+	if global.EnableUffdGc {
+		cmd.Flag("--runtime-arg").Flag("-Xgc:CMC")
+	}
+
 	rule.Install(odexPath, odexInstallPath)
 	rule.Install(vdexPath, vdexInstallPath)
 }
diff --git a/java/Android.bp b/java/Android.bp
index 0bf7a0b..9d63319 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -91,6 +91,7 @@
         "dexpreopt_config_test.go",
         "droiddoc_test.go",
         "droidstubs_test.go",
+        "fuzz_test.go",
         "genrule_test.go",
         "hiddenapi_singleton_test.go",
         "jacoco_test.go",
diff --git a/java/app.go b/java/app.go
index e36808f..a822cbf 100755
--- a/java/app.go
+++ b/java/app.go
@@ -591,7 +591,7 @@
 		// Set a certificate to avoid panics later when accessing it.
 		mainCertificate = Certificate{
 			Key: android.PathForModuleOut(ctx, "missing.pk8"),
-			Pem: android.PathForModuleOut(ctx, "missing.pem"),
+			Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
 		}
 	}
 
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index b3faae8..3effff6 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -752,6 +752,10 @@
 		cmd.FlagWithArg("--instruction-set-features=", global.InstructionSetFeatures[arch])
 	}
 
+	if global.EnableUffdGc {
+		cmd.Flag("--runtime-arg").Flag("-Xgc:CMC")
+	}
+
 	if global.BootFlags != "" {
 		cmd.Flag(global.BootFlags)
 	}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 2173dae..8a291ad 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -304,6 +304,9 @@
 		flags = append(flags, "-I"+src.String())
 	}
 
+	minSdkVersion := j.MinSdkVersion(ctx).ApiLevel.FinalOrFutureInt()
+	flags = append(flags, fmt.Sprintf("--min_sdk_version=%v", minSdkVersion))
+
 	return strings.Join(flags, " "), deps
 }
 
diff --git a/java/fuzz_test.go b/java/fuzz_test.go
index 0a2c945..6e5d912 100644
--- a/java/fuzz_test.go
+++ b/java/fuzz_test.go
@@ -65,9 +65,8 @@
 
 	osCommonTarget := result.Config.BuildOSCommonTarget.String()
 
-	osCommonTargetWithSan := osCommonTarget + "_asan" + "_fuzzer"
-	javac := result.ModuleForTests("foo", osCommonTargetWithSan).Rule("javac")
-	combineJar := result.ModuleForTests("foo", osCommonTargetWithSan).Description("for javac")
+	javac := result.ModuleForTests("foo", osCommonTarget).Rule("javac")
+	combineJar := result.ModuleForTests("foo", osCommonTarget).Description("for javac")
 
 	if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
 		t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
@@ -85,9 +84,9 @@
 	}
 
 	ctx := result.TestContext
-	foo := ctx.ModuleForTests("foo", osCommonTargetWithSan).Module().(*JavaFuzzLibrary)
+	foo := ctx.ModuleForTests("foo", osCommonTarget).Module().(*JavaFuzzLibrary)
 
-	expected := "libjni.so"
+	expected := "lib64/libjni.so"
 	if runtime.GOOS == "darwin" {
 		expected = "libjni.dylib"
 	}
diff --git a/java/invalid_implementation_jar.sh b/java/invalid_implementation_jar.sh
deleted file mode 100755
index 3820058..0000000
--- a/java/invalid_implementation_jar.sh
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/bin/bash
-
-# Copyright 2022 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.
-
-# Script to detect and report an attempt to access an invalid implementation
-# jar.
-
-MOD=$1
-
-cat <<EOF
-
-    $MOD is a java_library that generates a jar file which must not be accessed
-    from outside the mainline module that provides it. If you are seeing this
-    message it means that you are incorrectly attempting to use the jar file
-    from a java_import prebuilt of $MOD.
-
-    This is most likely due to an incorrect dependency on $MOD in an Android.mk
-    or Android.bp file. Please remove that dependency and replace with
-    something more appropriate, e.g. a dependency on an API provided by the
-    module.
-
-    If you do not know where the extraneous dependency was added then you can
-    run the following command to find a list of all the paths from the target
-    which you are trying to build to the target which produced this error.
-
-        prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-\${TARGET_PRODUCT}.ninja -t path <target> <invalid-jar>
-
-    Where <target> is the build target you specified on the command line which
-    produces this error and <invalid-jar> is the rule that failed with this
-    message. If you are specifying multiple build targets then you will need to
-    run the above command for every target until you find the cause.
-
-    The command will output one (of the possibly many) dependency paths from
-    <target> to <invalid-jar>, one file/phony target per line. e.g. it may
-    output something like this:
-
-        ....
-        out/soong/.intermediates/acme/broken/android_common/combined/broken.jar
-        out/soong/.intermediates/prebuilts/module_sdk/art/current/sdk/prebuilt_core-libart/android_common/combined/core-libart.jar
-        out/soong/.intermediates/prebuilts/module_sdk/art/current/sdk/art-module-sdk_core-libart-error/gen/this-file-will-never-be-created.jar
-
-    The last line is the failing target, the second to last line is a dependency
-    from the core-libart java_import onto the failing target, the third to last
-    line is the source of the dependency so you should look in acme/Android.bp
-    file for the "broken" module.
-
-EOF
-
-exit 1
diff --git a/java/java.go b/java/java.go
index ad46e98..25b6349 100644
--- a/java/java.go
+++ b/java/java.go
@@ -89,11 +89,11 @@
 var (
 	// Supports adding java header libraries to module_exports and sdk.
 	javaHeaderLibsSdkMemberType = &librarySdkMemberType{
-		SdkMemberTypeBase: android.SdkMemberTypeBase{
+		android.SdkMemberTypeBase{
 			PropertyName: "java_header_libs",
 			SupportsSdk:  true,
 		},
-		jarToExportGetter: func(_ android.SdkMemberContext, j *Library) android.Path {
+		func(_ android.SdkMemberContext, j *Library) android.Path {
 			headerJars := j.HeaderJars()
 			if len(headerJars) != 1 {
 				panic(fmt.Errorf("there must be only one header jar from %q", j.Name()))
@@ -101,8 +101,8 @@
 
 			return headerJars[0]
 		},
-		snapshotPathGetter:    sdkSnapshotFilePathForJar,
-		onlyCopyJarToSnapshot: copyEverythingToSnapshot,
+		sdkSnapshotFilePathForJar,
+		copyEverythingToSnapshot,
 	}
 
 	// Export implementation classes jar as part of the sdk.
@@ -116,12 +116,12 @@
 
 	// Supports adding java implementation libraries to module_exports but not sdk.
 	javaLibsSdkMemberType = &librarySdkMemberType{
-		SdkMemberTypeBase: android.SdkMemberTypeBase{
+		android.SdkMemberTypeBase{
 			PropertyName: "java_libs",
 		},
-		jarToExportGetter:     exportImplementationClassesJar,
-		snapshotPathGetter:    sdkSnapshotFilePathForJar,
-		onlyCopyJarToSnapshot: copyEverythingToSnapshot,
+		exportImplementationClassesJar,
+		sdkSnapshotFilePathForJar,
+		copyEverythingToSnapshot,
 	}
 
 	snapshotRequiresImplementationJar = func(ctx android.SdkMemberContext) bool {
@@ -146,11 +146,11 @@
 	// necessary. The java_boot_libs property to allow those modules to be exported as part of the
 	// sdk/module_exports without exposing any unnecessary information.
 	javaBootLibsSdkMemberType = &librarySdkMemberType{
-		SdkMemberTypeBase: android.SdkMemberTypeBase{
+		android.SdkMemberTypeBase{
 			PropertyName: "java_boot_libs",
 			SupportsSdk:  true,
 		},
-		jarToExportGetter: func(ctx android.SdkMemberContext, j *Library) android.Path {
+		func(ctx android.SdkMemberContext, j *Library) android.Path {
 			if snapshotRequiresImplementationJar(ctx) {
 				return exportImplementationClassesJar(ctx, j)
 			}
@@ -159,9 +159,9 @@
 			// jar for use by dexpreopting and boot jars package check. They do not need to provide an
 			// actual implementation jar but the java_import will need a file that exists so just copy an
 			// empty file. Any attempt to use that file as a jar will cause a build error.
-			return nil
+			return ctx.SnapshotBuilder().EmptyFile()
 		},
-		snapshotPathGetter: func(ctx android.SdkMemberContext, osPrefix, name string) string {
+		func(ctx android.SdkMemberContext, osPrefix, name string) string {
 			if snapshotRequiresImplementationJar(ctx) {
 				return sdkSnapshotFilePathForJar(ctx, osPrefix, name)
 			}
@@ -171,7 +171,7 @@
 			// TODO(b/175714559): Provide a proper error message in Soong not ninja.
 			return filepath.Join(osPrefix, "java_boot_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix)
 		},
-		onlyCopyJarToSnapshot: onlyCopyJarToSnapshot,
+		onlyCopyJarToSnapshot,
 	}
 
 	// Supports adding java systemserver libraries to module_exports and sdk.
@@ -185,27 +185,27 @@
 	// necessary. The java_systemserver_libs property to allow those modules to be exported as part of
 	// the sdk/module_exports without exposing any unnecessary information.
 	javaSystemserverLibsSdkMemberType = &librarySdkMemberType{
-		SdkMemberTypeBase: android.SdkMemberTypeBase{
+		android.SdkMemberTypeBase{
 			PropertyName: "java_systemserver_libs",
 			SupportsSdk:  true,
 
 			// This was only added in Tiramisu.
 			SupportedBuildReleaseSpecification: "Tiramisu+",
 		},
-		jarToExportGetter: func(ctx android.SdkMemberContext, j *Library) android.Path {
+		func(ctx android.SdkMemberContext, j *Library) android.Path {
 			// Java systemserver libs are only provided in the SDK to provide access to their dex
 			// implementation jar for use by dexpreopting. They do not need to provide an actual
 			// implementation jar but the java_import will need a file that exists so just copy an empty
 			// file. Any attempt to use that file as a jar will cause a build error.
-			return nil
+			return ctx.SnapshotBuilder().EmptyFile()
 		},
-		snapshotPathGetter: func(_ android.SdkMemberContext, osPrefix, name string) string {
+		func(_ android.SdkMemberContext, osPrefix, name string) string {
 			// Create a special name for the implementation jar to try and provide some useful information
 			// to a developer that attempts to compile against this.
 			// TODO(b/175714559): Provide a proper error message in Soong not ninja.
 			return filepath.Join(osPrefix, "java_systemserver_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix)
 		},
-		onlyCopyJarToSnapshot: onlyCopyJarToSnapshot,
+		onlyCopyJarToSnapshot,
 	}
 
 	// Supports adding java test libraries to module_exports but not sdk.
@@ -235,7 +235,7 @@
 	ImplementationAndResourcesJars android.Paths
 
 	// ImplementationJars is a list of jars that contain the implementations of classes in the
-	// module.
+	//module.
 	ImplementationJars android.Paths
 
 	// ResourceJars is a list of jars that contain the resources included in the module.
@@ -721,8 +721,7 @@
 	android.SdkMemberTypeBase
 
 	// Function to retrieve the appropriate output jar (implementation or header) from
-	// the library, if this returns nil then it is assumed that the snapshot must not provide access
-	// to the jar.
+	// the library.
 	jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path
 
 	// Function to compute the snapshot relative path to which the named library's
@@ -759,11 +758,7 @@
 type librarySdkMemberProperties struct {
 	android.SdkMemberPropertiesBase
 
-	JarToExport android.Path `android:"arch_variant"`
-
-	// The path to a script to use when the jar is invalid.
-	InvalidJarScript android.Path
-
+	JarToExport     android.Path `android:"arch_variant"`
 	AidlIncludeDirs android.Paths
 
 	// The list of permitted packages that need to be passed to the prebuilts as they are used to
@@ -774,15 +769,7 @@
 func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
 	j := variant.(*Library)
 
-	memberType := ctx.MemberType().(*librarySdkMemberType)
-	p.JarToExport = memberType.jarToExportGetter(ctx, j)
-
-	// If no jar was provided for export then disallow access to it completely.
-	if p.JarToExport == nil {
-		// Copy the script to prevent access to the jar into the snapshot.
-		p.InvalidJarScript = android.PathForSource(ctx.SdkModuleContext(),
-			"build/soong/java/invalid_implementation_jar.sh")
-	}
+	p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j)
 
 	p.AidlIncludeDirs = j.AidlIncludeDirs()
 
@@ -805,21 +792,6 @@
 		propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
 	}
 
-	if scriptSrc := p.InvalidJarScript; scriptSrc != nil {
-		// Copy the script to prevent access to the jar into the snapshot.
-		scriptDest := filepath.Join("scripts", scriptSrc.Base())
-		builder.CopyToSnapshot(scriptSrc, scriptDest)
-
-		// Generate a genrule module that will invoke the script passing in the module name.
-		genrule := builder.AddInternalModule(p, "genrule", "error")
-		genRuleName := genrule.Name()
-		genrule.AddProperty("out", []string{"this-file-will-never-be-created.jar"})
-		genrule.AddProperty("tool_files", []string{scriptDest})
-		genrule.AddProperty("cmd", fmt.Sprintf("$(location %s) %s", scriptDest, p.Name()))
-
-		propertySet.AddPropertyWithTag("jars", []string{":" + genRuleName}, builder.SdkMemberReferencePropertyTag(true))
-	}
-
 	if len(p.PermittedPackages) > 0 {
 		propertySet.AddProperty("permitted_packages", p.PermittedPackages)
 	}
@@ -1580,8 +1552,8 @@
 	// name of the API surface
 	Api_surface *string
 
-	// list of API provider modules that consists this API surface
-	Api_providers []string
+	// list of Java API contribution modules that consists this API surface
+	Api_contributions []string
 
 	// List of flags to be passed to the javac compiler to generate jar file
 	Javacflags []string
@@ -1649,12 +1621,12 @@
 	}
 }
 
-var javaApiProviderTag = dependencyTag{name: "java-api-provider"}
+var javaApiContributionTag = dependencyTag{name: "java-api-contribution"}
 
 func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
-	apiProviders := al.properties.Api_providers
-	for _, apiProviderName := range apiProviders {
-		ctx.AddDependency(ctx.Module(), javaApiProviderTag, apiProviderName)
+	apiContributions := al.properties.Api_contributions
+	for _, apiContributionName := range apiContributions {
+		ctx.AddDependency(ctx.Module(), javaApiContributionTag, apiContributionName)
 	}
 }
 
@@ -1673,16 +1645,11 @@
 
 	homeDir := android.PathForModuleOut(ctx, "metalava", "home")
 
-	apiProviders := al.properties.Api_providers
-	srcFiles := make([]android.Path, len(apiProviders))
-	for i, apiProviderName := range apiProviders {
-		apiProvider := ctx.GetDirectDepWithTag(apiProviderName, javaApiProviderTag)
-		if apiProvider == nil {
-			panic(fmt.Errorf("Java API provider module %s not found, called from %s", apiProviderName, al.Name()))
-		}
-		provider := ctx.OtherModuleProvider(apiProvider, JavaApiImportProvider).(JavaApiImportInfo)
-		srcFiles[i] = android.PathForModuleSrc(ctx, provider.ApiFile.String())
-	}
+	var srcFiles []android.Path
+	ctx.VisitDirectDepsWithTag(javaApiContributionTag, func(dep android.Module) {
+		provider := ctx.OtherModuleProvider(dep, JavaApiImportProvider).(JavaApiImportInfo)
+		srcFiles = append(srcFiles, android.PathForModuleSrc(ctx, provider.ApiFile.String()))
+	})
 
 	cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir)
 
@@ -1857,7 +1824,7 @@
 }
 
 func (j *Import) commonBuildActions(ctx android.ModuleContext) {
-	// TODO(b/231322772) these should come from Bazel once available
+	//TODO(b/231322772) these should come from Bazel once available
 	j.sdkVersion = j.SdkVersion(ctx)
 	j.minSdkVersion = j.MinSdkVersion(ctx)
 
@@ -2460,7 +2427,7 @@
 		resources.Append(android.BazelLabelForModuleSrc(ctx, m.properties.Java_resources))
 	}
 
-	// TODO(b/179889880) handle case where glob includes files outside package
+	//TODO(b/179889880) handle case where glob includes files outside package
 	resDeps := ResourceDirsToFiles(
 		ctx,
 		m.properties.Java_resource_dirs,
@@ -2622,7 +2589,7 @@
 	}
 
 	epEnabled := m.properties.Errorprone.Enabled
-	// TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable
+	//TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable
 	if Bool(epEnabled) {
 		javacopts = append(javacopts, m.properties.Errorprone.Javacflags...)
 	}
@@ -2876,7 +2843,7 @@
 		HeaderJars:                     android.PathsIfNonNil(i.combinedClasspathFile),
 		ImplementationAndResourcesJars: android.PathsIfNonNil(i.combinedClasspathFile),
 		ImplementationJars:             android.PathsIfNonNil(i.combinedClasspathFile),
-		// TODO(b/240308299) include AIDL information from Bazel
+		//TODO(b/240308299) include AIDL information from Bazel
 	})
 
 	i.maybeInstall(ctx, jarName, outputFile)
diff --git a/java/java_test.go b/java/java_test.go
index 3f8cd8e..ff15783 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1370,6 +1370,39 @@
 	}
 }
 
+func TestAidlFlagsMinSdkVersionDroidstubs(t *testing.T) {
+	bpTemplate := `
+	droidstubs {
+		name: "foo-stubs",
+		srcs: ["foo.aidl"],
+		%s
+		system_modules: "none",
+	}
+	`
+	testCases := []struct {
+		desc                  string
+		sdkVersionBp          string
+		minSdkVersionExpected string
+	}{
+		{
+			desc:                  "sdk_version not set, module compiles against private platform APIs",
+			sdkVersionBp:          ``,
+			minSdkVersionExpected: "10000",
+		},
+		{
+			desc:                  "sdk_version set to none, module does not build against an SDK",
+			sdkVersionBp:          `sdk_version: "none",`,
+			minSdkVersionExpected: "10000",
+		},
+	}
+	for _, tc := range testCases {
+		ctx := prepareForJavaTest.RunTestWithBp(t, fmt.Sprintf(bpTemplate, tc.sdkVersionBp))
+		aidlCmd := ctx.ModuleForTests("foo-stubs", "android_common").Rule("aidl").RuleParams.Command
+		expected := "--min_sdk_version=" + tc.minSdkVersionExpected
+		android.AssertStringDoesContain(t, "aidl command conatins incorrect min_sdk_version for testCse: "+tc.desc, aidlCmd, expected)
+	}
+}
+
 func TestAidlEnforcePermissions(t *testing.T) {
 	ctx, _ := testJava(t, `
 		java_library {
@@ -1823,13 +1856,13 @@
 		java_api_library {
 			name: "bar1",
 			api_surface: "public",
-			api_providers: ["foo1"],
+			api_contributions: ["foo1"],
 		}
 
 		java_api_library {
 			name: "bar2",
 			api_surface: "system",
-			api_providers: ["foo1", "foo2"],
+			api_contributions: ["foo1", "foo2"],
 		}
 		`,
 		map[string][]byte{
@@ -1876,13 +1909,13 @@
 		java_api_library {
 			name: "bar1",
 			api_surface: "public",
-			api_providers: ["foo1"],
+			api_contributions: ["foo1"],
 		}
 
 		java_api_library {
 			name: "bar2",
 			api_surface: "system",
-			api_providers: ["foo1", "foo2"],
+			api_contributions: ["foo1", "foo2"],
 		}
 		`,
 		map[string][]byte{
diff --git a/java/legacy_core_platform_api_usage.go b/java/legacy_core_platform_api_usage.go
index 1f374b4..6cb549e 100644
--- a/java/legacy_core_platform_api_usage.go
+++ b/java/legacy_core_platform_api_usage.go
@@ -53,15 +53,6 @@
 	"SettingsGoogleOverlayCoral",
 	"SettingsGoogleOverlayFlame",
 	"SettingsLib",
-	"SettingsOverlayG020I",
-	"SettingsOverlayG020I_VN",
-	"SettingsOverlayG020J",
-	"SettingsOverlayG020M",
-	"SettingsOverlayG020N",
-	"SettingsOverlayG020P",
-	"SettingsOverlayG020Q",
-	"SettingsOverlayG025H",
-	"SettingsOverlayG5NZ6",
 	"SettingsRoboTests",
 	"SimContact",
 	"SimContacts",
diff --git a/java/lint.go b/java/lint.go
index 9827159..7a6e5d9 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -190,10 +190,8 @@
 
 	extraCheckModules := l.properties.Lint.Extra_check_modules
 
-	if checkOnly := ctx.Config().Getenv("ANDROID_LINT_CHECK"); checkOnly != "" {
-		if checkOnlyModules := ctx.Config().Getenv("ANDROID_LINT_CHECK_EXTRA_MODULES"); checkOnlyModules != "" {
-			extraCheckModules = strings.Split(checkOnlyModules, ",")
-		}
+	if extraCheckModulesEnv := ctx.Config().Getenv("ANDROID_LINT_CHECK_EXTRA_MODULES"); extraCheckModulesEnv != "" {
+		extraCheckModules = append(extraCheckModules, strings.Split(extraCheckModulesEnv, ",")...)
 	}
 
 	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(),
diff --git a/java/sdk_library.go b/java/sdk_library.go
index fad1df7..56e5550 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1648,6 +1648,7 @@
 	// shared libs and static libs. So we need to add both of these libs to Libs property.
 	props.Libs = module.properties.Libs
 	props.Libs = append(props.Libs, module.properties.Static_libs...)
+	props.Libs = append(props.Libs, module.sdkLibraryProperties.Stub_only_libs...)
 	props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
 	props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
 	props.Java_version = module.properties.Java_version
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 096bca8..210bfc3 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -1385,3 +1385,29 @@
 			}
 		`)
 }
+
+func TestJavaSdkLibrary_StubOnlyLibs_PassedToDroidstubs(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		prepareForJavaTest,
+		PrepareForTestWithJavaSdkLibraryFiles,
+		FixtureWithLastReleaseApis("foo"),
+	).RunTestWithBp(t, `
+		java_sdk_library {
+			name: "foo",
+			srcs: ["a.java"],
+			public: {
+				enabled: true,
+			},
+			stub_only_libs: ["bar-lib"],
+		}
+
+		java_library {
+			name: "bar-lib",
+			srcs: ["b.java"],
+		}
+		`)
+
+	// The foo.stubs.source should depend on bar-lib
+	fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs)
+	android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs, "bar-lib")
+}
diff --git a/rust/library.go b/rust/library.go
index c2ce9de..bc9c9aa 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -267,84 +267,94 @@
 var _ libraryInterface = (*libraryDecorator)(nil)
 var _ exportedFlagsProducer = (*libraryDecorator)(nil)
 
-// rust_library produces all rust variants.
+// rust_library produces all Rust variants (rust_library_dylib and
+// rust_library_rlib).
 func RustLibraryFactory() android.Module {
 	module, library := NewRustLibrary(android.HostAndDeviceSupported)
 	library.BuildOnlyRust()
 	return module.Init()
 }
 
-// rust_ffi produces all ffi variants.
+// rust_ffi produces all FFI variants (rust_ffi_shared and
+// rust_ffi_static).
 func RustFFIFactory() android.Module {
 	module, library := NewRustLibrary(android.HostAndDeviceSupported)
 	library.BuildOnlyFFI()
 	return module.Init()
 }
 
-// rust_library_dylib produces a dylib.
+// rust_library_dylib produces a Rust dylib (Rust crate type "dylib").
 func RustLibraryDylibFactory() android.Module {
 	module, library := NewRustLibrary(android.HostAndDeviceSupported)
 	library.BuildOnlyDylib()
 	return module.Init()
 }
 
-// rust_library_rlib produces an rlib.
+// rust_library_rlib produces an rlib (Rust crate type "rlib").
 func RustLibraryRlibFactory() android.Module {
 	module, library := NewRustLibrary(android.HostAndDeviceSupported)
 	library.BuildOnlyRlib()
 	return module.Init()
 }
 
-// rust_ffi_shared produces a shared library.
+// rust_ffi_shared produces a shared library (Rust crate type
+// "cdylib").
 func RustFFISharedFactory() android.Module {
 	module, library := NewRustLibrary(android.HostAndDeviceSupported)
 	library.BuildOnlyShared()
 	return module.Init()
 }
 
-// rust_ffi_static produces a static library.
+// rust_ffi_static produces a static library (Rust crate type
+// "staticlib").
 func RustFFIStaticFactory() android.Module {
 	module, library := NewRustLibrary(android.HostAndDeviceSupported)
 	library.BuildOnlyStatic()
 	return module.Init()
 }
 
-// rust_library_host produces all rust variants.
+// rust_library_host produces all Rust variants for the host
+// (rust_library_dylib_host and rust_library_rlib_host).
 func RustLibraryHostFactory() android.Module {
 	module, library := NewRustLibrary(android.HostSupported)
 	library.BuildOnlyRust()
 	return module.Init()
 }
 
-// rust_ffi_host produces all FFI variants.
+// rust_ffi_host produces all FFI variants for the host
+// (rust_ffi_static_host and rust_ffi_shared_host).
 func RustFFIHostFactory() android.Module {
 	module, library := NewRustLibrary(android.HostSupported)
 	library.BuildOnlyFFI()
 	return module.Init()
 }
 
-// rust_library_dylib_host produces a dylib.
+// rust_library_dylib_host produces a dylib for the host (Rust crate
+// type "dylib").
 func RustLibraryDylibHostFactory() android.Module {
 	module, library := NewRustLibrary(android.HostSupported)
 	library.BuildOnlyDylib()
 	return module.Init()
 }
 
-// rust_library_rlib_host produces an rlib.
+// rust_library_rlib_host produces an rlib for the host (Rust crate
+// type "rlib").
 func RustLibraryRlibHostFactory() android.Module {
 	module, library := NewRustLibrary(android.HostSupported)
 	library.BuildOnlyRlib()
 	return module.Init()
 }
 
-// rust_ffi_static_host produces a static library.
+// rust_ffi_static_host produces a static library for the host (Rust
+// crate type "staticlib").
 func RustFFIStaticHostFactory() android.Module {
 	module, library := NewRustLibrary(android.HostSupported)
 	library.BuildOnlyStatic()
 	return module.Init()
 }
 
-// rust_ffi_shared_host produces an shared library.
+// rust_ffi_shared_host produces an shared library for the host (Rust
+// crate type "cdylib").
 func RustFFISharedHostFactory() android.Module {
 	module, library := NewRustLibrary(android.HostSupported)
 	library.BuildOnlyShared()
diff --git a/rust/library_test.go b/rust/library_test.go
index 4633cc7..e3e4d0f 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -30,11 +30,11 @@
 			srcs: ["foo.rs"],
 			crate_name: "foo",
 		}
-                rust_ffi_host {
-                        name: "libfoo.ffi",
-                        srcs: ["foo.rs"],
-                        crate_name: "foo"
-                }`)
+		rust_ffi_host {
+			name: "libfoo.ffi",
+			srcs: ["foo.rs"],
+			crate_name: "foo"
+		}`)
 
 	// Test all variants are being built.
 	libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
@@ -45,7 +45,7 @@
 	rlibCrateType := "rlib"
 	dylibCrateType := "dylib"
 	sharedCrateType := "cdylib"
-	staticCrateType := "static"
+	staticCrateType := "staticlib"
 
 	// Test crate type for rlib is correct.
 	if !strings.Contains(libfooRlib.Args["rustcFlags"], "crate-type="+rlibCrateType) {
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index 58c1647..1b64130 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -169,15 +169,7 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["com.android.art"],
-    jars: [":mysdk_core1-error"],
-}
-
-genrule {
-    name: "mysdk_core1-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) core1",
+    jars: ["java_boot_libs/snapshot/jars/are/invalid/core1.jar"],
 }
 
 java_import {
@@ -185,15 +177,7 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["com.android.art"],
-    jars: [":mysdk_core2-error"],
-}
-
-genrule {
-    name: "mysdk_core2-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) core2",
+    jars: ["java_boot_libs/snapshot/jars/are/invalid/core2.jar"],
 }
 `),
 		checkAllCopyRules(`
@@ -203,7 +187,8 @@
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
-build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/core1.jar
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/core2.jar
 		`),
 		snapshotTestPreparer(checkSnapshotWithoutSource, preparerForSnapshot),
 
@@ -372,18 +357,10 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["myapex"],
-    jars: [":mysdk_mybootlib-error"],
+    jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"],
     permitted_packages: ["mybootlib"],
 }
 
-genrule {
-    name: "mysdk_mybootlib-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) mybootlib",
-}
-
 java_sdk_library_import {
     name: "myothersdklibrary",
     prefer: false,
@@ -490,7 +467,7 @@
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
-build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar
 .intermediates/myothersdklibrary.stubs/android_common/javac/myothersdklibrary.stubs.jar -> sdk_library/public/myothersdklibrary-stubs.jar
 .intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_api.txt -> sdk_library/public/myothersdklibrary.txt
 .intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_removed.txt -> sdk_library/public/myothersdklibrary-removed.txt
@@ -510,7 +487,7 @@
 .intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv
 .intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
 .intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
-build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar
 .intermediates/myothersdklibrary.stubs/android_common/javac/myothersdklibrary.stubs.jar -> sdk_library/public/myothersdklibrary-stubs.jar
 .intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_api.txt -> sdk_library/public/myothersdklibrary.txt
 .intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_removed.txt -> sdk_library/public/myothersdklibrary-removed.txt
@@ -899,18 +876,10 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["myapex"],
-    jars: [":mysdk_mybootlib-error"],
+    jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"],
     permitted_packages: ["mybootlib"],
 }
 
-genrule {
-    name: "mysdk_mybootlib-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) mybootlib",
-}
-
 java_sdk_library_import {
     name: "mynewlibrary",
     prefer: false,
@@ -961,7 +930,7 @@
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
-build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar
 .intermediates/mynewlibrary.stubs/android_common/javac/mynewlibrary.stubs.jar -> sdk_library/public/mynewlibrary-stubs.jar
 .intermediates/mynewlibrary.stubs.source/android_common/metalava/mynewlibrary.stubs.source_api.txt -> sdk_library/public/mynewlibrary.txt
 .intermediates/mynewlibrary.stubs.source/android_common/metalava/mynewlibrary.stubs.source_removed.txt -> sdk_library/public/mynewlibrary-removed.txt
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index c6cb6c2..51903ce3 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -19,13 +19,11 @@
 	"testing"
 
 	"android/soong/android"
-	"android/soong/genrule"
 	"android/soong/java"
 )
 
 var prepareForSdkTestWithJava = android.GroupFixturePreparers(
 	java.PrepareForTestWithJavaBuildComponents,
-	genrule.PrepareForTestWithGenRuleBuildComponents,
 	PrepareForTestWithSdkBuildComponents,
 
 	// Ensure that all source paths are provided. This helps ensure that the snapshot generation is
@@ -36,7 +34,6 @@
 	// Files needs by most of the tests.
 	android.MockFS{
 		"Test.java": nil,
-		"build/soong/java/invalid_implementation_jar.sh": nil,
 	}.AddToFixture(),
 )
 
@@ -291,26 +288,18 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
-    jars: [":mysdk_myjavalib-error"],
+    jars: ["java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar"],
     permitted_packages: ["pkg.myjavalib"],
 }
-
-genrule {
-    name: "mysdk_myjavalib-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) myjavalib",
-}
 `),
 		checkAllCopyRules(`
-build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar
 `),
 	)
 }
 
 func TestSnapshotWithJavaBootLibrary_UpdatableMedia(t *testing.T) {
-	runTest := func(t *testing.T, targetBuildRelease, expectedJarPath, expectedGenRule, expectedCopyRule string) {
+	runTest := func(t *testing.T, targetBuildRelease, expectedJarPath, expectedCopyRule string) {
 		result := android.GroupFixturePreparers(
 			prepareForSdkTestWithJava,
 			android.FixtureMergeEnv(map[string]string{
@@ -345,27 +334,20 @@
     jars: ["%s"],
     permitted_packages: ["pkg.media"],
 }
-%s`, expectedJarPath, expectedGenRule)),
+`, expectedJarPath)),
 			checkAllCopyRules(expectedCopyRule),
 		)
 	}
 
 	t.Run("updatable-media in S", func(t *testing.T) {
-		runTest(t, "S", "java/updatable-media.jar", "", `
+		runTest(t, "S", "java/updatable-media.jar", `
 .intermediates/updatable-media/android_common/package-check/updatable-media.jar -> java/updatable-media.jar
 `)
 	})
 
 	t.Run("updatable-media in T", func(t *testing.T) {
-		runTest(t, "Tiramisu", ":mysdk_updatable-media-error", `
-genrule {
-    name: "mysdk_updatable-media-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) updatable-media",
-}`, `
-build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
+		runTest(t, "Tiramisu", "java_boot_libs/snapshot/jars/are/invalid/updatable-media.jar", `
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/updatable-media.jar
 `)
 	})
 }
@@ -407,20 +389,12 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
-    jars: [":myexports_myjavalib-error"],
+    jars: ["java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar"],
     permitted_packages: ["pkg.myjavalib"],
 }
-
-genrule {
-    name: "myexports_myjavalib-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) myjavalib",
-}
 `),
 		checkAllCopyRules(`
-build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
+.intermediates/myexports/common_os/empty -> java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar
 `),
 	)
 }
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index 2f9aee9..108a664 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -409,60 +409,6 @@
 		)
 	})
 
-	t.Run("SOONG_SDK_SNAPSHOT_PREFER=true", func(t *testing.T) {
-		result := android.GroupFixturePreparers(
-			preparer,
-			android.FixtureMergeEnv(map[string]string{
-				"SOONG_SDK_SNAPSHOT_PREFER": "true",
-			}),
-		).RunTest(t)
-
-		checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip")
-
-		CheckSnapshot(t, result, "mysdk", "",
-			checkAndroidBpContents(`
-// This is auto-generated. DO NOT EDIT.
-
-java_import {
-    name: "myjavalib",
-    prefer: true,
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    jars: ["java/myjavalib.jar"],
-}
-			`),
-		)
-	})
-
-	t.Run("SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR=module:build_from_source", func(t *testing.T) {
-		result := android.GroupFixturePreparers(
-			preparer,
-			android.FixtureMergeEnv(map[string]string{
-				"SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR": "module:build_from_source",
-			}),
-		).RunTest(t)
-
-		checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip")
-
-		CheckSnapshot(t, result, "mysdk", "",
-			checkAndroidBpContents(`
-// This is auto-generated. DO NOT EDIT.
-
-java_import {
-    name: "myjavalib",
-    prefer: false,
-    use_source_config_var: {
-        config_namespace: "module",
-        var_name: "build_from_source",
-    },
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    jars: ["java/myjavalib.jar"],
-}
-			`),
-		)
-	})
-
 	t.Run("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE=S", func(t *testing.T) {
 		result := android.GroupFixturePreparers(
 			prepareForSdkTestWithJava,
diff --git a/sdk/systemserverclasspath_fragment_sdk_test.go b/sdk/systemserverclasspath_fragment_sdk_test.go
index 9540a6b..1ac405d 100644
--- a/sdk/systemserverclasspath_fragment_sdk_test.go
+++ b/sdk/systemserverclasspath_fragment_sdk_test.go
@@ -119,18 +119,10 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["myapex"],
-    jars: [":mysdk_mylib-error"],
+    jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"],
     permitted_packages: ["mylib"],
 }
 
-genrule {
-    name: "mysdk_mylib-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) mylib",
-}
-
 prebuilt_systemserverclasspath_fragment {
     name: "mysystemserverclasspathfragment",
     prefer: false,
@@ -188,18 +180,10 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["myapex"],
-    jars: [":mysdk_mylib-error"],
+    jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"],
     permitted_packages: ["mylib"],
 }
 
-genrule {
-    name: "mysdk_mylib-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) mylib",
-}
-
 prebuilt_systemserverclasspath_fragment {
     name: "mysystemserverclasspathfragment",
     prefer: false,
diff --git a/sdk/update.go b/sdk/update.go
index 6ebbf09..baa2033 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -34,41 +34,6 @@
 // Environment variables that affect the generated snapshot
 // ========================================================
 //
-// SOONG_SDK_SNAPSHOT_PREFER
-//     By default every module in the generated snapshot has prefer: false. Building it
-//     with SOONG_SDK_SNAPSHOT_PREFER=true will force them to use prefer: true.
-//
-// SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR
-//     If set this specifies the Soong config var that can be used to control whether the prebuilt
-//     modules from the generated snapshot or the original source modules. Values must be a colon
-//     separated pair of strings, the first of which is the Soong config namespace, and the second
-//     is the name of the variable within that namespace.
-//
-//     The config namespace and var name are used to set the `use_source_config_var` property. That
-//     in turn will cause the generated prebuilts to use the soong config variable to select whether
-//     source or the prebuilt is used.
-//     e.g. If an sdk snapshot is built using:
-//       m SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR=acme:build_from_source sdkextensions-sdk
-//     Then the resulting snapshot will include:
-//       use_source_config_var: {
-//         config_namespace: "acme",
-//         var_name: "build_from_source",
-//       }
-//
-//     Assuming that the config variable is defined in .mk using something like:
-//       $(call add_soong_config_namespace,acme)
-//       $(call add_soong_config_var_value,acme,build_from_source,true)
-//
-//     Then when the snapshot is unpacked in the repository it will have the following behavior:
-//       m droid - will use the sdkextensions-sdk prebuilts if present. Otherwise, it will use the
-//           sources.
-//       m SOONG_CONFIG_acme_build_from_source=true droid - will use the sdkextensions-sdk
-//            sources, if present. Otherwise, it will use the prebuilts.
-//
-//     This is a temporary mechanism to control the prefer flags and will be removed once a more
-//     maintainable solution has been implemented.
-//     TODO(b/174997203): Remove when no longer necessary.
-//
 // SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE
 //     This allows the target build release (i.e. the release version of the build within which
 //     the snapshot will be used) of the snapshot to be specified. If unspecified then it defaults
@@ -1049,6 +1014,9 @@
 	filesToZip  android.Paths
 	zipsToMerge android.Paths
 
+	// The path to an empty file.
+	emptyFile android.WritablePath
+
 	prebuiltModules map[string]*bpModule
 	prebuiltOrder   []*bpModule
 
@@ -1108,6 +1076,19 @@
 	s.zipsToMerge = append(s.zipsToMerge, tmpZipPath)
 }
 
+func (s *snapshotBuilder) EmptyFile() android.Path {
+	if s.emptyFile == nil {
+		ctx := s.ctx
+		s.emptyFile = android.PathForModuleOut(ctx, "empty")
+		s.ctx.Build(pctx, android.BuildParams{
+			Rule:   android.Touch,
+			Output: s.emptyFile,
+		})
+	}
+
+	return s.emptyFile
+}
+
 func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType string) android.BpModule {
 	name := member.Name()
 	if s.prebuiltModules[name] != nil {
@@ -1184,24 +1165,6 @@
 	return m
 }
 
-func (s *snapshotBuilder) AddInternalModule(properties android.SdkMemberProperties, moduleType string, nameSuffix string) android.BpModule {
-	name := properties.Name() + "-" + nameSuffix
-
-	if s.prebuiltModules[name] != nil {
-		panic(fmt.Sprintf("Duplicate module detected, module %s has already been added", name))
-	}
-
-	m := s.bpFile.newModule(moduleType)
-	m.AddProperty("name", name)
-	m.AddProperty("visibility", []string{"//visibility:private"})
-
-	s.prebuiltModules[name] = m
-	s.prebuiltOrder = append(s.prebuiltOrder, m)
-
-	s.allMembersByName[name] = struct{}{}
-	return m
-}
-
 func addHostDeviceSupportedProperties(deviceSupported bool, hostSupported bool, bpModule *bpModule) {
 	// If neither device or host is supported then this module does not support either so will not
 	// recognize the properties.
@@ -1232,23 +1195,18 @@
 // Get a name for sdk snapshot member. If the member is private then generate a snapshot specific
 // name. As part of the processing this checks to make sure that any required members are part of
 // the snapshot.
-func (s *snapshotBuilder) snapshotSdkMemberName(reference string, required bool) string {
-	prefix := ""
-	name := strings.TrimPrefix(reference, ":")
-	if name != reference {
-		prefix = ":"
-	}
+func (s *snapshotBuilder) snapshotSdkMemberName(name string, required bool) string {
 	if _, ok := s.allMembersByName[name]; !ok {
 		if required {
 			s.ctx.ModuleErrorf("Required member reference %s is not a member of the sdk", name)
 		}
-		return reference
+		return name
 	}
 
 	if s.isInternalMember(name) {
-		return prefix + s.ctx.ModuleName() + "_" + name
+		return s.ctx.ModuleName() + "_" + name
 	} else {
-		return reference
+		return name
 	}
 }
 
@@ -2026,29 +1984,12 @@
 
 	// Do not add the prefer property if the member snapshot module is a source module type.
 	moduleCtx := ctx.sdkMemberContext
-	config := moduleCtx.Config()
 	if !memberType.UsesSourceModuleTypeInSnapshot() {
-		// Set the prefer based on the environment variable. This is a temporary work around to allow a
-		// snapshot to be created that sets prefer: true.
-		// TODO(b/174997203): Remove once the ability to select the modules to prefer can be done
-		//  dynamically at build time not at snapshot generation time.
-		prefer := config.IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER")
-
 		// Set prefer. Setting this to false is not strictly required as that is the default but it does
 		// provide a convenient hook to post-process the generated Android.bp file, e.g. in tests to
 		// check the behavior when a prebuilt is preferred. It also makes it explicit what the default
 		// behavior is for the module.
-		bpModule.insertAfter("name", "prefer", prefer)
-
-		configVar := config.Getenv("SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR")
-		if configVar != "" {
-			parts := strings.Split(configVar, ":")
-			cfp := android.ConfigVarProperties{
-				Config_namespace: proptools.StringPtr(parts[0]),
-				Var_name:         proptools.StringPtr(parts[1]),
-			}
-			bpModule.insertAfter("prefer", "use_source_config_var", cfp)
-		}
+		bpModule.insertAfter("name", "prefer", false)
 	}
 
 	variants := selectApexVariantsWhereAvailable(ctx, member.variants)
@@ -2064,7 +2005,6 @@
 	variantPropertiesFactory := func() android.SdkMemberProperties {
 		properties := memberType.CreateVariantPropertiesStruct()
 		base := properties.Base()
-		base.MemberName = member.Name()
 		base.Os_count = osCount
 		return properties
 	}
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index adc56ac..b3b3866 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -154,10 +154,7 @@
 	"HOST_CROSS_OS",
 	"BUILD_ID",
 	"OUT_DIR",
-	"SOONG_SDK_SNAPSHOT_PREFER",
 	"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE",
-	"SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR",
-	"SOONG_SDK_SNAPSHOT_VERSION",
 }
 
 func Banner(make_vars map[string]string) string {