add manifest_values application id property to soong

Bug:278905106
Test: go test ./java --run TestManifestValuesApplicationIdSetsPackageName
	and locally built a module and checked manifest pacakge_name
Change-Id: I5c8fd27c177b9e255dce197706f62580894008cb
diff --git a/java/aar.go b/java/aar.go
index 479b5e0..713feee 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -134,6 +134,10 @@
 	resourcesNodesDepSet *android.DepSet[*resourcesNode]
 	rroDirsDepSet        *android.DepSet[rroDir]
 	manifestsDepSet      *android.DepSet[android.Path]
+
+	manifestValues struct {
+		applicationId string
+	}
 }
 
 type split struct {
@@ -380,7 +384,9 @@
 	if len(transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) {
 		manifestMergerParams := ManifestMergerParams{
 			staticLibManifests: transitiveManifestPaths[1:],
-			isLibrary:          a.isLibrary}
+			isLibrary:          a.isLibrary,
+			packageName:        a.manifestValues.applicationId,
+		}
 		a.mergedManifestFile = manifestMerger(ctx, transitiveManifestPaths[0], manifestMergerParams)
 		if !a.isLibrary {
 			// Only use the merged manifest for applications.  For libraries, the transitive closure of manifests
diff --git a/java/android_manifest.go b/java/android_manifest.go
index a39c002..082b00e 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -203,15 +203,21 @@
 type ManifestMergerParams struct {
 	staticLibManifests android.Paths
 	isLibrary          bool
+	packageName        string
 }
 
 func manifestMerger(ctx android.ModuleContext, manifest android.Path,
 	params ManifestMergerParams) android.Path {
 
-	var args string
+	var args []string
 	if !params.isLibrary {
 		// Follow Gradle's behavior, only pass --remove-tools-declarations when merging app manifests.
-		args = "--remove-tools-declarations"
+		args = append(args, "--remove-tools-declarations")
+	}
+
+	packageName := params.packageName
+	if packageName != "" {
+		args = append(args, "--property PACKAGE="+packageName)
 	}
 
 	mergedManifest := android.PathForModuleOut(ctx, "manifest_merger", "AndroidManifest.xml")
@@ -223,7 +229,7 @@
 		Output:      mergedManifest,
 		Args: map[string]string{
 			"libs": android.JoinWithPrefix(params.staticLibManifests.Strings(), "--libs "),
-			"args": args,
+			"args": strings.Join(args, " "),
 		},
 	})
 
diff --git a/java/android_manifest_test.go b/java/android_manifest_test.go
index b12d778..0a39dca 100644
--- a/java/android_manifest_test.go
+++ b/java/android_manifest_test.go
@@ -15,8 +15,9 @@
 package java
 
 import (
-	"android/soong/android"
 	"testing"
+
+	"android/soong/android"
 )
 
 func TestManifestMerger(t *testing.T) {
@@ -101,3 +102,41 @@
 		},
 		manifestMergerRule.Implicits)
 }
+
+func TestManifestValuesApplicationIdSetsPackageName(t *testing.T) {
+	bp := `
+		android_test {
+			name: "test",
+			sdk_version: "current",
+			srcs: ["app/app.java"],
+			manifest: "test/AndroidManifest.xml",
+			additional_manifests: ["test/AndroidManifest2.xml"],
+			static_libs: ["direct"],
+      test_suites: ["device-tests"],
+      manifest_values:  {
+        applicationId: "new_package_name"
+      },
+		}
+
+		android_library {
+			name: "direct",
+			sdk_version: "current",
+			srcs: ["direct/direct.java"],
+			resource_dirs: ["direct/res"],
+			manifest: "direct/AndroidManifest.xml",
+			additional_manifests: ["direct/AndroidManifest2.xml"],
+		}
+
+	`
+
+	result := android.GroupFixturePreparers(
+		PrepareForTestWithJavaDefaultModules,
+		PrepareForTestWithOverlayBuildComponents,
+	).RunTestWithBp(t, bp)
+
+	manifestMergerRule := result.ModuleForTests("test", "android_common").Rule("manifestMerger")
+	android.AssertStringMatches(t,
+		"manifest merger args",
+		manifestMergerRule.Args["args"],
+		"--property PACKAGE=new_package_name")
+}
diff --git a/java/app.go b/java/app.go
index 0cb72e2..7b9e6bb 100755
--- a/java/app.go
+++ b/java/app.go
@@ -308,6 +308,13 @@
 }
 
 func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	applicationId := a.appTestHelperAppProperties.Manifest_values.ApplicationId
+	if applicationId != nil {
+		if a.overridableAppProperties.Package_name != nil {
+			ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
+		}
+		a.aapt.manifestValues.applicationId = *applicationId
+	}
 	a.generateAndroidBuildActions(ctx)
 }
 
@@ -1107,6 +1114,12 @@
 	return module
 }
 
+// A dictionary of values to be overridden in the manifest.
+type Manifest_values struct {
+	// Overrides the value of package_name in the manifest
+	ApplicationId *string
+}
+
 type appTestProperties struct {
 	// The name of the android_app module that the tests will run against.
 	Instrumentation_for *string
@@ -1116,6 +1129,8 @@
 
 	// If specified, the mainline module package name in the test config is overwritten by it.
 	Mainline_package_name *string
+
+	Manifest_values Manifest_values
 }
 
 type AndroidTest struct {
@@ -1160,6 +1175,13 @@
 			a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
 		}
 	}
+	applicationId := a.appTestProperties.Manifest_values.ApplicationId
+	if applicationId != nil {
+		if a.overridableAppProperties.Package_name != nil {
+			ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
+		}
+		a.aapt.manifestValues.applicationId = *applicationId
+	}
 	a.generateAndroidBuildActions(ctx)
 
 	for _, module := range a.testProperties.Test_mainline_modules {
@@ -1264,6 +1286,8 @@
 
 	// Install the test into a folder named for the module in all test suites.
 	Per_testcase_directory *bool
+
+	Manifest_values Manifest_values
 }
 
 type AndroidTestHelperApp struct {