diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go index 79d3c26e3..0737e5e2f 100644 --- a/sdk/java_sdk_test.go +++ b/sdk/java_sdk_test.go @@ -588,12 +588,13 @@ func TestSnapshotWithJavaSystemModules(t *testing.T) { result := testSdkWithJava(t, ` sdk { name: "mysdk", + java_header_libs: ["exported-system-module"], java_system_modules: ["my-system-modules"], } java_system_modules { name: "my-system-modules", - libs: ["system-module"], + libs: ["system-module", "exported-system-module"], } java_library { @@ -602,42 +603,73 @@ func TestSnapshotWithJavaSystemModules(t *testing.T) { sdk_version: "none", system_modules: "none", } + + java_library { + name: "exported-system-module", + srcs: ["Test.java"], + sdk_version: "none", + system_modules: "none", + } `) result.CheckSnapshot("mysdk", "android_common", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. +java_import { + name: "mysdk_exported-system-module@current", + sdk_member_name: "exported-system-module", + jars: ["java/exported-system-module.jar"], +} + +java_import { + name: "exported-system-module", + prefer: false, + jars: ["java/exported-system-module.jar"], +} + java_import { name: "mysdk_system-module@current", sdk_member_name: "system-module", + visibility: ["//visibility:private"], jars: ["java/system-module.jar"], } java_import { - name: "system-module", + name: "mysdk_system-module", prefer: false, + visibility: ["//visibility:private"], jars: ["java/system-module.jar"], } java_system_modules_import { name: "mysdk_my-system-modules@current", sdk_member_name: "my-system-modules", - libs: ["mysdk_system-module@current"], + libs: [ + "mysdk_system-module@current", + "mysdk_exported-system-module@current", + ], } java_system_modules_import { name: "my-system-modules", prefer: false, - libs: ["system-module"], + libs: [ + "mysdk_system-module", + "exported-system-module", + ], } sdk_snapshot { name: "mysdk@current", + java_header_libs: ["mysdk_exported-system-module@current"], java_system_modules: ["mysdk_my-system-modules@current"], } `), - checkAllCopyRules(".intermediates/system-module/android_common/turbine-combined/system-module.jar -> java/system-module.jar"), + checkAllCopyRules(` +.intermediates/exported-system-module/android_common/turbine-combined/exported-system-module.jar -> java/exported-system-module.jar +.intermediates/system-module/android_common/turbine-combined/system-module.jar -> java/system-module.jar +`), ) } @@ -677,14 +709,16 @@ func TestHostSnapshotWithJavaSystemModules(t *testing.T) { java_import { name: "mysdk_system-module@current", sdk_member_name: "system-module", + visibility: ["//visibility:private"], device_supported: false, host_supported: true, jars: ["java/system-module.jar"], } java_import { - name: "system-module", + name: "mysdk_system-module", prefer: false, + visibility: ["//visibility:private"], device_supported: false, host_supported: true, jars: ["java/system-module.jar"], @@ -703,7 +737,7 @@ java_system_modules_import { prefer: false, device_supported: false, host_supported: true, - libs: ["system-module"], + libs: ["mysdk_system-module"], } sdk_snapshot { diff --git a/sdk/sdk.go b/sdk/sdk.go index f22763c10..dbe9ce223 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -50,6 +50,9 @@ type sdk struct { // list properties, e.g. java_libs. dynamicMemberTypeListProperties interface{} + // The set of exported members. + exportedMembers map[string]struct{} + properties sdkProperties snapshotFile android.OptionalPath @@ -217,6 +220,33 @@ func SnapshotModuleFactory() android.Module { return s } +func (s *sdk) memberListProperties() []*sdkMemberListProperty { + return s.dynamicSdkMemberTypes.memberListProperties +} + +func (s *sdk) getExportedMembers() map[string]struct{} { + if s.exportedMembers == nil { + // Collect all the exported members. + s.exportedMembers = make(map[string]struct{}) + + for _, memberListProperty := range s.memberListProperties() { + names := memberListProperty.getter(s.dynamicMemberTypeListProperties) + + // Every member specified explicitly in the properties is exported by the sdk. + for _, name := range names { + s.exportedMembers[name] = struct{}{} + } + } + } + + return s.exportedMembers +} + +func (s *sdk) isInternalMember(memberName string) bool { + _, ok := s.getExportedMembers()[memberName] + return !ok +} + func (s *sdk) snapshot() bool { return s.properties.Snapshot } @@ -290,7 +320,7 @@ func (t sdkMemberVersionedDepTag) ExcludeFromVisibilityEnforcement() {} // Step 1: create dependencies from an SDK module to its members. func memberMutator(mctx android.BottomUpMutatorContext) { if s, ok := mctx.Module().(*sdk); ok { - for _, memberListProperty := range s.dynamicSdkMemberTypes.memberListProperties { + for _, memberListProperty := range s.memberListProperties() { names := memberListProperty.getter(s.dynamicMemberTypeListProperties) tag := memberListProperty.dependencyTag memberListProperty.memberType.AddDependencies(mctx, tag, names) diff --git a/sdk/update.go b/sdk/update.go index 9032d1fb8..ff567be61 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -130,7 +130,9 @@ func (s *sdk) collectMembers(ctx android.ModuleContext) []*sdkMember { byType[memberType] = append(byType[memberType], member) } - member.variants = append(member.variants, child.(android.SdkAware)) + // Only append new variants to the list. This is needed because a member can be both + // exported by the sdk and also be a transitive sdk member. + member.variants = appendUniqueVariants(member.variants, child.(android.SdkAware)) // If the member type supports transitive sdk members then recurse down into // its dependencies, otherwise exit traversal. @@ -141,7 +143,7 @@ func (s *sdk) collectMembers(ctx android.ModuleContext) []*sdkMember { }) var members []*sdkMember - for _, memberListProperty := range s.dynamicSdkMemberTypes.memberListProperties { + for _, memberListProperty := range s.memberListProperties() { membersOfType := byType[memberListProperty.memberType] members = append(members, membersOfType...) } @@ -149,6 +151,15 @@ func (s *sdk) collectMembers(ctx android.ModuleContext) []*sdkMember { return members } +func appendUniqueVariants(variants []android.SdkAware, newVariant android.SdkAware) []android.SdkAware { + for _, v := range variants { + if v == newVariant { + return variants + } + } + return append(variants, newVariant) +} + // SDK directory structure // / // Android.bp : definition of a 'sdk' module is here. This is a hand-made one. @@ -203,17 +214,20 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath { // Create a transformer that will transform an unversioned module into a versioned module. unversionedToVersionedTransformer := unversionedToVersionedTransformation{builder: builder} + // Create a transformer that will transform an unversioned module by replacing any references + // to internal members with a unique module name and setting prefer: false. + unversionedTransformer := unversionedTransformation{builder: builder} + for _, unversioned := range builder.prebuiltOrder { // Copy the unversioned module so it can be modified to make it versioned. versioned := unversioned.deepCopy() // Transform the unversioned module into a versioned one. versioned.transform(unversionedToVersionedTransformer) - bpFile.AddModule(versioned) - // Set prefer: false - this is not strictly required as that is the default. - unversioned.insertAfter("name", "prefer", false) + // Transform the unversioned module to make it suitable for use in the snapshot. + unversioned.transform(unversionedTransformer) bpFile.AddModule(unversioned) } @@ -235,7 +249,7 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath { } addHostDeviceSupportedProperties(&s.ModuleBase, snapshotModule) - for _, memberListProperty := range s.dynamicSdkMemberTypes.memberListProperties { + for _, memberListProperty := range s.memberListProperties() { names := memberListProperty.getter(s.dynamicMemberTypeListProperties) if len(names) > 0 { snapshotModule.AddProperty(memberListProperty.propertyName(), builder.versionedSdkMemberNames(names)) @@ -319,6 +333,30 @@ func (t unversionedToVersionedTransformation) transformProperty(name string, val } } +type unversionedTransformation struct { + identityTransformation + builder *snapshotBuilder +} + +func (t unversionedTransformation) transformModule(module *bpModule) *bpModule { + // If the module is an internal member then use a unique name for it. + name := module.getValue("name").(string) + module.setProperty("name", t.builder.unversionedSdkMemberName(name)) + + // Set prefer: false - this is not strictly required as that is the default. + module.insertAfter("name", "prefer", false) + + return module +} + +func (t unversionedTransformation) transformProperty(name string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) { + if tag == sdkMemberReferencePropertyTag { + return t.builder.unversionedSdkMemberNames(value.([]string)), tag + } else { + return value, tag + } +} + func generateBpContents(contents *generatedContents, bpFile *bpFile) { contents.Printfln("// This is auto-generated. DO NOT EDIT.") for _, bpModule := range bpFile.order { @@ -442,11 +480,17 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType m := s.bpFile.newModule(moduleType) m.AddProperty("name", name) - // Extract visibility information from a member variant. All variants have the same - // visibility so it doesn't matter which one is used. - visibility := android.EffectiveVisibilityRules(s.ctx, member.Variants()[0]) - if len(visibility) != 0 { - m.AddProperty("visibility", visibility) + if s.sdk.isInternalMember(name) { + // An internal member is only referenced from the sdk snapshot which is in the + // same package so can be marked as private. + m.AddProperty("visibility", []string{"//visibility:private"}) + } else { + // Extract visibility information from a member variant. All variants have the same + // visibility so it doesn't matter which one is used. + visibility := android.EffectiveVisibilityRules(s.ctx, member.Variants()[0]) + if len(visibility) != 0 { + m.AddProperty("visibility", visibility) + } } addHostDeviceSupportedProperties(&s.sdk.ModuleBase, m) @@ -482,6 +526,23 @@ func (s *snapshotBuilder) versionedSdkMemberNames(members []string) []string { return references } +// Get an internal name unique to the sdk. +func (s *snapshotBuilder) unversionedSdkMemberName(unversionedName string) string { + if s.sdk.isInternalMember(unversionedName) { + return s.ctx.ModuleName() + "_" + unversionedName + } else { + return unversionedName + } +} + +func (s *snapshotBuilder) unversionedSdkMemberNames(members []string) []string { + var references []string = nil + for _, m := range members { + references = append(references, s.unversionedSdkMemberName(m)) + } + return references +} + var _ android.SdkMember = (*sdkMember)(nil) type sdkMember struct {