소스 검색

Add hidden API properties to java_sdk_library modules

Previously, hidden API properties were only allowed on
bootclasspath_fragment and platform_bootclasspath module types. This
change allows them to be specified on java_sdk_library modules too. It
involves the following changes:

1. Add the properties to the java.Module.
2. Populate and provide a HiddenAPIPropertyInfo struct from
   java_sdk_library modules.
3. Modify bootclasspath_fragment to merge information gathered from its
   content libraries as if it was specified on the fragment itself.

Bug: 240406019
Test: m nothing
      packages/modules/common/build/mainline_modules_sdks.sh
      # Ran the previous command with and without this change to make
      # sure that this change does not change the sdk snapshot
      # contents.
Change-Id: I64eb71c2039ddc14cf380689d0cec7ec221f5b88
Paul Duffin 1 년 전
부모
커밋
3f1ae0b55a
6개의 변경된 파일230개의 추가작업 그리고 8개의 파일을 삭제
  1. 17 0
      java/base.go
  2. 2 0
      java/bootclasspath_fragment.go
  3. 114 0
      java/bootclasspath_fragment_test.go
  4. 40 2
      java/hiddenapi_modular.go
  5. 3 0
      java/java.go
  6. 54 6
      sdk/bootclasspath_fragment_sdk_test.go

+ 17 - 0
java/base.go

@@ -267,6 +267,9 @@ type DeviceProperties struct {
 	// Only for libraries created by a sysprop_library module, SyspropPublicStub is the name of the
 	// public stubs library.
 	SyspropPublicStub string `blueprint:"mutated"`
+
+	HiddenAPIPackageProperties
+	HiddenAPIFlagFileProperties
 }
 
 // Device properties that can be overridden by overriding module (e.g. override_android_app)
@@ -564,6 +567,20 @@ func (j *Module) addHostAndDeviceProperties() {
 	)
 }
 
+// provideHiddenAPIPropertyInfo populates a HiddenAPIPropertyInfo from hidden API properties and
+// makes it available through the hiddenAPIPropertyInfoProvider.
+func (j *Module) provideHiddenAPIPropertyInfo(ctx android.ModuleContext) {
+	hiddenAPIInfo := newHiddenAPIPropertyInfo()
+
+	// Populate with flag file paths from the properties.
+	hiddenAPIInfo.extractFlagFilesFromProperties(ctx, &j.deviceProperties.HiddenAPIFlagFileProperties)
+
+	// Populate with package rules from the properties.
+	hiddenAPIInfo.extractPackageRulesFromProperties(&j.deviceProperties.HiddenAPIPackageProperties)
+
+	ctx.SetProvider(hiddenAPIPropertyInfoProvider, hiddenAPIInfo)
+}
+
 func (j *Module) OutputFiles(tag string) (android.Paths, error) {
 	switch tag {
 	case "":

+ 2 - 0
java/bootclasspath_fragment.go

@@ -830,6 +830,8 @@ func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.Modul
 	// Populate with package rules from the properties.
 	input.extractPackageRulesFromProperties(&b.sourceOnlyProperties.HiddenAPIPackageProperties)
 
+	input.gatherPropertyInfo(ctx, contents)
+
 	// Add the stub dex jars from this module's fragment dependencies.
 	input.DependencyStubDexJarsByScope.addStubDexJarsByModule(dependencyHiddenApiInfo.TransitiveStubDexJarsByScope)
 

+ 114 - 0
java/bootclasspath_fragment_test.go

@@ -15,6 +15,7 @@
 package java
 
 import (
+	"strings"
 	"testing"
 
 	"android/soong/android"
@@ -285,6 +286,119 @@ func TestBootclasspathFragment_StubLibs(t *testing.T) {
 	android.AssertPathsRelativeToTopEquals(t, "widest dex stubs jar", expectedWidestPaths, info.TransitiveStubDexJarsByScope.StubDexJarsForWidestAPIScope())
 }
 
+func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		prepareForTestWithBootclasspathFragment,
+		PrepareForTestWithJavaSdkLibraryFiles,
+		FixtureWithLastReleaseApis("mysdklibrary", "mynewlibrary"),
+		FixtureConfigureApexBootJars("myapex:mybootlib", "myapex:mynewlibrary"),
+		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,
+			"my-new-max-target-q.txt":          nil,
+		}.AddToFixture(),
+		android.FixtureWithRootAndroidBp(`
+			bootclasspath_fragment {
+				name: "mybootclasspathfragment",
+				apex_available: ["myapex"],
+				contents: ["mybootlib", "mynewlibrary"],
+				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",
+					],
+					split_packages: ["sdklibrary"],
+					package_prefixes: ["sdklibrary.all.mine"],
+					single_packages: ["sdklibrary.mine"],
+				},
+			}
+
+			java_library {
+				name: "mybootlib",
+				apex_available: ["myapex"],
+				srcs: ["Test.java"],
+				system_modules: "none",
+				sdk_version: "none",
+				min_sdk_version: "1",
+				compile_dex: true,
+				permitted_packages: ["mybootlib"],
+			}
+
+			java_sdk_library {
+				name: "mynewlibrary",
+				apex_available: ["myapex"],
+				srcs: ["Test.java"],
+				min_sdk_version: "10",
+				compile_dex: true,
+				public: {enabled: true},
+				permitted_packages: ["mysdklibrary"],
+				hidden_api: {
+					max_target_q: [
+							"my-new-max-target-q.txt",
+					],
+					split_packages: ["sdklibrary", "newlibrary"],
+					package_prefixes: ["newlibrary.all.mine"],
+					single_packages: ["newlibrary.mine"],
+				},
+			}
+		`),
+	).RunTest(t)
+
+	// Make sure that the library exports hidden API properties for use by the bootclasspath_fragment.
+	library := result.Module("mynewlibrary", "android_common")
+	info := result.ModuleProvider(library, hiddenAPIPropertyInfoProvider).(HiddenAPIPropertyInfo)
+	android.AssertArrayString(t, "split packages", []string{"sdklibrary", "newlibrary"}, info.SplitPackages)
+	android.AssertArrayString(t, "package prefixes", []string{"newlibrary.all.mine"}, info.PackagePrefixes)
+	android.AssertArrayString(t, "single packages", []string{"newlibrary.mine"}, info.SinglePackages)
+	for _, c := range HiddenAPIFlagFileCategories {
+		expectedMaxTargetQPaths := []string(nil)
+		if c.PropertyName == "max_target_q" {
+			expectedMaxTargetQPaths = []string{"my-new-max-target-q.txt"}
+		}
+		android.AssertPathsRelativeToTopEquals(t, c.PropertyName, expectedMaxTargetQPaths, info.FlagFilesByCategory[c])
+	}
+
+	// Make sure that the signature-patterns.csv is passed all the appropriate package properties
+	// from the bootclasspath_fragment and its contents.
+	fragment := result.ModuleForTests("mybootclasspathfragment", "android_common")
+	rule := fragment.Output("modular-hiddenapi/signature-patterns.csv")
+	expectedCommand := strings.Join([]string{
+		"--split-package newlibrary",
+		"--split-package sdklibrary",
+		"--package-prefix newlibrary.all.mine",
+		"--package-prefix sdklibrary.all.mine",
+		"--single-package newlibrary.mine",
+		"--single-package sdklibrary",
+	}, " ")
+	android.AssertStringDoesContain(t, "signature patterns command", rule.RuleParams.Command, expectedCommand)
+}
+
 func TestBootclasspathFragment_Test(t *testing.T) {
 	result := android.GroupFixturePreparers(
 		prepareForTestWithBootclasspathFragment,

+ 40 - 2
java/hiddenapi_modular.go

@@ -440,7 +440,18 @@ var hiddenAPIRemovedFlagFileCategory = &hiddenAPIFlagFileCategory{
 	},
 }
 
-var HiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
+type hiddenAPIFlagFileCategories []*hiddenAPIFlagFileCategory
+
+func (c hiddenAPIFlagFileCategories) byProperty(name string) *hiddenAPIFlagFileCategory {
+	for _, category := range c {
+		if category.PropertyName == name {
+			return category
+		}
+	}
+	panic(fmt.Errorf("no category exists with property name %q in %v", name, c))
+}
+
+var HiddenAPIFlagFileCategories = hiddenAPIFlagFileCategories{
 	// See HiddenAPIFlagFileProperties.Unsupported
 	{
 		PropertyName: "unsupported",
@@ -517,13 +528,20 @@ var HiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
 // FlagFilesByCategory maps a hiddenAPIFlagFileCategory to the paths to the files in that category.
 type FlagFilesByCategory map[*hiddenAPIFlagFileCategory]android.Paths
 
-// append appends the supplied flags files to the corresponding category in this map.
+// append the supplied flags files to the corresponding category in this map.
 func (s FlagFilesByCategory) append(other FlagFilesByCategory) {
 	for _, category := range HiddenAPIFlagFileCategories {
 		s[category] = append(s[category], other[category]...)
 	}
 }
 
+// sort the paths for each category in this map.
+func (s FlagFilesByCategory) sort() {
+	for category, value := range s {
+		s[category] = android.SortedUniquePaths(value)
+	}
+}
+
 // HiddenAPIInfo contains information provided by the hidden API processing.
 //
 // That includes paths resolved from HiddenAPIFlagFileProperties and also generated by hidden API
@@ -706,6 +724,8 @@ type HiddenAPIPropertyInfo struct {
 	SplitPackages []string
 }
 
+var hiddenAPIPropertyInfoProvider = blueprint.NewProvider(HiddenAPIPropertyInfo{})
+
 // newHiddenAPIPropertyInfo creates a new initialized HiddenAPIPropertyInfo struct.
 func newHiddenAPIPropertyInfo() HiddenAPIPropertyInfo {
 	return HiddenAPIPropertyInfo{
@@ -730,6 +750,24 @@ func (i *HiddenAPIPropertyInfo) extractPackageRulesFromProperties(p *HiddenAPIPa
 	i.SplitPackages = p.Hidden_api.Split_packages
 }
 
+func (i *HiddenAPIPropertyInfo) gatherPropertyInfo(ctx android.ModuleContext, contents []android.Module) {
+	for _, module := range contents {
+		if ctx.OtherModuleHasProvider(module, hiddenAPIPropertyInfoProvider) {
+			info := ctx.OtherModuleProvider(module, hiddenAPIPropertyInfoProvider).(HiddenAPIPropertyInfo)
+			i.FlagFilesByCategory.append(info.FlagFilesByCategory)
+			i.PackagePrefixes = append(i.PackagePrefixes, info.PackagePrefixes...)
+			i.SinglePackages = append(i.SinglePackages, info.SinglePackages...)
+			i.SplitPackages = append(i.SplitPackages, info.SplitPackages...)
+		}
+	}
+
+	// Dedup and sort the information to ensure consistent builds.
+	i.FlagFilesByCategory.sort()
+	i.PackagePrefixes = android.SortedUniqueStrings(i.PackagePrefixes)
+	i.SinglePackages = android.SortedUniqueStrings(i.SinglePackages)
+	i.SplitPackages = android.SortedUniqueStrings(i.SplitPackages)
+}
+
 // HiddenAPIFlagInput encapsulates information obtained from a module and its dependencies that are
 // needed for hidden API flag generation.
 type HiddenAPIFlagInput struct {

+ 3 - 0
java/java.go

@@ -629,6 +629,9 @@ func setUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter, dexer
 }
 
 func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+
+	j.provideHiddenAPIPropertyInfo(ctx)
+
 	j.sdkVersion = j.SdkVersion(ctx)
 	j.minSdkVersion = j.MinSdkVersion(ctx)
 	j.maxSdkVersion = j.MaxSdkVersion(ctx)

+ 54 - 6
sdk/bootclasspath_fragment_sdk_test.go

@@ -675,8 +675,8 @@ func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) {
 		prepareForSdkTestWithJava,
 		java.PrepareForTestWithJavaDefaultModules,
 		java.PrepareForTestWithJavaSdkLibraryFiles,
-		java.FixtureWithLastReleaseApis("mysdklibrary"),
-		java.FixtureConfigureApexBootJars("myapex:mybootlib"),
+		java.FixtureWithLastReleaseApis("mysdklibrary", "mynewlibrary"),
+		java.FixtureConfigureApexBootJars("myapex:mybootlib", "myapex:mynewlibrary"),
 		prepareForSdkTestWithApex,
 
 		// Add a platform_bootclasspath that depends on the fragment.
@@ -691,6 +691,7 @@ func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) {
 			"my-removed.txt":                   nil,
 			"my-unsupported-packages.txt":      nil,
 			"my-unsupported.txt":               nil,
+			"my-new-max-target-q.txt":          nil,
 		}.AddToFixture(),
 		android.FixtureWithRootAndroidBp(`
 			sdk {
@@ -708,7 +709,7 @@ func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) {
 			bootclasspath_fragment {
 				name: "mybootclasspathfragment",
 				apex_available: ["myapex"],
-				contents: ["mybootlib"],
+				contents: ["mybootlib", "mynewlibrary"],
 				api: {
 					stub_libs: ["mysdklibrary"],
 				},
@@ -737,7 +738,9 @@ func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) {
 					unsupported_packages: [
 							"my-unsupported-packages.txt",
 					],
-					split_packages: ["*"],
+					split_packages: ["sdklibrary"],
+					package_prefixes: ["sdklibrary.all.mine"],
+					single_packages: ["sdklibrary.mine"],
 				},
 			}
 
@@ -759,6 +762,24 @@ func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) {
 				public: {enabled: true},
 				permitted_packages: ["mysdklibrary"],
 			}
+
+			java_sdk_library {
+				name: "mynewlibrary",
+				apex_available: ["myapex"],
+				srcs: ["Test.java"],
+				min_sdk_version: "10",
+				compile_dex: true,
+				public: {enabled: true},
+				permitted_packages: ["mysdklibrary"],
+				hidden_api: {
+					max_target_q: [
+							"my-new-max-target-q.txt",
+					],
+					split_packages: ["sdklibrary", "newlibrary"],
+					package_prefixes: ["newlibrary.all.mine"],
+					single_packages: ["newlibrary.mine"],
+				},
+			}
 		`),
 	).RunTest(t)
 
@@ -774,7 +795,10 @@ prebuilt_bootclasspath_fragment {
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["myapex"],
-    contents: ["mybootlib"],
+    contents: [
+        "mybootlib",
+        "mynewlibrary",
+    ],
     api: {
         stub_libs: ["mysdklibrary"],
     },
@@ -782,7 +806,10 @@ prebuilt_bootclasspath_fragment {
         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_q: [
+            "hiddenapi/my-max-target-q.txt",
+            "hiddenapi/my-new-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"],
@@ -805,6 +832,23 @@ java_import {
     permitted_packages: ["mybootlib"],
 }
 
+java_sdk_library_import {
+    name: "mynewlibrary",
+    prefer: false,
+    visibility: ["//visibility:public"],
+    apex_available: ["myapex"],
+    shared_library: true,
+    compile_dex: true,
+    permitted_packages: ["mysdklibrary"],
+    public: {
+        jars: ["sdk_library/public/mynewlibrary-stubs.jar"],
+        stub_srcs: ["sdk_library/public/mynewlibrary_stub_sources"],
+        current_api: "sdk_library/public/mynewlibrary.txt",
+        removed_api: "sdk_library/public/mynewlibrary-removed.txt",
+        sdk_version: "current",
+    },
+}
+
 java_sdk_library_import {
     name: "mysdklibrary",
     prefer: false,
@@ -827,6 +871,7 @@ 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-new-max-target-q.txt -> hiddenapi/my-new-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
@@ -838,6 +883,9 @@ my-unsupported-packages.txt -> hiddenapi/my-unsupported-packages.txt
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
 .intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar
+.intermediates/mynewlibrary.stubs/android_common/javac/mynewlibrary.stubs.jar -> sdk_library/public/mynewlibrary-stubs.jar
+.intermediates/mynewlibrary.stubs.source/android_common/metalava/mynewlibrary.stubs.source_api.txt -> sdk_library/public/mynewlibrary.txt
+.intermediates/mynewlibrary.stubs.source/android_common/metalava/mynewlibrary.stubs.source_removed.txt -> sdk_library/public/mynewlibrary-removed.txt
 .intermediates/mysdklibrary.stubs/android_common/javac/mysdklibrary.stubs.jar -> sdk_library/public/mysdklibrary-stubs.jar
 .intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt
 .intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt