Merge "Relax apex package restriction for T+ jars"
diff --git a/android/defaults.go b/android/defaults.go
index 9046002..d2b351d 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -89,10 +89,10 @@
 var _ Defaultable = (*DefaultableModuleBase)(nil)
 
 func InitDefaultableModule(module DefaultableModule) {
-	if module.(Module).base().module == nil {
+	if module.base().module == nil {
 		panic("InitAndroidModule must be called before InitDefaultableModule")
 	}
-	module.setProperties(module.(Module).GetProperties(), module.(Module).base().variableProperties)
+	module.setProperties(module.GetProperties(), module.base().variableProperties)
 
 	module.AddProperties(module.defaults())
 
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 84bdcdd..254c90e 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -965,7 +965,7 @@
 
 	a.installDir = android.PathForModuleInstall(ctx, "apex")
 	if a.installable() {
-		ctx.InstallFile(a.installDir, a.installFilename, a.outputApex)
+		a.installedFile = ctx.InstallFile(a.installDir, a.installFilename, a.outputApex)
 	}
 
 	// in case that apex_set replaces source apex (using prefer: prop)
diff --git a/bp2build/performance_test.go b/bp2build/performance_test.go
index 3283952..c4bbae2 100644
--- a/bp2build/performance_test.go
+++ b/bp2build/performance_test.go
@@ -29,6 +29,10 @@
 	"testing"
 )
 
+const (
+	performance_test_dir = "."
+)
+
 func genCustomModule(i int, convert bool) string {
 	var conversionString string
 	if convert {
@@ -76,34 +80,83 @@
 	return strings.Join(bp, "\n\n")
 }
 
+type testConfig struct {
+	config     android.Config
+	ctx        *android.TestContext
+	codegenCtx *CodegenContext
+}
+
+func (tc testConfig) parse() []error {
+	_, errs := tc.ctx.ParseFileList(performance_test_dir, []string{"Android.bp"})
+	return errs
+}
+
+func (tc testConfig) resolveDependencies() []error {
+	_, errs := tc.ctx.ResolveDependencies(tc.config)
+	return errs
+}
+
+func (tc testConfig) convert() {
+	generateBazelTargetsForDir(tc.codegenCtx, performance_test_dir)
+}
+
+func setup(builddir string, tcSize float64) testConfig {
+	config := android.TestConfig(buildDir, nil, genCustomModuleBp(tcSize), nil)
+	ctx := android.NewTestContext(config)
+
+	registerCustomModuleForBp2buildConversion(ctx)
+	codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+	return testConfig{
+		config,
+		ctx,
+		codegenCtx,
+	}
+}
+
 var pctToConvert = []float64{0.0, 0.01, 0.05, 0.10, 0.25, 0.5, 0.75, 1.0}
 
+// This is not intended to test performance, but to verify performance infra continues to work
+func TestConvertManyModulesFull(t *testing.T) {
+	for _, tcSize := range pctToConvert {
+
+		t.Run(fmt.Sprintf("pctConverted %f", tcSize), func(t *testing.T) {
+			testConfig := setup(buildDir, tcSize)
+
+			errs := testConfig.parse()
+			if len(errs) > 0 {
+				t.Fatalf("Unexpected errors: %s", errs)
+			}
+
+			errs = testConfig.resolveDependencies()
+			if len(errs) > 0 {
+				t.Fatalf("Unexpected errors: %s", errs)
+			}
+
+			testConfig.convert()
+		})
+	}
+}
+
 func BenchmarkManyModulesFull(b *testing.B) {
-	dir := "."
 	for _, tcSize := range pctToConvert {
 
 		b.Run(fmt.Sprintf("pctConverted %f", tcSize), func(b *testing.B) {
 			for n := 0; n < b.N; n++ {
 				b.StopTimer()
-				// setup we don't want to measure
-				config := android.TestConfig(buildDir, nil, genCustomModuleBp(tcSize), nil)
-				ctx := android.NewTestContext(config)
-
-				registerCustomModuleForBp2buildConversion(ctx)
-				codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+				testConfig := setup(buildDir, tcSize)
 
 				b.StartTimer()
-				_, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
+				errs := testConfig.parse()
 				if len(errs) > 0 {
 					b.Fatalf("Unexpected errors: %s", errs)
 				}
 
-				_, errs = ctx.ResolveDependencies(config)
+				errs = testConfig.resolveDependencies()
 				if len(errs) > 0 {
 					b.Fatalf("Unexpected errors: %s", errs)
 				}
 
-				generateBazelTargetsForDir(codegenCtx, dir)
+				testConfig.convert()
 				b.StopTimer()
 			}
 		})
@@ -111,63 +164,53 @@
 }
 
 func BenchmarkManyModulesResolveDependencies(b *testing.B) {
-	dir := "."
 	for _, tcSize := range pctToConvert {
 
 		b.Run(fmt.Sprintf("pctConverted %f", tcSize), func(b *testing.B) {
 			for n := 0; n < b.N; n++ {
 				b.StopTimer()
 				// setup we don't want to measure
-				config := android.TestConfig(buildDir, nil, genCustomModuleBp(tcSize), nil)
-				ctx := android.NewTestContext(config)
+				testConfig := setup(buildDir, tcSize)
 
-				registerCustomModuleForBp2buildConversion(ctx)
-				codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
-
-				_, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
+				errs := testConfig.parse()
 				if len(errs) > 0 {
 					b.Fatalf("Unexpected errors: %s", errs)
 				}
 
 				b.StartTimer()
-				_, errs = ctx.ResolveDependencies(config)
+				errs = testConfig.resolveDependencies()
 				b.StopTimer()
 				if len(errs) > 0 {
 					b.Fatalf("Unexpected errors: %s", errs)
 				}
 
-				generateBazelTargetsForDir(codegenCtx, dir)
+				testConfig.convert()
 			}
 		})
 	}
 }
 
 func BenchmarkManyModulesGenerateBazelTargetsForDir(b *testing.B) {
-	dir := "."
 	for _, tcSize := range pctToConvert {
 
 		b.Run(fmt.Sprintf("pctConverted %f", tcSize), func(b *testing.B) {
 			for n := 0; n < b.N; n++ {
 				b.StopTimer()
 				// setup we don't want to measure
-				config := android.TestConfig(buildDir, nil, genCustomModuleBp(tcSize), nil)
-				ctx := android.NewTestContext(config)
+				testConfig := setup(buildDir, tcSize)
 
-				registerCustomModuleForBp2buildConversion(ctx)
-				codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
-
-				_, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
+				errs := testConfig.parse()
 				if len(errs) > 0 {
 					b.Fatalf("Unexpected errors: %s", errs)
 				}
 
-				_, errs = ctx.ResolveDependencies(config)
+				errs = testConfig.resolveDependencies()
 				if len(errs) > 0 {
 					b.Fatalf("Unexpected errors: %s", errs)
 				}
 
 				b.StartTimer()
-				generateBazelTargetsForDir(codegenCtx, dir)
+				testConfig.convert()
 				b.StopTimer()
 			}
 		})
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 38065f1..f29d8ad 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -16,6 +16,7 @@
 
 import (
 	"fmt"
+	"strconv"
 	"strings"
 
 	"github.com/google/blueprint"
@@ -42,6 +43,21 @@
 	},
 	"args", "libs")
 
+// targetSdkVersion for manifest_fixer
+// When TARGET_BUILD_APPS is not empty, this method returns 10000 for modules targeting an unreleased SDK
+// This enables release builds (that run with TARGET_BUILD_APPS=[val...]) to target APIs that have not yet been finalized as part of an SDK
+func targetSdkVersionForManifestFixer(ctx android.ModuleContext, sdkContext android.SdkContext) string {
+	targetSdkVersionSpec := sdkContext.TargetSdkVersion(ctx)
+	if ctx.Config().UnbundledBuildApps() && targetSdkVersionSpec.ApiLevel.IsPreview() {
+		return strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt())
+	}
+	targetSdkVersion, err := targetSdkVersionSpec.EffectiveVersionString(ctx)
+	if err != nil {
+		ctx.ModuleErrorf("invalid targetSdkVersion: %s", err)
+	}
+	return targetSdkVersion
+}
+
 // Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
 func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext android.SdkContext,
 	classLoaderContexts dexpreopt.ClassLoaderContextMap, isLibrary, useEmbeddedNativeLibs, usesNonSdkApis,
@@ -89,10 +105,8 @@
 		args = append(args, "--logging-parent", loggingParent)
 	}
 	var deps android.Paths
-	targetSdkVersion, err := sdkContext.TargetSdkVersion(ctx).EffectiveVersionString(ctx)
-	if err != nil {
-		ctx.ModuleErrorf("invalid targetSdkVersion: %s", err)
-	}
+	targetSdkVersion := targetSdkVersionForManifestFixer(ctx, sdkContext)
+
 	if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
 		targetSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String())
 		deps = append(deps, ApiFingerprintPath(ctx))
diff --git a/java/app_test.go b/java/app_test.go
index 0aae928..4da7c3d 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2873,3 +2873,76 @@
 		t.Errorf("App does not use library proguard config")
 	}
 }
+
+func TestTargetSdkVersionManifestFixer(t *testing.T) {
+	platform_sdk_codename := "Tiramisu"
+	testCases := []struct {
+		name                     string
+		targetSdkVersionInBp     string
+		targetSdkVersionExpected string
+		unbundledBuild           bool
+	}{
+		{
+			name:                     "Non-Unbundled build: Android.bp has targetSdkVersion",
+			targetSdkVersionInBp:     "30",
+			targetSdkVersionExpected: "30",
+			unbundledBuild:           false,
+		},
+		{
+			name:                     "Unbundled build: Android.bp has targetSdkVersion",
+			targetSdkVersionInBp:     "30",
+			targetSdkVersionExpected: "30",
+			unbundledBuild:           true,
+		},
+		{
+			name:                     "Non-Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename",
+			targetSdkVersionInBp:     platform_sdk_codename,
+			targetSdkVersionExpected: platform_sdk_codename,
+			unbundledBuild:           false,
+		},
+		{
+			name:                     "Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename",
+			targetSdkVersionInBp:     platform_sdk_codename,
+			targetSdkVersionExpected: "10000",
+			unbundledBuild:           true,
+		},
+
+		{
+			name:                     "Non-Unbundled build: Android.bp has no targetSdkVersion",
+			targetSdkVersionExpected: platform_sdk_codename,
+			unbundledBuild:           false,
+		},
+		{
+			name:                     "Unbundled build: Android.bp has no targetSdkVersion",
+			targetSdkVersionExpected: "10000",
+			unbundledBuild:           true,
+		},
+	}
+	for _, testCase := range testCases {
+		bp := fmt.Sprintf(`
+			android_app {
+				name: "foo",
+				sdk_version: "current",
+				target_sdk_version: "%v",
+			}
+			`, testCase.targetSdkVersionInBp)
+		fixture := android.GroupFixturePreparers(
+			prepareForJavaTest,
+			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+				// explicitly set platform_sdk_codename to make the test deterministic
+				variables.Platform_sdk_codename = &platform_sdk_codename
+				variables.Platform_version_active_codenames = []string{platform_sdk_codename}
+				// create a non-empty list if unbundledBuild==true
+				if testCase.unbundledBuild {
+					variables.Unbundled_build_apps = []string{"apex_a", "apex_b"}
+				}
+			}),
+		)
+
+		result := fixture.RunTestWithBp(t, bp)
+		foo := result.ModuleForTests("foo", "android_common")
+
+		manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args
+		android.AssertStringEquals(t, testCase.name, testCase.targetSdkVersionExpected, manifestFixerArgs["targetSdkVersion"])
+	}
+}