Output bootclasspath_fragment's fragments property to sdk snapshot
Adds support for printing a PropertySet that has a property whose value is an array of structs. Bug: 179354495 Test: m nothing m conscrypt-module-sdk - check generated Android.bp file Change-Id: I71be04188465610bcbea4d3c9a5e8204171a1eeb
This commit is contained in:
@@ -300,6 +300,22 @@ type BpModule interface {
|
|||||||
Name() string
|
Name() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BpPrintable is a marker interface that must be implemented by any struct that is added as a
|
||||||
|
// property value.
|
||||||
|
type BpPrintable interface {
|
||||||
|
bpPrintable()
|
||||||
|
}
|
||||||
|
|
||||||
|
// BpPrintableBase must be embedded within any struct that is added as a
|
||||||
|
// property value.
|
||||||
|
type BpPrintableBase struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BpPrintableBase) bpPrintable() {
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ BpPrintable = BpPrintableBase{}
|
||||||
|
|
||||||
// An individual member of the SDK, includes all of the variants that the SDK
|
// An individual member of the SDK, includes all of the variants that the SDK
|
||||||
// requires.
|
// requires.
|
||||||
type SdkMember interface {
|
type SdkMember interface {
|
||||||
|
@@ -144,6 +144,8 @@ func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tag blueprin
|
|||||||
|
|
||||||
// ApexVariantReference specifies a particular apex variant of a module.
|
// ApexVariantReference specifies a particular apex variant of a module.
|
||||||
type ApexVariantReference struct {
|
type ApexVariantReference struct {
|
||||||
|
android.BpPrintableBase
|
||||||
|
|
||||||
// The name of the module apex variant, i.e. the apex containing the module variant.
|
// The name of the module apex variant, i.e. the apex containing the module variant.
|
||||||
//
|
//
|
||||||
// If this is not specified then it defaults to "platform" which will cause a dependency to be
|
// If this is not specified then it defaults to "platform" which will cause a dependency to be
|
||||||
|
@@ -749,6 +749,9 @@ type bootclasspathFragmentSdkMemberProperties struct {
|
|||||||
Stub_libs []string
|
Stub_libs []string
|
||||||
Core_platform_stub_libs []string
|
Core_platform_stub_libs []string
|
||||||
|
|
||||||
|
// Fragment properties
|
||||||
|
Fragments []ApexVariantReference
|
||||||
|
|
||||||
// Flag files by *hiddenAPIFlagFileCategory
|
// Flag files by *hiddenAPIFlagFileCategory
|
||||||
Flag_files_by_category FlagFilesByCategory
|
Flag_files_by_category FlagFilesByCategory
|
||||||
|
|
||||||
@@ -789,6 +792,9 @@ func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx andro
|
|||||||
// Copy stub_libs properties.
|
// Copy stub_libs properties.
|
||||||
b.Stub_libs = module.properties.Api.Stub_libs
|
b.Stub_libs = module.properties.Api.Stub_libs
|
||||||
b.Core_platform_stub_libs = module.properties.Core_platform_api.Stub_libs
|
b.Core_platform_stub_libs = module.properties.Core_platform_api.Stub_libs
|
||||||
|
|
||||||
|
// Copy fragment properties.
|
||||||
|
b.Fragments = module.properties.Fragments
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bootclasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
|
func (b *bootclasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
|
||||||
@@ -811,6 +817,9 @@ func (b *bootclasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.
|
|||||||
corePlatformApiPropertySet := propertySet.AddPropertySet("core_platform_api")
|
corePlatformApiPropertySet := propertySet.AddPropertySet("core_platform_api")
|
||||||
corePlatformApiPropertySet.AddPropertyWithTag("stub_libs", b.Core_platform_stub_libs, requiredMemberDependency)
|
corePlatformApiPropertySet.AddPropertyWithTag("stub_libs", b.Core_platform_stub_libs, requiredMemberDependency)
|
||||||
}
|
}
|
||||||
|
if len(b.Fragments) > 0 {
|
||||||
|
propertySet.AddProperty("fragments", b.Fragments)
|
||||||
|
}
|
||||||
|
|
||||||
hiddenAPISet := propertySet.AddPropertySet("hidden_api")
|
hiddenAPISet := propertySet.AddPropertySet("hidden_api")
|
||||||
hiddenAPIDir := "hiddenapi"
|
hiddenAPIDir := "hiddenapi"
|
||||||
|
@@ -511,6 +511,127 @@ sdk_snapshot {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestSnapshotWithBootClasspathFragment_Fragments makes sure that the fragments property of a
|
||||||
|
// bootclasspath_fragment is correctly output to the sdk snapshot.
|
||||||
|
func TestSnapshotWithBootClasspathFragment_Fragments(t *testing.T) {
|
||||||
|
result := android.GroupFixturePreparers(
|
||||||
|
prepareForSdkTestWithJava,
|
||||||
|
java.PrepareForTestWithJavaDefaultModules,
|
||||||
|
java.PrepareForTestWithJavaSdkLibraryFiles,
|
||||||
|
java.FixtureWithLastReleaseApis("mysdklibrary", "myothersdklibrary"),
|
||||||
|
prepareForSdkTestWithApex,
|
||||||
|
|
||||||
|
// Some additional files needed for the myotherapex.
|
||||||
|
android.FixtureMergeMockFs(android.MockFS{
|
||||||
|
"system/sepolicy/apex/myotherapex-file_contexts": nil,
|
||||||
|
"myotherapex/apex_manifest.json": nil,
|
||||||
|
"myotherapex/Test.java": nil,
|
||||||
|
}),
|
||||||
|
|
||||||
|
android.FixtureAddTextFile("myotherapex/Android.bp", `
|
||||||
|
apex {
|
||||||
|
name: "myotherapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
min_sdk_version: "2",
|
||||||
|
bootclasspath_fragments: ["myotherbootclasspathfragment"],
|
||||||
|
}
|
||||||
|
|
||||||
|
bootclasspath_fragment {
|
||||||
|
name: "myotherbootclasspathfragment",
|
||||||
|
apex_available: ["myotherapex"],
|
||||||
|
contents: [
|
||||||
|
"myotherlib",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_library {
|
||||||
|
name: "myotherlib",
|
||||||
|
apex_available: ["myotherapex"],
|
||||||
|
srcs: ["Test.java"],
|
||||||
|
min_sdk_version: "2",
|
||||||
|
permitted_packages: ["myothersdklibrary"],
|
||||||
|
compile_dex: true,
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
|
||||||
|
android.FixtureWithRootAndroidBp(`
|
||||||
|
sdk {
|
||||||
|
name: "mysdk",
|
||||||
|
bootclasspath_fragments: ["mybootclasspathfragment"],
|
||||||
|
}
|
||||||
|
|
||||||
|
bootclasspath_fragment {
|
||||||
|
name: "mybootclasspathfragment",
|
||||||
|
contents: [
|
||||||
|
"mysdklibrary",
|
||||||
|
],
|
||||||
|
fragments: [
|
||||||
|
{
|
||||||
|
apex: "myotherapex",
|
||||||
|
module: "myotherbootclasspathfragment"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_sdk_library {
|
||||||
|
name: "mysdklibrary",
|
||||||
|
srcs: ["Test.java"],
|
||||||
|
shared_library: false,
|
||||||
|
public: {enabled: true},
|
||||||
|
min_sdk_version: "2",
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
).RunTest(t)
|
||||||
|
|
||||||
|
// A preparer to update the test fixture used when processing an unpackage snapshot.
|
||||||
|
preparerForSnapshot := fixtureAddPrebuiltApexForBootclasspathFragment("myapex", "mybootclasspathfragment")
|
||||||
|
|
||||||
|
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: ["mysdklibrary"],
|
||||||
|
fragments: [
|
||||||
|
{
|
||||||
|
apex: "myotherapex",
|
||||||
|
module: "myotherbootclasspathfragment",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
hidden_api: {
|
||||||
|
stub_flags: "hiddenapi/stub-flags.csv",
|
||||||
|
annotation_flags: "hiddenapi/annotation-flags.csv",
|
||||||
|
metadata: "hiddenapi/metadata.csv",
|
||||||
|
index: "hiddenapi/index.csv",
|
||||||
|
all_flags: "hiddenapi/all-flags.csv",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
java_sdk_library_import {
|
||||||
|
name: "mysdklibrary",
|
||||||
|
prefer: false,
|
||||||
|
visibility: ["//visibility:public"],
|
||||||
|
apex_available: ["//apex_available:platform"],
|
||||||
|
shared_library: false,
|
||||||
|
public: {
|
||||||
|
jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
|
||||||
|
stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
|
||||||
|
current_api: "sdk_library/public/mysdklibrary.txt",
|
||||||
|
removed_api: "sdk_library/public/mysdklibrary-removed.txt",
|
||||||
|
sdk_version: "current",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
snapshotTestPreparer(checkSnapshotWithoutSource, preparerForSnapshot),
|
||||||
|
snapshotTestPreparer(checkSnapshotWithSourcePreferred, preparerForSnapshot),
|
||||||
|
snapshotTestPreparer(checkSnapshotPreferredWithSource, preparerForSnapshot),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Test that bootclasspath_fragment works with sdk.
|
// Test that bootclasspath_fragment works with sdk.
|
||||||
func TestBasicSdkWithBootclasspathFragment(t *testing.T) {
|
func TestBasicSdkWithBootclasspathFragment(t *testing.T) {
|
||||||
android.GroupFixturePreparers(
|
android.GroupFixturePreparers(
|
||||||
|
@@ -824,13 +824,18 @@ func outputUnnamedValue(contents *generatedContents, value reflect.Value) {
|
|||||||
case reflect.String:
|
case reflect.String:
|
||||||
contents.UnindentedPrintf("%q", value)
|
contents.UnindentedPrintf("%q", value)
|
||||||
|
|
||||||
|
case reflect.Ptr:
|
||||||
|
outputUnnamedValue(contents, value.Elem())
|
||||||
|
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
length := value.Len()
|
length := value.Len()
|
||||||
if length == 0 {
|
if length == 0 {
|
||||||
contents.UnindentedPrintf("[]")
|
contents.UnindentedPrintf("[]")
|
||||||
} else if length == 1 {
|
} else {
|
||||||
|
firstValue := value.Index(0)
|
||||||
|
if length == 1 && !multiLineValue(firstValue) {
|
||||||
contents.UnindentedPrintf("[")
|
contents.UnindentedPrintf("[")
|
||||||
outputUnnamedValue(contents, value.Index(0))
|
outputUnnamedValue(contents, firstValue)
|
||||||
contents.UnindentedPrintf("]")
|
contents.UnindentedPrintf("]")
|
||||||
} else {
|
} else {
|
||||||
contents.UnindentedPrintf("[\n")
|
contents.UnindentedPrintf("[\n")
|
||||||
@@ -844,12 +849,40 @@ func outputUnnamedValue(contents *generatedContents, value reflect.Value) {
|
|||||||
contents.Dedent()
|
contents.Dedent()
|
||||||
contents.IndentedPrintf("]")
|
contents.IndentedPrintf("]")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Struct:
|
||||||
|
// Avoid unlimited recursion by requiring every structure to implement android.BpPrintable.
|
||||||
|
v := value.Interface()
|
||||||
|
if _, ok := v.(android.BpPrintable); !ok {
|
||||||
|
panic(fmt.Errorf("property value %#v of type %T does not implement android.BpPrintable", v, v))
|
||||||
|
}
|
||||||
|
contents.UnindentedPrintf("{\n")
|
||||||
|
contents.Indent()
|
||||||
|
for f := 0; f < valueType.NumField(); f++ {
|
||||||
|
fieldType := valueType.Field(f)
|
||||||
|
if fieldType.Anonymous {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fieldValue := value.Field(f)
|
||||||
|
fieldName := fieldType.Name
|
||||||
|
propertyName := proptools.PropertyNameForField(fieldName)
|
||||||
|
outputNamedValue(contents, propertyName, fieldValue)
|
||||||
|
}
|
||||||
|
contents.Dedent()
|
||||||
|
contents.IndentedPrintf("}")
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("Unknown type: %T of value %#v", value, value))
|
panic(fmt.Errorf("Unknown type: %T of value %#v", value, value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// multiLineValue returns true if the supplied value may require multiple lines in the output.
|
||||||
|
func multiLineValue(value reflect.Value) bool {
|
||||||
|
kind := value.Kind()
|
||||||
|
return kind == reflect.Slice || kind == reflect.Struct
|
||||||
|
}
|
||||||
|
|
||||||
func (s *sdk) GetAndroidBpContentsForTests() string {
|
func (s *sdk) GetAndroidBpContentsForTests() string {
|
||||||
contents := &generatedContents{}
|
contents := &generatedContents{}
|
||||||
generateBpContents(contents, s.builderForTests.bpFile)
|
generateBpContents(contents, s.builderForTests.bpFile)
|
||||||
|
Reference in New Issue
Block a user