Support aconfig stoage files for apex.

Bug: 323071835
Test: unit tests and manual build test.
Change-Id: I4a1a05b3afdf88058a970040b3f176f36c5c8037
diff --git a/aconfig/init.go b/aconfig/init.go
index 16fb0cd..77fb2a7 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -76,6 +76,14 @@
 			},
 		}, "cache_files")
 
+	CreateStorageRule = pctx.AndroidStaticRule("aconfig_create_storage",
+		blueprint.RuleParams{
+			Command: `${aconfig} create-storage --container ${container} --file ${file_type} --out ${out} ${cache_files}`,
+			CommandDeps: []string{
+				"${aconfig}",
+			},
+		}, "container", "file_type", "cache_files")
+
 	// For exported_java_aconfig_library: Generate a JAR from all
 	// java_aconfig_libraries to be consumed by apps built outside the
 	// platform
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 5cc50dd..02dc6e6 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -11115,25 +11115,23 @@
 	mod := ctx.ModuleForTests("myapex", "android_common_myapex")
 	s := mod.Rule("apexRule").Args["copy_commands"]
 	copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
-	if len(copyCmds) != 5 {
+	if len(copyCmds) != 8 {
 		t.Fatalf("Expected 5 commands, got %d in:\n%s", len(copyCmds), s)
 	}
 
 	ensureMatches(t, copyCmds[4], "^cp -f .*/aconfig_flags.pb .*/image.apex$")
+	ensureMatches(t, copyCmds[5], "^cp -f .*/package.map .*/image.apex$")
+	ensureMatches(t, copyCmds[6], "^cp -f .*/flag.map .*/image.apex$")
+	ensureMatches(t, copyCmds[7], "^cp -f .*/flag.val .*/image.apex$")
 
-	combineAconfigRule := mod.Rule("All_aconfig_declarations_dump")
-	s = " " + combineAconfigRule.Args["cache_files"]
-	aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:]
-	if len(aconfigArgs) != 2 {
-		t.Fatalf("Expected 2 commands, got %d in:\n%s", len(aconfigArgs), s)
+	inputs := []string{
+		"my_aconfig_declarations_foo/intermediate.pb",
+		"my_aconfig_declarations_bar/intermediate.pb",
 	}
-	android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb")
-	android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_bar/intermediate.pb")
-
-	buildParams := combineAconfigRule.BuildParams
-	android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb")
-	android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_bar/intermediate.pb")
-	ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb")
+	VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "")
+	VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map")
+	VerifyAconfigRule(t, &mod, "create_aconfig_flag_map_file", inputs, "android_common_myapex/flag.map", "myapex", "flag_map")
+	VerifyAconfigRule(t, &mod, "create_aconfig_flag_val_file", inputs, "android_common_myapex/flag.val", "myapex", "flag_val")
 }
 
 func TestAconfigFilesJavaAndCcDeps(t *testing.T) {
@@ -11241,30 +11239,24 @@
 	mod := ctx.ModuleForTests("myapex", "android_common_myapex")
 	s := mod.Rule("apexRule").Args["copy_commands"]
 	copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
-	if len(copyCmds) != 9 {
-		t.Fatalf("Expected 9 commands, got %d in:\n%s", len(copyCmds), s)
+	if len(copyCmds) != 12 {
+		t.Fatalf("Expected 12 commands, got %d in:\n%s", len(copyCmds), s)
 	}
 
 	ensureMatches(t, copyCmds[8], "^cp -f .*/aconfig_flags.pb .*/image.apex$")
+	ensureMatches(t, copyCmds[9], "^cp -f .*/package.map .*/image.apex$")
+	ensureMatches(t, copyCmds[10], "^cp -f .*/flag.map .*/image.apex$")
+	ensureMatches(t, copyCmds[11], "^cp -f .*/flag.val .*/image.apex$")
 
-	combineAconfigRule := mod.Rule("All_aconfig_declarations_dump")
-	s = " " + combineAconfigRule.Args["cache_files"]
-	aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:]
-	if len(aconfigArgs) != 3 {
-		t.Fatalf("Expected 3 commands, got %d in:\n%s", len(aconfigArgs), s)
+	inputs := []string{
+		"my_aconfig_declarations_foo/intermediate.pb",
+		"my_cc_library_bar/android_arm64_armv8-a_shared_apex10000/myapex/aconfig_merged.pb",
+		"my_aconfig_declarations_baz/intermediate.pb",
 	}
-	android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb")
-	android.EnsureListContainsSuffix(t, aconfigArgs, "my_cc_library_bar/android_arm64_armv8-a_shared_apex10000/myapex/aconfig_merged.pb")
-	android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_baz/intermediate.pb")
-
-	buildParams := combineAconfigRule.BuildParams
-	if len(buildParams.Inputs) != 3 {
-		t.Fatalf("Expected 3 input, got %d", len(buildParams.Inputs))
-	}
-	android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb")
-	android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_cc_library_bar/android_arm64_armv8-a_shared_apex10000/myapex/aconfig_merged.pb")
-	android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_baz/intermediate.pb")
-	ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb")
+	VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "")
+	VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map")
+	VerifyAconfigRule(t, &mod, "create_aconfig_flag_map_file", inputs, "android_common_myapex/flag.map", "myapex", "flag_map")
+	VerifyAconfigRule(t, &mod, "create_aconfig_flag_val_file", inputs, "android_common_myapex/flag.val", "myapex", "flag_val")
 }
 
 func TestAconfigFilesRustDeps(t *testing.T) {
@@ -11388,28 +11380,43 @@
 	mod := ctx.ModuleForTests("myapex", "android_common_myapex")
 	s := mod.Rule("apexRule").Args["copy_commands"]
 	copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
-	if len(copyCmds) != 23 {
-		t.Fatalf("Expected 23 commands, got %d in:\n%s", len(copyCmds), s)
+	if len(copyCmds) != 26 {
+		t.Fatalf("Expected 26 commands, got %d in:\n%s", len(copyCmds), s)
 	}
 
 	ensureMatches(t, copyCmds[22], "^cp -f .*/aconfig_flags.pb .*/image.apex$")
+	ensureMatches(t, copyCmds[23], "^cp -f .*/package.map .*/image.apex$")
+	ensureMatches(t, copyCmds[24], "^cp -f .*/flag.map .*/image.apex$")
+	ensureMatches(t, copyCmds[25], "^cp -f .*/flag.val .*/image.apex$")
 
-	combineAconfigRule := mod.Rule("All_aconfig_declarations_dump")
-	s = " " + combineAconfigRule.Args["cache_files"]
+	inputs := []string{
+		"my_aconfig_declarations_foo/intermediate.pb",
+		"my_rust_binary/android_arm64_armv8-a_apex10000/myapex/aconfig_merged.pb",
+	}
+	VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "")
+	VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map")
+	VerifyAconfigRule(t, &mod, "create_aconfig_flag_map_file", inputs, "android_common_myapex/flag.map", "myapex", "flag_map")
+	VerifyAconfigRule(t, &mod, "create_aconfig_flag_val_file", inputs, "android_common_myapex/flag.val", "myapex", "flag_val")
+}
+
+func VerifyAconfigRule(t *testing.T, mod *android.TestingModule, desc string, inputs []string, output string, container string, file_type string) {
+	aconfigRule := mod.Description(desc)
+	s := " " + aconfigRule.Args["cache_files"]
 	aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:]
-	if len(aconfigArgs) != 2 {
-		t.Fatalf("Expected 2 commands, got %d in:\n%s", len(aconfigArgs), s)
+	if len(aconfigArgs) != len(inputs) {
+		t.Fatalf("Expected %d commands, got %d in:\n%s", len(inputs), len(aconfigArgs), s)
 	}
-	android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb")
-	android.EnsureListContainsSuffix(t, aconfigArgs, "my_rust_binary/android_arm64_armv8-a_apex10000/myapex/aconfig_merged.pb")
 
-	buildParams := combineAconfigRule.BuildParams
-	if len(buildParams.Inputs) != 2 {
-		t.Fatalf("Expected 3 input, got %d", len(buildParams.Inputs))
+	ensureEquals(t, container, aconfigRule.Args["container"])
+	ensureEquals(t, file_type, aconfigRule.Args["file_type"])
+
+	buildParams := aconfigRule.BuildParams
+	for _, input := range inputs {
+		android.EnsureListContainsSuffix(t, aconfigArgs, input)
+		android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), input)
 	}
-	android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb")
-	android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_rust_binary/android_arm64_armv8-a_apex10000/myapex/aconfig_merged.pb")
-	ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb")
+
+	ensureContains(t, buildParams.Output.String(), output)
 }
 
 func TestAconfigFilesOnlyMatchCurrentApex(t *testing.T) {
diff --git a/apex/builder.go b/apex/builder.go
index 3d61219..e49cf28 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -85,6 +85,18 @@
 	pctx.HostBinToolVariable("aconfig", "aconfig")
 }
 
+type createStorageStruct struct {
+	Output_file string
+	Desc        string
+	File_type   string
+}
+
+var createStorageInfo = []createStorageStruct{
+	{"package.map", "create_aconfig_package_map_file", "package_map"},
+	{"flag.map", "create_aconfig_flag_map_file", "flag_map"},
+	{"flag.val", "create_aconfig_flag_val_file", "flag_val"},
+}
+
 var (
 	apexManifestRule = pctx.StaticRule("apexManifestRule", blueprint.RuleParams{
 		Command: `rm -f $out && ${jsonmodify} $in ` +
@@ -648,6 +660,25 @@
 		copyCommands = append(copyCommands, "cp -f "+apexAconfigFile.String()+" "+imageDir.String())
 		implicitInputs = append(implicitInputs, apexAconfigFile)
 		defaultReadOnlyFiles = append(defaultReadOnlyFiles, apexAconfigFile.Base())
+
+		for _, info := range createStorageInfo {
+			outputFile := android.PathForModuleOut(ctx, info.Output_file)
+			ctx.Build(pctx, android.BuildParams{
+				Rule:        aconfig.CreateStorageRule,
+				Inputs:      a.aconfigFiles,
+				Output:      outputFile,
+				Description: info.Desc,
+				Args: map[string]string{
+					"container":   ctx.ModuleName(),
+					"file_type":   info.File_type,
+					"cache_files": android.JoinPathsWithPrefix(a.aconfigFiles, "--cache "),
+				},
+			})
+
+			copyCommands = append(copyCommands, "cp -f "+outputFile.String()+" "+imageDir.String())
+			implicitInputs = append(implicitInputs, outputFile)
+			defaultReadOnlyFiles = append(defaultReadOnlyFiles, outputFile.Base())
+		}
 	}
 
 	////////////////////////////////////////////////////////////////////////////////////