Merge "New AndroidMk authoring system based on entry map."
diff --git a/android/config.go b/android/config.go
index 3af448d..25615b6 100644
--- a/android/config.go
+++ b/android/config.go
@@ -198,6 +198,14 @@
 
 // TestConfig returns a Config object suitable for using for tests
 func TestConfig(buildDir string, env map[string]string) Config {
+	envCopy := make(map[string]string)
+	for k, v := range env {
+		envCopy[k] = v
+	}
+
+	// Copy the real PATH value to the test environment, it's needed by HostSystemTool() used in x86_darwin_host.go
+	envCopy["PATH"] = originalEnv["PATH"]
+
 	config := &config{
 		productVariables: productVariables{
 			DeviceName:                  stringPtr("test_device"),
@@ -212,7 +220,7 @@
 
 		buildDir:     buildDir,
 		captureBuild: true,
-		env:          env,
+		env:          envCopy,
 	}
 	config.deviceConfig = &deviceConfig{
 		config: config,
@@ -622,7 +630,7 @@
 	return Bool(c.productVariables.Unbundled_build)
 }
 
-func (c *config) UnbundledBuildPrebuiltSdks() bool {
+func (c *config) UnbundledBuildUsePrebuiltSdks() bool {
 	return Bool(c.productVariables.Unbundled_build) && !Bool(c.productVariables.Unbundled_build_sdks_from_source)
 }
 
diff --git a/apex/apex.go b/apex/apex.go
index 004de86..509e0f2 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -977,6 +977,17 @@
 			optFlags = append(optFlags, "--android_manifest "+androidManifestFile.String())
 		}
 
+		targetSdkVersion := ctx.Config().DefaultAppTargetSdk()
+		if targetSdkVersion == ctx.Config().PlatformSdkCodename() &&
+			ctx.Config().UnbundledBuild() &&
+			!ctx.Config().UnbundledBuildUsePrebuiltSdks() &&
+			ctx.Config().IsEnvTrue("UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT") {
+			apiFingerprint := java.ApiFingerprintPath(ctx)
+			targetSdkVersion += fmt.Sprintf(".$$(cat %s)", apiFingerprint.String())
+			implicitInputs = append(implicitInputs, apiFingerprint)
+		}
+		optFlags = append(optFlags, "--target_sdk_version "+targetSdkVersion)
+
 		ctx.Build(pctx, android.BuildParams{
 			Rule:        apexRule,
 			Implicits:   implicitInputs,
diff --git a/apex/apex_test.go b/apex/apex_test.go
index fce2135..b0cd4be 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -171,6 +171,7 @@
 		"testkey2.pem":                         nil,
 		"myapex-arm64.apex":                    nil,
 		"myapex-arm.apex":                      nil,
+		"frameworks/base/api/current.txt":      nil,
 	})
 	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
 	android.FailIfErrored(t, errs)
@@ -190,6 +191,8 @@
 	config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
 	config.TestProductVariables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test")
 	config.TestProductVariables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"}
+	config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("Q")
+	config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(false)
 	return
 }
 
diff --git a/cc/proto_test.go b/cc/proto_test.go
index a7fcef9..4f0de78 100644
--- a/cc/proto_test.go
+++ b/cc/proto_test.go
@@ -15,7 +15,6 @@
 package cc
 
 import (
-	"runtime"
 	"strings"
 	"testing"
 
@@ -38,9 +37,6 @@
 	})
 
 	t.Run("plugin", func(t *testing.T) {
-		if runtime.GOOS != "linux" {
-			t.Skip("TODO(b/129763458): cc_binary_host tests fail on mac when trying to exec xcrun")
-		}
 		ctx := testCc(t, `
 		cc_binary_host {
 			name: "protoc-gen-foobar",
diff --git a/cmd/pom2bp/pom2bp.go b/cmd/pom2bp/pom2bp.go
index 2dfa546..c858c40 100644
--- a/cmd/pom2bp/pom2bp.go
+++ b/cmd/pom2bp/pom2bp.go
@@ -126,6 +126,7 @@
 
 var sdkVersion string
 var useVersion string
+var staticDeps bool
 var jetifier bool
 
 func InList(s string, list []string) bool {
@@ -333,6 +334,38 @@
 
 var bpTemplate = template.Must(template.New("bp").Parse(`
 {{.ImportModuleType}} {
+    name: "{{.BpName}}",
+    {{.ImportProperty}}: ["{{.ArtifactFile}}"],
+    sdk_version: "{{.SdkVersion}}",
+    {{- if .Jetifier}}
+    jetifier: true,
+    {{- end}}
+    {{- if .IsAar}}
+    min_sdk_version: "{{.MinSdkVersion}}",
+    static_libs: [
+        {{- range .BpJarDeps}}
+        "{{.}}",
+        {{- end}}
+        {{- range .BpAarDeps}}
+        "{{.}}",
+        {{- end}}
+        {{- range .BpExtraStaticLibs}}
+        "{{.}}",
+        {{- end}}
+    ],
+    {{- if .BpExtraLibs}}
+    libs: [
+        {{- range .BpExtraLibs}}
+        "{{.}}",
+        {{- end}}
+    ],
+    {{- end}}
+    {{- end}}
+}
+`))
+
+var bpDepsTemplate = template.Must(template.New("bp").Parse(`
+{{.ImportModuleType}} {
     name: "{{.BpName}}-nodeps",
     {{.ImportProperty}}: ["{{.ArtifactFile}}"],
     sdk_version: "{{.SdkVersion}}",
@@ -533,8 +566,8 @@
 	flag.Var(&hostModuleNames, "host", "Specifies that the corresponding module (specified in the form 'module.group:module.artifact') is a host module")
 	flag.StringVar(&sdkVersion, "sdk-version", "", "What to write to sdk_version")
 	flag.StringVar(&useVersion, "use-version", "", "Only read artifacts of a specific version")
+	flag.BoolVar(&staticDeps, "static-deps", false, "Statically include direct dependencies")
 	flag.BoolVar(&jetifier, "jetifier", false, "Sets jetifier: true on all modules")
-	flag.Bool("static-deps", false, "Ignored")
 	flag.StringVar(&regen, "regen", "", "Rewrite specified file")
 	flag.Parse()
 
@@ -648,7 +681,11 @@
 
 	for _, pom := range poms {
 		var err error
-		err = bpTemplate.Execute(buf, pom)
+		if staticDeps {
+			err = bpDepsTemplate.Execute(buf, pom)
+		} else {
+			err = bpTemplate.Execute(buf, pom)
+		}
 		if err != nil {
 			fmt.Fprintln(os.Stderr, "Error writing", pom.PomFile, pom.BpName(), err)
 			os.Exit(1)
diff --git a/java/aar.go b/java/aar.go
index a993bf6..c621276 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -511,7 +511,7 @@
 }
 
 func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
-	if !ctx.Config().UnbundledBuildPrebuiltSdks() {
+	if !ctx.Config().UnbundledBuildUsePrebuiltSdks() {
 		sdkDep := decodeSdkDep(ctx, sdkContext(a))
 		if sdkDep.useModule && sdkDep.frameworkResModule != "" {
 			ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
diff --git a/java/android_manifest.go b/java/android_manifest.go
index d72476d..8dc3b47 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -68,15 +68,27 @@
 		args = append(args, "--use-embedded-dex=true")
 	}
 
+	var deps android.Paths
+	targetSdkVersion := sdkVersionOrDefault(ctx, sdkContext.targetSdkVersion())
+	if targetSdkVersion == ctx.Config().PlatformSdkCodename() &&
+		ctx.Config().UnbundledBuild() &&
+		!ctx.Config().UnbundledBuildUsePrebuiltSdks() &&
+		ctx.Config().IsEnvTrue("UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT") {
+		apiFingerprint := ApiFingerprintPath(ctx)
+		targetSdkVersion += fmt.Sprintf(".$$(cat %s)", apiFingerprint.String())
+		deps = append(deps, apiFingerprint)
+	}
+
 	// Inject minSdkVersion into the manifest
 	fixedManifest := android.PathForModuleOut(ctx, "manifest_fixer", "AndroidManifest.xml")
 	ctx.Build(pctx, android.BuildParams{
-		Rule:   manifestFixerRule,
-		Input:  manifest,
-		Output: fixedManifest,
+		Rule:      manifestFixerRule,
+		Input:     manifest,
+		Implicits: deps,
+		Output:    fixedManifest,
 		Args: map[string]string{
 			"minSdkVersion":    sdkVersionOrDefault(ctx, sdkContext.minSdkVersion()),
-			"targetSdkVersion": sdkVersionOrDefault(ctx, sdkContext.targetSdkVersion()),
+			"targetSdkVersion": targetSdkVersion,
 			"args":             strings.Join(args, " "),
 		},
 	})
diff --git a/java/sdk.go b/java/sdk.go
index d50bcae..e93f8fb 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -19,6 +19,7 @@
 	"android/soong/java/config"
 	"fmt"
 	"path/filepath"
+	"runtime"
 	"sort"
 	"strconv"
 	"strings"
@@ -29,11 +30,12 @@
 func init() {
 	android.RegisterPreSingletonType("sdk_versions", sdkPreSingletonFactory)
 	android.RegisterSingletonType("sdk", sdkSingletonFactory)
-	android.RegisterMakeVarsProvider(pctx, sdkFrameworkAidlMakeVars)
+	android.RegisterMakeVarsProvider(pctx, sdkMakeVars)
 }
 
 var sdkVersionsKey = android.NewOnceKey("sdkVersionsKey")
 var sdkFrameworkAidlPathKey = android.NewOnceKey("sdkFrameworkAidlPathKey")
+var apiFingerprintPathKey = android.NewOnceKey("apiFingerprintPathKey")
 
 type sdkContext interface {
 	// sdkVersion eturns the sdk_version property of the current module, or an empty string if it is not set.
@@ -171,7 +173,7 @@
 		}
 	}
 
-	if ctx.Config().UnbundledBuildPrebuiltSdks() && v != "" {
+	if ctx.Config().UnbundledBuildUsePrebuiltSdks() && v != "" {
 		return toPrebuilt(v)
 	}
 
@@ -230,12 +232,16 @@
 type sdkSingleton struct{}
 
 func (sdkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
-	if ctx.Config().UnbundledBuildPrebuiltSdks() || ctx.Config().IsPdkBuild() {
+	if ctx.Config().UnbundledBuildUsePrebuiltSdks() || ctx.Config().IsPdkBuild() {
 		return
 	}
 
-	// Create framework.aidl by extracting anything that implements android.os.Parcelable from the SDK stubs modules.
+	createSdkFrameworkAidl(ctx)
+	createAPIFingerprint(ctx)
+}
 
+// Create framework.aidl by extracting anything that implements android.os.Parcelable from the SDK stubs modules.
+func createSdkFrameworkAidl(ctx android.SingletonContext) {
 	stubsModules := []string{
 		"android_stubs_current",
 		"android_test_stubs_current",
@@ -308,10 +314,62 @@
 	}).(android.OutputPath)
 }
 
-func sdkFrameworkAidlMakeVars(ctx android.MakeVarsContext) {
-	if ctx.Config().UnbundledBuildPrebuiltSdks() || ctx.Config().IsPdkBuild() {
+// Create api_fingerprint.txt
+func createAPIFingerprint(ctx android.SingletonContext) {
+	out := ApiFingerprintPath(ctx)
+
+	rule := android.NewRuleBuilder()
+
+	rule.Command().
+		Text("rm -f").Output(out)
+	cmd := rule.Command()
+
+	if ctx.Config().PlatformSdkCodename() == "REL" {
+		cmd.Text("echo REL >").Output(out)
+	} else if ctx.Config().IsPdkBuild() {
+		// TODO: get this from the PDK artifacts?
+		cmd.Text("echo PDK >").Output(out)
+	} else if !ctx.Config().UnbundledBuildUsePrebuiltSdks() {
+		in, err := ctx.GlobWithDeps("frameworks/base/api/*current.txt", nil)
+		if err != nil {
+			ctx.Errorf("error globbing API files: %s", err)
+		}
+
+		cmd.Text("cat").
+			Inputs(android.PathsForSource(ctx, in)).
+			Text("|")
+
+		if runtime.GOOS == "darwin" {
+			cmd.Text("md5")
+		} else {
+			cmd.Text("md5sum")
+		}
+
+		cmd.Text("| cut -d' ' -f1 >").
+			Output(out)
+	} else {
+		// Unbundled build
+		// TODO: use a prebuilt api_fingerprint.txt from prebuilts/sdk/current.txt once we have one
+		cmd.Text("echo").
+			Flag(ctx.Config().PlatformPreviewSdkVersion()).
+			Text(">").
+			Output(out)
+	}
+
+	rule.Build(pctx, ctx, "api_fingerprint", "generate api_fingerprint.txt")
+}
+
+func ApiFingerprintPath(ctx android.PathContext) android.OutputPath {
+	return ctx.Config().Once(apiFingerprintPathKey, func() interface{} {
+		return android.PathForOutput(ctx, "api_fingerprint.txt")
+	}).(android.OutputPath)
+}
+
+func sdkMakeVars(ctx android.MakeVarsContext) {
+	if ctx.Config().UnbundledBuildUsePrebuiltSdks() || ctx.Config().IsPdkBuild() {
 		return
 	}
 
 	ctx.Strict("FRAMEWORK_AIDL", sdkFrameworkAidlPath(ctx).String())
+	ctx.Strict("API_FINGERPRINT", ApiFingerprintPath(ctx).String())
 }
diff --git a/java/sdk_library.go b/java/sdk_library.go
index c60a8a0..72c5cfc 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -402,7 +402,7 @@
 	props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
 	props.Libs = module.sdkLibraryProperties.Stub_only_libs
 	// Unbundled apps will use the prebult one from /prebuilts/sdk
-	if mctx.Config().UnbundledBuildPrebuiltSdks() {
+	if mctx.Config().UnbundledBuildUsePrebuiltSdks() {
 		props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
 	}
 	props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
@@ -612,7 +612,7 @@
 // to satisfy SdkLibraryDependency interface
 func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
 	// This module is just a wrapper for the stubs.
-	if ctx.Config().UnbundledBuildPrebuiltSdks() {
+	if ctx.Config().UnbundledBuildUsePrebuiltSdks() {
 		return module.PrebuiltJars(ctx, sdkVersion)
 	} else {
 		if strings.HasPrefix(sdkVersion, "system_") {
@@ -628,7 +628,7 @@
 // to satisfy SdkLibraryDependency interface
 func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
 	// This module is just a wrapper for the stubs.
-	if ctx.Config().UnbundledBuildPrebuiltSdks() {
+	if ctx.Config().UnbundledBuildUsePrebuiltSdks() {
 		return module.PrebuiltJars(ctx, sdkVersion)
 	} else {
 		if strings.HasPrefix(sdkVersion, "system_") {