From c9864278da15ccd4cfd164ab7408f20aa2811191 Mon Sep 17 00:00:00 2001 From: Jiakai Zhang Date: Sun, 26 Sep 2021 03:52:19 +0000 Subject: [PATCH 1/4] Add prebuilt_systemserverclasspath_fragment rule. This is the prebuilt side of systemserverclasspath_fragment, currently for used for dexpreopting. The change to automactially generate prebuilt_systemserverclasspath_fragment rules will be in a separate CL. Bug: 194150908 Test: m nothing Change-Id: Ibf5322f80f78ac3ca037489f4a279456fe38a23f --- apex/systemserver_classpath_fragment_test.go | 31 +++++++++++++++++++ java/systemserver_classpath_fragment.go | 32 ++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go index a8d5931db..822d2773e 100644 --- a/apex/systemserver_classpath_fragment_test.go +++ b/apex/systemserver_classpath_fragment_test.go @@ -181,3 +181,34 @@ func TestSystemServerClasspathFragmentWithContentNotInMake(t *testing.T) { } `) } + +func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) { + result := android.GroupFixturePreparers( + prepareForTestWithSystemserverclasspathFragment, + prepareForTestWithMyapex, + dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"), + ).RunTestWithBp(t, ` + java_import { + name: "foo", + jars: ["foo.jar"], + apex_available: [ + "myapex", + ], + } + + prebuilt_systemserverclasspath_fragment { + name: "mysystemserverclasspathfragment", + prefer: true, + contents: [ + "foo", + ], + apex_available: [ + "myapex", + ], + } + `) + + java.CheckModuleDependencies(t, result.TestContext, "mysystemserverclasspathfragment", "android_common", []string{ + `prebuilt_foo`, + }) +} diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go index de2a9787f..e2738d7fa 100644 --- a/java/systemserver_classpath_fragment.go +++ b/java/systemserver_classpath_fragment.go @@ -28,6 +28,7 @@ func init() { func registerSystemserverClasspathBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("platform_systemserverclasspath", platformSystemServerClasspathFactory) ctx.RegisterModuleType("systemserverclasspath_fragment", systemServerClasspathFactory) + ctx.RegisterModuleType("prebuilt_systemserverclasspath_fragment", prebuiltSystemServerClasspathModuleFactory) } type platformSystemServerClasspathModule struct { @@ -144,8 +145,14 @@ func IsSystemServerClasspathFragmentContentDepTag(tag blueprint.DependencyTag) b func (s *SystemServerClasspathModule) ComponentDepsMutator(ctx android.BottomUpMutatorContext) { module := ctx.Module() + _, isSourceModule := module.(*SystemServerClasspathModule) for _, name := range s.properties.Contents { + // A systemserverclasspath_fragment must depend only on other source modules, while the + // prebuilt_systemserverclasspath_fragment_fragment must only depend on other prebuilt modules. + if !isSourceModule { + name = android.PrebuiltNameFromSource(name) + } ctx.AddDependency(module, systemServerClasspathFragmentContentDepTag, name) } } @@ -155,3 +162,28 @@ func (s *SystemServerClasspathModule) IDEInfo(dpInfo *android.IdeInfo) { dpInfo.Deps = append(dpInfo.Deps, s.properties.Contents...) dpInfo.Paths = append(dpInfo.Paths, s.modulePaths...) } + +// A prebuilt version of the systemserverclasspath_fragment module. +type prebuiltSystemServerClasspathModule struct { + SystemServerClasspathModule + prebuilt android.Prebuilt +} + +func (module *prebuiltSystemServerClasspathModule) Prebuilt() *android.Prebuilt { + return &module.prebuilt +} + +func (module *prebuiltSystemServerClasspathModule) Name() string { + return module.prebuilt.Name(module.ModuleBase.Name()) +} + +func prebuiltSystemServerClasspathModuleFactory() android.Module { + m := &prebuiltSystemServerClasspathModule{} + m.AddProperties(&m.properties) + // This doesn't actually have any prebuilt files of its own so pass a placeholder for the srcs + // array. + android.InitPrebuiltModule(m, &[]string{"placeholder"}) + android.InitApexModule(m) + android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) + return m +} From 774dd305f4e9970fbf8d961db9dcf56eca8c9838 Mon Sep 17 00:00:00 2001 From: Jiakai Zhang Date: Sun, 26 Sep 2021 03:54:25 +0000 Subject: [PATCH 2/4] Add exported_systemserverclasspath_fragments to prebuilt_apex rule. This is for exporting the contents of systemserverclasspath_fragment for dexpreopting. Bug: 194150908 Test: manual - 1. Patch aosp/1818020 and aosp/1834534 2. m SOONG_CONFIG_art_module_source_build=false com.android.art Change-Id: I7d2d2e02869d8a523f7c0efbbff81706672a95c5 --- apex/prebuilt.go | 57 +++++++++++++------- apex/systemserver_classpath_fragment_test.go | 21 +++++++- java/systemserver_classpath_fragment.go | 10 ++++ 3 files changed, 67 insertions(+), 21 deletions(-) diff --git a/apex/prebuilt.go b/apex/prebuilt.go index d59f8bfec..55a9e421a 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -103,6 +103,10 @@ type PrebuiltCommonProperties struct { // List of bootclasspath fragments inside this prebuilt APEX bundle and for which this APEX // bundle will create an APEX variant. Exported_bootclasspath_fragments []string + + // List of systemserverclasspath fragments inside this prebuilt APEX bundle and for which this + // APEX bundle will create an APEX variant. + Exported_systemserverclasspath_fragments []string } // initPrebuiltCommon initializes the prebuiltCommon structure and performs initialization of the @@ -174,7 +178,8 @@ func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) { tag := ctx.OtherModuleDependencyTag(child) name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) - if java.IsBootclasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag { + if java.IsBootclasspathFragmentContentDepTag(tag) || + java.IsSystemServerClasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag { // If the exported java module provides a dex jar path then add it to the list of apexFiles. path := child.(interface { DexJarBuildPath() java.OptionalDexJarPath @@ -194,8 +199,9 @@ func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) { } p.apexFilesForAndroidMk = append(p.apexFilesForAndroidMk, af) } - } else if tag == exportedBootclasspathFragmentTag { - // Visit the children of the bootclasspath_fragment. + } else if tag == exportedBootclasspathFragmentTag || + tag == exportedSystemserverclasspathFragmentTag { + // Visit the children of the bootclasspath_fragment and systemserver_fragment. return true } @@ -311,21 +317,31 @@ func prebuiltApexModuleCreatorMutator(ctx android.TopDownMutatorContext) { } } +func (p *prebuiltCommon) getExportedDependencies() map[string]exportedDependencyTag { + dependencies := make(map[string]exportedDependencyTag) + + for _, dep := range p.prebuiltCommonProperties.Exported_java_libs { + dependencies[dep] = exportedJavaLibTag + } + + for _, dep := range p.prebuiltCommonProperties.Exported_bootclasspath_fragments { + dependencies[dep] = exportedBootclasspathFragmentTag + } + + for _, dep := range p.prebuiltCommonProperties.Exported_systemserverclasspath_fragments { + dependencies[dep] = exportedSystemserverclasspathFragmentTag + } + + return dependencies +} + // prebuiltApexContentsDeps adds dependencies onto the prebuilt apex module's contents. func (p *prebuiltCommon) prebuiltApexContentsDeps(ctx android.BottomUpMutatorContext) { module := ctx.Module() - // Add dependencies onto the java modules that represent the java libraries that are provided by - // and exported from this prebuilt apex. - for _, exported := range p.prebuiltCommonProperties.Exported_java_libs { - dep := android.PrebuiltNameFromSource(exported) - ctx.AddDependency(module, exportedJavaLibTag, dep) - } - // Add dependencies onto the bootclasspath fragment modules that are exported from this prebuilt - // apex. - for _, exported := range p.prebuiltCommonProperties.Exported_bootclasspath_fragments { - dep := android.PrebuiltNameFromSource(exported) - ctx.AddDependency(module, exportedBootclasspathFragmentTag, dep) + for dep, tag := range p.getExportedDependencies() { + prebuiltDep := android.PrebuiltNameFromSource(dep) + ctx.AddDependency(module, tag, prebuiltDep) } } @@ -576,9 +592,9 @@ func createApexSelectorModule(ctx android.TopDownMutatorContext, name string, ap // A deapexer module is only needed when the prebuilt apex specifies one or more modules in either // the `exported_java_libs` or `exported_bootclasspath_fragments` properties as that indicates that // the listed modules need access to files from within the prebuilt .apex file. -func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerName string, apexFileSource string, properties *PrebuiltCommonProperties) { +func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerName string, apexFileSource string) { // Only create the deapexer module if it is needed. - if len(properties.Exported_java_libs)+len(properties.Exported_bootclasspath_fragments) == 0 { + if len(p.getExportedDependencies()) == 0 { return } @@ -674,8 +690,9 @@ func (t exportedDependencyTag) RequiresFilesFromPrebuiltApex() {} var _ android.RequiresFilesFromPrebuiltApexTag = exportedDependencyTag{} var ( - exportedJavaLibTag = exportedDependencyTag{name: "exported_java_libs"} - exportedBootclasspathFragmentTag = exportedDependencyTag{name: "exported_bootclasspath_fragments"} + exportedJavaLibTag = exportedDependencyTag{name: "exported_java_libs"} + exportedBootclasspathFragmentTag = exportedDependencyTag{name: "exported_bootclasspath_fragments"} + exportedSystemserverclasspathFragmentTag = exportedDependencyTag{name: "exported_systemserverclasspath_fragments"} ) var _ prebuiltApexModuleCreator = (*Prebuilt)(nil) @@ -716,7 +733,7 @@ func (p *Prebuilt) createPrebuiltApexModules(ctx android.TopDownMutatorContext) createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties) apexFileSource := ":" + apexSelectorModuleName - createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource, p.prebuiltCommonProperties) + p.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource) // Add a source reference to retrieve the selected apex from the selector module. p.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource) @@ -919,7 +936,7 @@ func (a *ApexSet) createPrebuiltApexModules(ctx android.TopDownMutatorContext) { createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties) apexFileSource := ":" + apexExtractorModuleName - createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource, a.prebuiltCommonProperties) + a.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource) // After passing the arch specific src properties to the creating the apex selector module a.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource) diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go index 822d2773e..dc682faa4 100644 --- a/apex/systemserver_classpath_fragment_test.go +++ b/apex/systemserver_classpath_fragment_test.go @@ -188,6 +188,19 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) { prepareForTestWithMyapex, dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"), ).RunTestWithBp(t, ` + prebuilt_apex { + name: "myapex", + arch: { + arm64: { + src: "myapex-arm64.apex", + }, + arm: { + src: "myapex-arm.apex", + }, + }, + exported_systemserverclasspath_fragments: ["mysystemserverclasspathfragment"], + } + java_import { name: "foo", jars: ["foo.jar"], @@ -208,7 +221,13 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) { } `) - java.CheckModuleDependencies(t, result.TestContext, "mysystemserverclasspathfragment", "android_common", []string{ + java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{ + `myapex.apex.selector`, + `prebuilt_mysystemserverclasspathfragment`, + }) + + java.CheckModuleDependencies(t, result.TestContext, "mysystemserverclasspathfragment", "android_common_myapex", []string{ + `myapex.deapexer`, `prebuilt_foo`, }) } diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go index e2738d7fa..26796a6cc 100644 --- a/java/systemserver_classpath_fragment.go +++ b/java/systemserver_classpath_fragment.go @@ -133,8 +133,12 @@ func (systemServerClasspathFragmentContentDependencyTag) ReplaceSourceWithPrebui // they were listed in java_libs. func (systemServerClasspathFragmentContentDependencyTag) CopyDirectlyInAnyApex() {} +// Contents of system server fragments require files from prebuilt apex files. +func (systemServerClasspathFragmentContentDependencyTag) RequiresFilesFromPrebuiltApex() {} + var _ android.ReplaceSourceWithPrebuilt = systemServerClasspathFragmentContentDepTag var _ android.CopyDirectlyInAnyApexTag = systemServerClasspathFragmentContentDepTag +var _ android.RequiresFilesFromPrebuiltApexTag = systemServerClasspathFragmentContentDepTag // The tag used for the dependency between the systemserverclasspath_fragment module and its contents. var systemServerClasspathFragmentContentDepTag = systemServerClasspathFragmentContentDependencyTag{} @@ -177,6 +181,12 @@ func (module *prebuiltSystemServerClasspathModule) Name() string { return module.prebuilt.Name(module.ModuleBase.Name()) } +func (module *prebuiltSystemServerClasspathModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string { + return nil +} + +var _ android.RequiredFilesFromPrebuiltApex = (*prebuiltSystemServerClasspathModule)(nil) + func prebuiltSystemServerClasspathModuleFactory() android.Module { m := &prebuiltSystemServerClasspathModule{} m.AddProperties(&m.properties) From ea18033f31bca4250f4ff2ab9772410910f7b49b Mon Sep 17 00:00:00 2001 From: Jiakai Zhang Date: Sun, 26 Sep 2021 08:58:02 +0000 Subject: [PATCH 3/4] Add a new SDK member type java_systemserver_libs. Similar to java_boot_libs, java_systemserver_libs only provide access to their dex implementation jar for use by dexpreopting and do not provide an actual implementation jar. This is used in the subsequent CL. Bug: 194150908 Test: m nothing Change-Id: Ib2e7d5e6c002314a0231f46934a766f4a27e610a --- java/java.go | 32 ++++++++++++++++++++++ sdk/java_sdk_test.go | 65 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/java/java.go b/java/java.go index 94c12bdbb..23809df74 100644 --- a/java/java.go +++ b/java/java.go @@ -73,6 +73,7 @@ func RegisterJavaSdkMemberTypes() { android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType) android.RegisterSdkMemberType(javaLibsSdkMemberType) android.RegisterSdkMemberType(javaBootLibsSdkMemberType) + android.RegisterSdkMemberType(javaSystemserverLibsSdkMemberType) android.RegisterSdkMemberType(javaTestSdkMemberType) } @@ -146,6 +147,37 @@ var ( onlyCopyJarToSnapshot, } + // Supports adding java systemserver libraries to module_exports and sdk. + // + // The build has some implicit dependencies (via the systemserver jars configuration) on a number + // of modules that are part of the java systemserver classpath and which are provided by mainline + // modules but which are not otherwise used outside those mainline modules. + // + // As they are not needed outside the mainline modules adding them to the sdk/module-exports as + // either java_libs, or java_header_libs would end up exporting more information than was strictly + // necessary. The java_systemserver_libs property to allow those modules to be exported as part of + // the sdk/module_exports without exposing any unnecessary information. + javaSystemserverLibsSdkMemberType = &librarySdkMemberType{ + android.SdkMemberTypeBase{ + PropertyName: "java_systemserver_libs", + SupportsSdk: true, + }, + func(ctx android.SdkMemberContext, j *Library) android.Path { + // Java systemserver libs are only provided in the SDK to provide access to their dex + // implementation jar for use by dexpreopting. They do not need to provide an actual + // implementation jar but the java_import will need a file that exists so just copy an empty + // file. Any attempt to use that file as a jar will cause a build error. + return ctx.SnapshotBuilder().EmptyFile() + }, + func(osPrefix, name string) string { + // Create a special name for the implementation jar to try and provide some useful information + // to a developer that attempts to compile against this. + // TODO(b/175714559): Provide a proper error message in Soong not ninja. + return filepath.Join(osPrefix, "java_systemserver_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) + }, + onlyCopyJarToSnapshot, + } + // Supports adding java test libraries to module_exports but not sdk. javaTestSdkMemberType = &testSdkMemberType{ SdkMemberTypeBase: android.SdkMemberTypeBase{ diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go index 2b537398a..0d9b4a063 100644 --- a/sdk/java_sdk_test.go +++ b/sdk/java_sdk_test.go @@ -482,6 +482,71 @@ module_exports_snapshot { ) } +func TestSnapshotWithJavaSystemserverLibrary(t *testing.T) { + result := android.GroupFixturePreparers( + prepareForSdkTestWithJava, + android.FixtureAddFile("aidl", nil), + android.FixtureAddFile("resource.txt", nil), + ).RunTestWithBp(t, ` + module_exports { + name: "myexports", + java_systemserver_libs: ["myjavalib"], + } + + java_library { + name: "myjavalib", + srcs: ["Test.java"], + java_resources: ["resource.txt"], + // The aidl files should not be copied to the snapshot because a java_systemserver_libs member + // is not intended to be used for compiling Java, only for accessing the dex implementation + // jar. + aidl: { + export_include_dirs: ["aidl"], + }, + system_modules: "none", + sdk_version: "none", + compile_dex: true, + permitted_packages: ["pkg.myjavalib"], + } + `) + + CheckSnapshot(t, result, "myexports", "", + checkUnversionedAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +java_import { + name: "myjavalib", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + jars: ["java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar"], + permitted_packages: ["pkg.myjavalib"], +} +`), + checkVersionedAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +java_import { + name: "myexports_myjavalib@current", + sdk_member_name: "myjavalib", + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + jars: ["java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar"], + permitted_packages: ["pkg.myjavalib"], +} + +module_exports_snapshot { + name: "myexports@current", + visibility: ["//visibility:public"], + java_systemserver_libs: ["myexports_myjavalib@current"], +} +`), + checkAllCopyRules(` +.intermediates/myexports/common_os/empty -> java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar +`), + ) +} + func TestHostSnapshotWithJavaImplLibrary(t *testing.T) { result := android.GroupFixturePreparers( prepareForSdkTestWithJava, From a8d8660ab1fbaf68a95961a2f72593eb01780640 Mon Sep 17 00:00:00 2001 From: Jiakai Zhang Date: Sun, 26 Sep 2021 09:02:17 +0000 Subject: [PATCH 4/4] Generate prebuilt_systemserverclasspath_fragment. Bug: 194150908 Test: m nothing Test: manual - 1. Patch aosp/1835087. 2. m out/soong/.intermediates/art/build/sdk/art-module-sdk/common_os/snapshot/Android.bp 3. See prebuilt_systemserverclasspath_fragment modules and systemserverclasspath_fragments in an sdk_snapshot module. Change-Id: I7876b077b0b4ed190f01dbfa9533de04ea32d524 --- java/systemserver_classpath_fragment.go | 74 +++++++- sdk/Android.bp | 2 + ...systemserverclasspath_fragment_sdk_test.go | 171 ++++++++++++++++++ 3 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 sdk/systemserverclasspath_fragment_sdk_test.go diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go index 26796a6cc..1b4fda821 100644 --- a/java/systemserver_classpath_fragment.go +++ b/java/systemserver_classpath_fragment.go @@ -23,6 +23,13 @@ import ( func init() { registerSystemserverClasspathBuildComponents(android.InitRegistrationContext) + + android.RegisterSdkMemberType(&systemServerClasspathFragmentMemberType{ + SdkMemberTypeBase: android.SdkMemberTypeBase{ + PropertyName: "systemserverclasspath_fragments", + SupportsSdk: true, + }, + }) } func registerSystemserverClasspathBuildComponents(ctx android.RegistrationContext) { @@ -62,6 +69,7 @@ func (p *platformSystemServerClasspathModule) configuredJars(ctx android.ModuleC type SystemServerClasspathModule struct { android.ModuleBase android.ApexModuleBase + android.SdkBase ClasspathFragmentBase @@ -86,6 +94,7 @@ func systemServerClasspathFactory() android.Module { m := &SystemServerClasspathModule{} m.AddProperties(&m.properties) android.InitApexModule(m) + android.InitSdkAwareModule(m) initClasspathFragment(m, SYSTEMSERVERCLASSPATH) android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) return m @@ -113,7 +122,7 @@ func (s *SystemServerClasspathModule) configuredJars(ctx android.ModuleContext) _, unknown = android.RemoveFromList("geotz", unknown) // For non test apexes, make sure that all contents are actually declared in make. - if global.ApexSystemServerJars.Len() > 0 && len(unknown) > 0 { + if global.ApexSystemServerJars.Len() > 0 && len(unknown) > 0 && !android.IsModuleInVersionedSdk(ctx.Module()) { ctx.ModuleErrorf("%s in contents must also be declared in PRODUCT_UPDATABLE_SYSTEM_SERVER_JARS", unknown) } @@ -129,6 +138,22 @@ func (systemServerClasspathFragmentContentDependencyTag) ReplaceSourceWithPrebui return false } +// SdkMemberType causes dependencies added with this tag to be automatically added to the sdk as if +// they were specified using java_systemserver_libs or java_sdk_libs. +func (b systemServerClasspathFragmentContentDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType { + // If the module is a java_sdk_library then treat it as if it was specified in the java_sdk_libs + // property, otherwise treat if it was specified in the java_systemserver_libs property. + if javaSdkLibrarySdkMemberType.IsInstance(child) { + return javaSdkLibrarySdkMemberType + } + + return javaSystemserverLibsSdkMemberType +} + +func (b systemServerClasspathFragmentContentDependencyTag) ExportMember() bool { + return true +} + // Contents of system server fragments in an apex are considered to be directly in the apex, as if // they were listed in java_libs. func (systemServerClasspathFragmentContentDependencyTag) CopyDirectlyInAnyApex() {} @@ -137,6 +162,7 @@ func (systemServerClasspathFragmentContentDependencyTag) CopyDirectlyInAnyApex() func (systemServerClasspathFragmentContentDependencyTag) RequiresFilesFromPrebuiltApex() {} var _ android.ReplaceSourceWithPrebuilt = systemServerClasspathFragmentContentDepTag +var _ android.SdkMemberDependencyTag = systemServerClasspathFragmentContentDepTag var _ android.CopyDirectlyInAnyApexTag = systemServerClasspathFragmentContentDepTag var _ android.RequiresFilesFromPrebuiltApexTag = systemServerClasspathFragmentContentDepTag @@ -167,6 +193,51 @@ func (s *SystemServerClasspathModule) IDEInfo(dpInfo *android.IdeInfo) { dpInfo.Paths = append(dpInfo.Paths, s.modulePaths...) } +type systemServerClasspathFragmentMemberType struct { + android.SdkMemberTypeBase +} + +func (s *systemServerClasspathFragmentMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) { + ctx.AddVariationDependencies(nil, dependencyTag, names...) +} + +func (s *systemServerClasspathFragmentMemberType) IsInstance(module android.Module) bool { + _, ok := module.(*SystemServerClasspathModule) + return ok +} + +func (s *systemServerClasspathFragmentMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { + return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_systemserverclasspath_fragment") +} + +func (s *systemServerClasspathFragmentMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { + return &systemServerClasspathFragmentSdkMemberProperties{} +} + +type systemServerClasspathFragmentSdkMemberProperties struct { + android.SdkMemberPropertiesBase + + // Contents of the systemserverclasspath fragment + Contents []string +} + +func (s *systemServerClasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { + module := variant.(*SystemServerClasspathModule) + + s.Contents = module.properties.Contents +} + +func (s *systemServerClasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { + builder := ctx.SnapshotBuilder() + requiredMemberDependency := builder.SdkMemberReferencePropertyTag(true) + + if len(s.Contents) > 0 { + propertySet.AddPropertyWithTag("contents", s.Contents, requiredMemberDependency) + } +} + +var _ android.SdkMemberType = (*systemServerClasspathFragmentMemberType)(nil) + // A prebuilt version of the systemserverclasspath_fragment module. type prebuiltSystemServerClasspathModule struct { SystemServerClasspathModule @@ -194,6 +265,7 @@ func prebuiltSystemServerClasspathModuleFactory() android.Module { // array. android.InitPrebuiltModule(m, &[]string{"placeholder"}) android.InitApexModule(m) + android.InitSdkAwareModule(m) android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) return m } diff --git a/sdk/Android.bp b/sdk/Android.bp index c6544d68a..acb9dbb56 100644 --- a/sdk/Android.bp +++ b/sdk/Android.bp @@ -11,6 +11,7 @@ bootstrap_go_package { "soong-android", "soong-apex", "soong-cc", + "soong-dexpreopt", "soong-java", ], srcs: [ @@ -31,6 +32,7 @@ bootstrap_go_package { "license_sdk_test.go", "member_trait_test.go", "sdk_test.go", + "systemserverclasspath_fragment_sdk_test.go", "testing.go", ], pluginFor: ["soong_build"], diff --git a/sdk/systemserverclasspath_fragment_sdk_test.go b/sdk/systemserverclasspath_fragment_sdk_test.go new file mode 100644 index 000000000..16e3e7fa9 --- /dev/null +++ b/sdk/systemserverclasspath_fragment_sdk_test.go @@ -0,0 +1,171 @@ +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sdk + +import ( + "testing" + + "android/soong/android" + "android/soong/dexpreopt" + "android/soong/java" +) + +func TestSnapshotWithSystemServerClasspathFragment(t *testing.T) { + result := android.GroupFixturePreparers( + prepareForSdkTestWithJava, + java.PrepareForTestWithJavaDefaultModules, + java.PrepareForTestWithJavaSdkLibraryFiles, + java.FixtureWithLastReleaseApis("mysdklibrary"), + dexpreopt.FixtureSetApexSystemServerJars("myapex:mylib", "myapex:mysdklibrary"), + prepareForSdkTestWithApex, + + android.FixtureWithRootAndroidBp(` + sdk { + name: "mysdk", + systemserverclasspath_fragments: ["mysystemserverclasspathfragment"], + java_sdk_libs: [ + // This is not strictly needed as it should be automatically added to the sdk_snapshot as + // a java_sdk_libs module because it is used in the mysystemserverclasspathfragment's + // contents property. However, it is specified here to ensure that duplicates are + // correctly deduped. + "mysdklibrary", + ], + } + + apex { + name: "myapex", + key: "myapex.key", + min_sdk_version: "2", + systemserverclasspath_fragments: ["mysystemserverclasspathfragment"], + } + + systemserverclasspath_fragment { + name: "mysystemserverclasspathfragment", + apex_available: ["myapex"], + contents: [ + "mylib", + "mysdklibrary", + ], + } + + java_library { + name: "mylib", + apex_available: ["myapex"], + srcs: ["Test.java"], + system_modules: "none", + sdk_version: "none", + min_sdk_version: "2", + compile_dex: true, + permitted_packages: ["mylib"], + } + + java_sdk_library { + name: "mysdklibrary", + apex_available: ["myapex"], + srcs: ["Test.java"], + shared_library: false, + public: {enabled: true}, + min_sdk_version: "2", + } + `), + ).RunTest(t) + + CheckSnapshot(t, result, "mysdk", "", + checkUnversionedAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +java_sdk_library_import { + name: "mysdklibrary", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["myapex"], + 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", + }, +} + +java_import { + name: "mylib", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["myapex"], + jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"], + permitted_packages: ["mylib"], +} + +prebuilt_systemserverclasspath_fragment { + name: "mysystemserverclasspathfragment", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["myapex"], + contents: [ + "mylib", + "mysdklibrary", + ], +} +`), + checkVersionedAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +java_sdk_library_import { + name: "mysdk_mysdklibrary@current", + sdk_member_name: "mysdklibrary", + visibility: ["//visibility:public"], + apex_available: ["myapex"], + 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", + }, +} + +java_import { + name: "mysdk_mylib@current", + sdk_member_name: "mylib", + visibility: ["//visibility:public"], + apex_available: ["myapex"], + jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"], + permitted_packages: ["mylib"], +} + +prebuilt_systemserverclasspath_fragment { + name: "mysdk_mysystemserverclasspathfragment@current", + sdk_member_name: "mysystemserverclasspathfragment", + visibility: ["//visibility:public"], + apex_available: ["myapex"], + contents: [ + "mysdk_mylib@current", + "mysdk_mysdklibrary@current", + ], +} + +sdk_snapshot { + name: "mysdk@current", + visibility: ["//visibility:public"], + java_sdk_libs: ["mysdk_mysdklibrary@current"], + java_systemserver_libs: ["mysdk_mylib@current"], + systemserverclasspath_fragments: ["mysdk_mysystemserverclasspathfragment@current"], +} +`), + ) +}