Merge "bootclasspath_fragment: Add hidden API flag files to snapshot"
diff --git a/java/boot_image.go b/java/boot_image.go
index 3c0181f..d0862a9 100644
--- a/java/boot_image.go
+++ b/java/boot_image.go
@@ -16,6 +16,7 @@
 
 import (
 	"fmt"
+	"path/filepath"
 	"strings"
 
 	"android/soong/android"
@@ -326,6 +327,9 @@
 
 	// Contents of the bootclasspath fragment
 	Contents []string
+
+	// Flag files by *hiddenAPIFlagFileCategory
+	Flag_files_by_category map[*hiddenAPIFlagFileCategory]android.Paths
 }
 
 func (b *bootImageSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
@@ -338,6 +342,11 @@
 		// boot image. Therefore, contents property is only copied if the image name is not specified.
 		b.Contents = module.properties.Contents
 	}
+
+	// Get the flag file information from the module.
+	mctx := ctx.SdkModuleContext()
+	flagFileInfo := mctx.OtherModuleProvider(module, hiddenAPIFlagFileInfoProvider).(hiddenAPIFlagFileInfo)
+	b.Flag_files_by_category = flagFileInfo.categoryToPaths
 }
 
 func (b *bootImageSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
@@ -348,6 +357,23 @@
 	if len(b.Contents) > 0 {
 		propertySet.AddPropertyWithTag("contents", b.Contents, ctx.SnapshotBuilder().SdkMemberReferencePropertyTag(true))
 	}
+
+	builder := ctx.SnapshotBuilder()
+	if b.Flag_files_by_category != nil {
+		hiddenAPISet := propertySet.AddPropertySet("hidden_api")
+		for _, category := range hiddenAPIFlagFileCategories {
+			paths := b.Flag_files_by_category[category]
+			if len(paths) > 0 {
+				dests := []string{}
+				for _, p := range paths {
+					dest := filepath.Join("hiddenapi", p.Base())
+					builder.CopyToSnapshot(p, dest)
+					dests = append(dests, dest)
+				}
+				hiddenAPISet.AddProperty(category.propertyName, dests)
+			}
+		}
+	}
 }
 
 var _ android.SdkMemberType = (*bootImageMemberType)(nil)
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index dac09de..0ce4351 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -248,3 +248,108 @@
 	`),
 	).RunTest(t)
 }
+
+func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		prepareForSdkTestWithJava,
+		android.MockFS{
+			"my-blocked.txt":                   nil,
+			"my-max-target-o-low-priority.txt": nil,
+			"my-max-target-p.txt":              nil,
+			"my-max-target-q.txt":              nil,
+			"my-max-target-r-low-priority.txt": nil,
+			"my-removed.txt":                   nil,
+			"my-unsupported-packages.txt":      nil,
+			"my-unsupported.txt":               nil,
+		}.AddToFixture(),
+		android.FixtureWithRootAndroidBp(`
+			sdk {
+				name: "mysdk",
+				bootclasspath_fragments: ["mybootclasspathfragment"],
+				java_boot_libs: ["mybootlib"],
+			}
+
+			bootclasspath_fragment {
+				name: "mybootclasspathfragment",
+				contents: ["mybootlib"],
+				hidden_api: {
+					unsupported: [
+							"my-unsupported.txt",
+					],
+					removed: [
+							"my-removed.txt",
+					],
+					max_target_r_low_priority: [
+							"my-max-target-r-low-priority.txt",
+					],
+					max_target_q: [
+							"my-max-target-q.txt",
+					],
+					max_target_p: [
+							"my-max-target-p.txt",
+					],
+					max_target_o_low_priority: [
+							"my-max-target-o-low-priority.txt",
+					],
+					blocked: [
+							"my-blocked.txt",
+					],
+					unsupported_packages: [
+							"my-unsupported-packages.txt",
+					],
+				},
+			}
+
+			java_library {
+				name: "mybootlib",
+				srcs: ["Test.java"],
+				system_modules: "none",
+				sdk_version: "none",
+				compile_dex: true,
+			}
+		`),
+	).RunTest(t)
+
+	CheckSnapshot(t, result, "mysdk", "",
+		checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+prebuilt_bootclasspath_fragment {
+    name: "mybootclasspathfragment",
+    prefer: false,
+    visibility: ["//visibility:public"],
+    apex_available: ["//apex_available:platform"],
+    contents: ["mybootlib"],
+    hidden_api: {
+        unsupported: ["hiddenapi/my-unsupported.txt"],
+        removed: ["hiddenapi/my-removed.txt"],
+        max_target_r_low_priority: ["hiddenapi/my-max-target-r-low-priority.txt"],
+        max_target_q: ["hiddenapi/my-max-target-q.txt"],
+        max_target_p: ["hiddenapi/my-max-target-p.txt"],
+        max_target_o_low_priority: ["hiddenapi/my-max-target-o-low-priority.txt"],
+        blocked: ["hiddenapi/my-blocked.txt"],
+        unsupported_packages: ["hiddenapi/my-unsupported-packages.txt"],
+    },
+}
+
+java_import {
+    name: "mybootlib",
+    prefer: false,
+    visibility: ["//visibility:public"],
+    apex_available: ["//apex_available:platform"],
+    jars: ["java/mybootlib.jar"],
+}
+`),
+		checkAllCopyRules(`
+my-unsupported.txt -> hiddenapi/my-unsupported.txt
+my-removed.txt -> hiddenapi/my-removed.txt
+my-max-target-r-low-priority.txt -> hiddenapi/my-max-target-r-low-priority.txt
+my-max-target-q.txt -> hiddenapi/my-max-target-q.txt
+my-max-target-p.txt -> hiddenapi/my-max-target-p.txt
+my-max-target-o-low-priority.txt -> hiddenapi/my-max-target-o-low-priority.txt
+my-blocked.txt -> hiddenapi/my-blocked.txt
+my-unsupported-packages.txt -> hiddenapi/my-unsupported-packages.txt
+.intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar
+`),
+	)
+}