Merge changes I816f209e,I9e4d51c3 into main

* changes:
  Handle enabled: false via conditions_default
  Handle nil enabled values
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 6f41f37..6ca4bb4 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -29,6 +29,7 @@
 	"android/soong/bazel"
 	"android/soong/starlark_fmt"
 	"android/soong/ui/metrics/bp2build_metrics_proto"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/bootstrap"
 	"github.com/google/blueprint/proptools"
@@ -94,16 +95,16 @@
 // statements (use LoadStatements for that), since the targets are usually not
 // adjacent to the load statements at the top of the BUILD file.
 func (targets BazelTargets) String() string {
-	var res string
+	var res strings.Builder
 	for i, target := range targets {
 		if target.ruleClass != "package" {
-			res += target.content
+			res.WriteString(target.content)
 		}
 		if i != len(targets)-1 {
-			res += "\n\n"
+			res.WriteString("\n\n")
 		}
 	}
-	return res
+	return res.String()
 }
 
 // LoadStatements return the string representation of the sorted and deduplicated
diff --git a/java/aapt2.go b/java/aapt2.go
index 4cff8a7..3bb70b5 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -146,21 +146,25 @@
 
 var aapt2LinkRule = pctx.AndroidStaticRule("aapt2Link",
 	blueprint.RuleParams{
-		Command: `rm -rf $genDir && ` +
-			`${config.Aapt2Cmd} link -o $out $flags --java $genDir --proguard $proguardOptions ` +
-			`--output-text-symbols ${rTxt} $inFlags && ` +
-			`${config.SoongZipCmd} -write_if_changed -jar -o $genJar -C $genDir -D $genDir &&` +
-			`${config.ExtractJarPackagesCmd} -i $genJar -o $extraPackages --prefix '--extra-packages ' && ` +
-			`rm -rf $genDir`,
+		Command: `$preamble` +
+			`${config.Aapt2Cmd} link -o $out $flags --proguard $proguardOptions ` +
+			`--output-text-symbols ${rTxt} $inFlags` +
+			`$postamble`,
 
 		CommandDeps: []string{
 			"${config.Aapt2Cmd}",
 			"${config.SoongZipCmd}",
-			"${config.ExtractJarPackagesCmd}",
 		},
 		Restat: true,
 	},
-	"flags", "inFlags", "proguardOptions", "genDir", "genJar", "rTxt", "extraPackages")
+	"flags", "inFlags", "proguardOptions", "rTxt", "extraPackages", "preamble", "postamble")
+
+var aapt2ExtractExtraPackagesRule = pctx.AndroidStaticRule("aapt2ExtractExtraPackages",
+	blueprint.RuleParams{
+		Command:     `${config.ExtractJarPackagesCmd} -i $in -o $out --prefix '--extra-packages '`,
+		CommandDeps: []string{"${config.ExtractJarPackagesCmd}"},
+		Restat:      true,
+	})
 
 var fileListToFileRule = pctx.AndroidStaticRule("fileListToFile",
 	blueprint.RuleParams{
@@ -176,12 +180,10 @@
 	})
 
 func aapt2Link(ctx android.ModuleContext,
-	packageRes, genJar, proguardOptions, rTxt, extraPackages android.WritablePath,
+	packageRes, genJar, proguardOptions, rTxt android.WritablePath,
 	flags []string, deps android.Paths,
 	compiledRes, compiledOverlay, assetPackages android.Paths, splitPackages android.WritablePaths) {
 
-	genDir := android.PathForModuleGen(ctx, "aapt2", "R")
-
 	var inFlags []string
 
 	if len(compiledRes) > 0 {
@@ -218,7 +220,7 @@
 	}
 
 	// Set auxiliary outputs as implicit outputs to establish correct dependency chains.
-	implicitOutputs := append(splitPackages, proguardOptions, genJar, rTxt, extraPackages)
+	implicitOutputs := append(splitPackages, proguardOptions, rTxt)
 	linkOutput := packageRes
 
 	// AAPT2 ignores assets in overlays. Merge them after linking.
@@ -233,25 +235,49 @@
 		})
 	}
 
+	// Note the absence of splitPackages. The caller is supposed to compose and provide --split flag
+	// values via the flags parameter when it wants to split outputs.
+	// TODO(b/174509108): Perhaps we can process it in this func while keeping the code reasonably
+	// tidy.
+	args := map[string]string{
+		"flags":           strings.Join(flags, " "),
+		"inFlags":         strings.Join(inFlags, " "),
+		"proguardOptions": proguardOptions.String(),
+		"rTxt":            rTxt.String(),
+	}
+
+	if genJar != nil {
+		// Generating java source files from aapt2 was requested, use aapt2LinkAndGenRule and pass it
+		// genJar and genDir args.
+		genDir := android.PathForModuleGen(ctx, "aapt2", "R")
+		ctx.Variable(pctx, "aapt2GenDir", genDir.String())
+		ctx.Variable(pctx, "aapt2GenJar", genJar.String())
+		implicitOutputs = append(implicitOutputs, genJar)
+		args["preamble"] = `rm -rf $aapt2GenDir && `
+		args["postamble"] = `&& ${config.SoongZipCmd} -write_if_changed -jar -o $aapt2GenJar -C $aapt2GenDir -D $aapt2GenDir && ` +
+			`rm -rf $aapt2GenDir`
+		args["flags"] += " --java $aapt2GenDir"
+	}
+
 	ctx.Build(pctx, android.BuildParams{
 		Rule:            aapt2LinkRule,
 		Description:     "aapt2 link",
 		Implicits:       deps,
 		Output:          linkOutput,
 		ImplicitOutputs: implicitOutputs,
-		// Note the absence of splitPackages. The caller is supposed to compose and provide --split flag
-		// values via the flags parameter when it wants to split outputs.
-		// TODO(b/174509108): Perhaps we can process it in this func while keeping the code reasonably
-		// tidy.
-		Args: map[string]string{
-			"flags":           strings.Join(flags, " "),
-			"inFlags":         strings.Join(inFlags, " "),
-			"proguardOptions": proguardOptions.String(),
-			"genDir":          genDir.String(),
-			"genJar":          genJar.String(),
-			"rTxt":            rTxt.String(),
-			"extraPackages":   extraPackages.String(),
-		},
+		Args:            args,
+	})
+}
+
+// aapt2ExtractExtraPackages takes a srcjar generated by aapt2 or a classes jar generated by ResourceProcessorBusyBox
+// and converts it to a text file containing a list of --extra_package arguments for passing to Make modules so they
+// correctly generate R.java entries for packages provided by transitive dependencies.
+func aapt2ExtractExtraPackages(ctx android.ModuleContext, out android.WritablePath, in android.Path) {
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        aapt2ExtractExtraPackagesRule,
+		Description: "aapt2 extract extra packages",
+		Input:       in,
+		Output:      out,
 	})
 }
 
diff --git a/java/aar.go b/java/aar.go
index 180e1d7..1e38efc 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -376,13 +376,12 @@
 	}
 
 	packageRes := android.PathForModuleOut(ctx, "package-res.apk")
-	// the subdir "android" is required to be filtered by package names
-	srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar")
 	proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
 	rTxt := android.PathForModuleOut(ctx, "R.txt")
 	// This file isn't used by Soong, but is generated for exporting
 	extraPackages := android.PathForModuleOut(ctx, "extra_packages")
 	var transitiveRJars android.Paths
+	var srcJar android.WritablePath
 
 	var compiledResDirs []android.Paths
 	for _, dir := range resDirs {
@@ -459,15 +458,19 @@
 		})
 	}
 
+	if !a.useResourceProcessorBusyBox() {
+		// the subdir "android" is required to be filtered by package names
+		srcJar = android.PathForModuleGen(ctx, "android", "R.srcjar")
+	}
+
 	// No need to specify assets from dependencies to aapt2Link for libraries, all transitive assets will be
 	// provided to the final app aapt2Link step.
 	var transitiveAssets android.Paths
 	if !a.isLibrary {
 		transitiveAssets = android.ReverseSliceInPlace(staticDeps.assets())
 	}
-	aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages,
+	aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt,
 		linkFlags, linkDeps, compiledRes, compiledOverlay, transitiveAssets, splitPackages)
-
 	// Extract assets from the resource package output so that they can be used later in aapt2link
 	// for modules that depend on this one.
 	if android.PrefixInList(linkFlags, "-A ") {
@@ -484,8 +487,11 @@
 	if a.useResourceProcessorBusyBox() {
 		rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
 		resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary)
+		aapt2ExtractExtraPackages(ctx, extraPackages, rJar)
 		transitiveRJars = append(transitiveRJars, rJar)
 		a.rJar = rJar
+	} else {
+		aapt2ExtractExtraPackages(ctx, extraPackages, srcJar)
 	}
 
 	a.aaptSrcJar = srcJar
@@ -731,9 +737,10 @@
 
 	ctx.CheckbuildFile(a.aapt.proguardOptionsFile)
 	ctx.CheckbuildFile(a.aapt.exportPackage)
-	ctx.CheckbuildFile(a.aapt.aaptSrcJar)
 	if a.useResourceProcessorBusyBox() {
 		ctx.CheckbuildFile(a.aapt.rJar)
+	} else {
+		ctx.CheckbuildFile(a.aapt.aaptSrcJar)
 	}
 
 	// apps manifests are handled by aapt, don't let Module see them
@@ -1063,8 +1070,6 @@
 	aapt2CompileZip(ctx, flata, a.aarPath, "res", compileFlags)
 
 	a.exportPackage = android.PathForModuleOut(ctx, "package-res.apk")
-	// the subdir "android" is required to be filtered by package names
-	srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar")
 	proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
 	a.rTxt = android.PathForModuleOut(ctx, "R.txt")
 	a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages")
@@ -1100,12 +1105,14 @@
 	}
 
 	transitiveAssets := android.ReverseSliceInPlace(staticDeps.assets())
-	aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, a.rTxt, a.extraAaptPackagesFile,
+	aapt2Link(ctx, a.exportPackage, nil, proguardOptionsFile, a.rTxt,
 		linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil)
 
 	a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar")
 	resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true)
 
+	aapt2ExtractExtraPackages(ctx, a.extraAaptPackagesFile, a.rJar)
+
 	resourcesNodesDepSetBuilder := android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL)
 	resourcesNodesDepSetBuilder.Direct(&resourcesNode{
 		resPackage: a.exportPackage,
@@ -1305,7 +1312,11 @@
 }
 
 func (a *AndroidLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
-	commonAttrs, bp2buildInfo := a.convertLibraryAttrsBp2Build(ctx)
+	commonAttrs, bp2buildInfo, supported := a.convertLibraryAttrsBp2Build(ctx)
+	if !supported {
+		return
+	}
+
 	depLabels := bp2buildInfo.DepLabels
 
 	deps := depLabels.Deps
diff --git a/java/app.go b/java/app.go
index 224bc88..e277aed 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1022,7 +1022,13 @@
 	case ".aapt.proguardOptionsFile":
 		return []android.Path{a.proguardOptionsFile}, nil
 	case ".aapt.srcjar":
-		return []android.Path{a.aaptSrcJar}, nil
+		if a.aaptSrcJar != nil {
+			return []android.Path{a.aaptSrcJar}, nil
+		}
+	case ".aapt.jar":
+		if a.rJar != nil {
+			return []android.Path{a.rJar}, nil
+		}
 	case ".export-package.apk":
 		return []android.Path{a.exportPackage}, nil
 	}
@@ -1613,7 +1619,10 @@
 
 // ConvertWithBp2build is used to convert android_app to Bazel.
 func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
-	commonAttrs, bp2BuildInfo := a.convertLibraryAttrsBp2Build(ctx)
+	commonAttrs, bp2BuildInfo, supported := a.convertLibraryAttrsBp2Build(ctx)
+	if !supported {
+		return
+	}
 	depLabels := bp2BuildInfo.DepLabels
 
 	deps := depLabels.Deps
diff --git a/java/java.go b/java/java.go
index f29f738..f11debf 100644
--- a/java/java.go
+++ b/java/java.go
@@ -26,6 +26,7 @@
 	"android/soong/bazel"
 	"android/soong/bazel/cquery"
 	"android/soong/remoteexec"
+	"android/soong/ui/metrics/bp2build_metrics_proto"
 
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
@@ -2828,7 +2829,7 @@
 // which has other non-attribute information needed for bp2build conversion
 // that needs different handling depending on the module types, and thus needs
 // to be returned to the calling function.
-func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) (*javaCommonAttributes, *bp2BuildJavaInfo) {
+func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) (*javaCommonAttributes, *bp2BuildJavaInfo, bool) {
 	var srcs bazel.LabelListAttribute
 	var deps bazel.LabelListAttribute
 	var staticDeps bazel.LabelListAttribute
@@ -2839,6 +2840,10 @@
 			if archProps, ok := _props.(*CommonProperties); ok {
 				archSrcs := android.BazelLabelForModuleSrcExcludes(ctx, archProps.Srcs, archProps.Exclude_srcs)
 				srcs.SetSelectValue(axis, config, archSrcs)
+				if archProps.Jarjar_rules != nil {
+					ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "jarjar_rules")
+					return &javaCommonAttributes{}, &bp2BuildJavaInfo{}, false
+				}
 			}
 		}
 	}
@@ -3006,7 +3011,7 @@
 		hasKotlin: hasKotlin,
 	}
 
-	return commonAttrs, bp2BuildInfo
+	return commonAttrs, bp2BuildInfo, true
 }
 
 type javaLibraryAttributes struct {
@@ -3036,7 +3041,10 @@
 }
 
 func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) {
-	commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx)
+	commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx)
+	if !supported {
+		return
+	}
 	depLabels := bp2BuildInfo.DepLabels
 
 	deps := depLabels.Deps
@@ -3083,7 +3091,10 @@
 
 // JavaBinaryHostBp2Build is for java_binary_host bp2build.
 func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) {
-	commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx)
+	commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx)
+	if !supported {
+		return
+	}
 	depLabels := bp2BuildInfo.DepLabels
 
 	deps := depLabels.Deps
@@ -3167,7 +3178,10 @@
 
 // javaTestHostBp2Build is for java_test_host bp2build.
 func javaTestHostBp2Build(ctx android.TopDownMutatorContext, m *TestHost) {
-	commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx)
+	commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx)
+	if !supported {
+		return
+	}
 	depLabels := bp2BuildInfo.DepLabels
 
 	deps := depLabels.Deps
diff --git a/java/plugin.go b/java/plugin.go
index 731dfda..5127298 100644
--- a/java/plugin.go
+++ b/java/plugin.go
@@ -66,7 +66,10 @@
 // ConvertWithBp2build is used to convert android_app to Bazel.
 func (p *Plugin) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
 	pluginName := p.Name()
-	commonAttrs, bp2BuildInfo := p.convertLibraryAttrsBp2Build(ctx)
+	commonAttrs, bp2BuildInfo, supported := p.convertLibraryAttrsBp2Build(ctx)
+	if !supported {
+		return
+	}
 	depLabels := bp2BuildInfo.DepLabels
 
 	deps := depLabels.Deps
diff --git a/ui/build/config.go b/ui/build/config.go
index e5c9a50..cecc8fa 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -15,7 +15,6 @@
 package build
 
 import (
-	"context"
 	"encoding/json"
 	"errors"
 	"fmt"
@@ -40,9 +39,6 @@
 const (
 	envConfigDir = "vendor/google/tools/soong_config"
 	jsonSuffix   = "json"
-
-	configFetcher         = "vendor/google/tools/soong/expconfigfetcher"
-	envConfigFetchTimeout = 20 * time.Second
 )
 
 var (
@@ -174,87 +170,6 @@
 	}
 }
 
-// fetchEnvConfig optionally fetches a configuration file that can then subsequently be
-// loaded into Soong environment to control certain aspects of build behavior (e.g., enabling RBE).
-// If a configuration file already exists on disk, the fetch is run in the background
-// so as to NOT block the rest of the build execution.
-func fetchEnvConfig(ctx Context, config *configImpl, envConfigName string) error {
-	configName := envConfigName + "." + jsonSuffix
-	expConfigFetcher := &smpb.ExpConfigFetcher{Filename: &configName}
-	defer func() {
-		ctx.Metrics.ExpConfigFetcher(expConfigFetcher)
-	}()
-	if !config.GoogleProdCredsExist() {
-		status := smpb.ExpConfigFetcher_MISSING_GCERT
-		expConfigFetcher.Status = &status
-		return nil
-	}
-
-	s, err := os.Stat(configFetcher)
-	if err != nil {
-		if os.IsNotExist(err) {
-			return nil
-		}
-		return err
-	}
-	if s.Mode()&0111 == 0 {
-		status := smpb.ExpConfigFetcher_ERROR
-		expConfigFetcher.Status = &status
-		return fmt.Errorf("configuration fetcher binary %v is not executable: %v", configFetcher, s.Mode())
-	}
-
-	configExists := false
-	outConfigFilePath := filepath.Join(config.OutDir(), configName)
-	if _, err := os.Stat(outConfigFilePath); err == nil {
-		configExists = true
-	}
-
-	tCtx, cancel := context.WithTimeout(ctx, envConfigFetchTimeout)
-	fetchStart := time.Now()
-	cmd := exec.CommandContext(tCtx, configFetcher, "-output_config_dir", config.OutDir(),
-		"-output_config_name", configName)
-	if err := cmd.Start(); err != nil {
-		status := smpb.ExpConfigFetcher_ERROR
-		expConfigFetcher.Status = &status
-		return err
-	}
-
-	fetchCfg := func() error {
-		if err := cmd.Wait(); err != nil {
-			status := smpb.ExpConfigFetcher_ERROR
-			expConfigFetcher.Status = &status
-			return err
-		}
-		fetchEnd := time.Now()
-		expConfigFetcher.Micros = proto.Uint64(uint64(fetchEnd.Sub(fetchStart).Microseconds()))
-		expConfigFetcher.Filename = proto.String(outConfigFilePath)
-
-		if _, err := os.Stat(outConfigFilePath); err != nil {
-			status := smpb.ExpConfigFetcher_NO_CONFIG
-			expConfigFetcher.Status = &status
-			return err
-		}
-		status := smpb.ExpConfigFetcher_CONFIG
-		expConfigFetcher.Status = &status
-		return nil
-	}
-
-	// If a config file does not exist, wait for the config file to be fetched. Otherwise
-	// fetch the config file in the background and return immediately.
-	if !configExists {
-		defer cancel()
-		return fetchCfg()
-	}
-
-	go func() {
-		defer cancel()
-		if err := fetchCfg(); err != nil {
-			ctx.Verbosef("Failed to fetch config file %v: %v\n", configName, err)
-		}
-	}()
-	return nil
-}
-
 func loadEnvConfig(ctx Context, config *configImpl, bc string) error {
 	if bc == "" {
 		return nil
@@ -368,9 +283,6 @@
 	bc := os.Getenv("ANDROID_BUILD_ENVIRONMENT_CONFIG")
 
 	if bc != "" {
-		if err := fetchEnvConfig(ctx, ret, bc); err != nil {
-			ctx.Verbosef("Failed to fetch config file: %v\n", err)
-		}
 		if err := loadEnvConfig(ctx, ret, bc); err != nil {
 			ctx.Fatalln("Failed to parse env config files: %v", err)
 		}