diff options
Diffstat (limited to 'java')
-rwxr-xr-x | java/app.go | 4 | ||||
-rw-r--r-- | java/bootclasspath_fragment_test.go | 36 | ||||
-rw-r--r-- | java/core-libraries/TxtStubLibraries.bp | 20 | ||||
-rw-r--r-- | java/dexpreopt_bootjars.go | 2 | ||||
-rw-r--r-- | java/dexpreopt_check.go | 2 | ||||
-rw-r--r-- | java/fuzz.go | 6 | ||||
-rw-r--r-- | java/hiddenapi_modular.go | 2 | ||||
-rw-r--r-- | java/hiddenapi_singleton.go | 2 | ||||
-rw-r--r-- | java/java.go | 10 | ||||
-rw-r--r-- | java/java_test.go | 23 | ||||
-rw-r--r-- | java/jdeps.go | 2 | ||||
-rw-r--r-- | java/lint.go | 2 | ||||
-rw-r--r-- | java/platform_bootclasspath.go | 2 | ||||
-rw-r--r-- | java/platform_compat_config.go | 2 | ||||
-rw-r--r-- | java/robolectric.go | 66 | ||||
-rw-r--r-- | java/sdk.go | 2 | ||||
-rw-r--r-- | java/sdk_library.go | 78 | ||||
-rw-r--r-- | java/sdk_library_test.go | 63 | ||||
-rw-r--r-- | java/testing.go | 31 |
19 files changed, 283 insertions, 72 deletions
diff --git a/java/app.go b/java/app.go index e09509299..366005ce3 100755 --- a/java/app.go +++ b/java/app.go @@ -977,6 +977,10 @@ func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android. // For OutputFileProducer interface func (a *AndroidApp) OutputFiles(tag string) (android.Paths, error) { switch tag { + // In some instances, it can be useful to reference the aapt-generated flags from another + // target, e.g., system server implements services declared in the framework-res manifest. + case ".aapt.proguardOptionsFile": + return []android.Path{a.proguardOptionsFile}, nil case ".aapt.srcjar": return []android.Path{a.aaptSrcJar}, nil case ".export-package.apk": diff --git a/java/bootclasspath_fragment_test.go b/java/bootclasspath_fragment_test.go index 2541f14ff..9bdef749b 100644 --- a/java/bootclasspath_fragment_test.go +++ b/java/bootclasspath_fragment_test.go @@ -432,3 +432,39 @@ func TestBootclasspathFragment_Test(t *testing.T) { fragment = result.Module("a_test_fragment", "android_common").(*BootclasspathFragmentModule) android.AssertBoolEquals(t, "is a test fragment by type", true, fragment.isTestFragment()) } + +func TestBootclassFragment_LinkTextStub(t *testing.T) { + result := android.GroupFixturePreparers( + prepareForJavaTest, + prepareForTestWithBootclasspathFragment, + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("mysdklibrary"), + android.FixtureModifyConfig(func(config android.Config) { + config.SetBuildFromTextStub(true) + }), + ).RunTestWithBp(t, ` + bootclasspath_fragment { + name: "myfragment", + contents: ["mysdklibrary"], + hidden_api: {split_packages: ["*"]}, + additional_stubs: [ + "android-non-updatable", + ], + } + java_sdk_library { + name: "mysdklibrary", + srcs: ["a.java"], + shared_library: false, + public: {enabled: true}, + system: {enabled: true}, + } + `) + + fragment := result.ModuleForTests("myfragment", "android_common") + ruleCommand := fragment.Rule("modularHiddenAPIStubFlagsFile").RuleParams.Command + android.AssertStringDoesContain(t, "Command expected to contain library as dependency stub dex", + ruleCommand, "--dependency-stub-dex=out/soong/.intermediates/default/java/android-non-updatable.stubs.module_lib.from-text/android_common/dex/android-non-updatable.stubs.module_lib.from-text.jar") + android.AssertStringDoesNotContain(t, + "Command not expected to contain multiple api_library as dependency stub dex", ruleCommand, + "--dependency-stub-dex=out/soong/.intermediates/default/java/android-non-updatable.stubs.from-text/android_common/dex/android-non-updatable.stubs.from-text.jar") +} diff --git a/java/core-libraries/TxtStubLibraries.bp b/java/core-libraries/TxtStubLibraries.bp index 813187e54..0cf0f360b 100644 --- a/java/core-libraries/TxtStubLibraries.bp +++ b/java/core-libraries/TxtStubLibraries.bp @@ -22,8 +22,6 @@ java_system_modules { libs: [ "core-current-stubs-for-system-modules-no-annotations.from-text", ], - // TODO: Enable after stub generation from .txt file is available - enabled: false, } java_library { @@ -36,8 +34,6 @@ java_library { "core.current.stubs.from-text", "core-lambda-stubs.from-text", ], - // TODO: Enable after stub generation from .txt file is available - enabled: false, } // Same as core-module-lib-stubs-system-modules, but the stubs are generated from .txt files @@ -47,8 +43,6 @@ java_system_modules { libs: [ "core-module-lib-stubs-for-system-modules-no-annotations.from-text", ], - // TODO: Enable after stub generation from .txt file is available - enabled: false, } java_library { @@ -61,8 +55,6 @@ java_library { "core.module_lib.stubs.from-text", "core-lambda-stubs.from-text", ], - // TODO: Enable after stub generation from .txt file is available - enabled: false, } java_library { @@ -79,8 +71,6 @@ java_library { sdk_version: "none", system_modules: "none", visibility: ["//visibility:private"], - // TODO: Enable after stub generation from .txt file is available - enabled: false, } // Same as legacy-core-platform-api-stubs-system-modules, but the stubs are generated from .txt files @@ -91,8 +81,6 @@ java_system_modules { "legacy.core.platform.api.no.annotations.stubs.from-text", "core-lambda-stubs.from-text", ], - // TODO: Enable after stub generation from .txt file is available - enabled: false, } java_library { @@ -108,8 +96,6 @@ java_library { "legacy.core.platform.api.stubs.from-text", ], patch_module: "java.base", - // TODO: Enable after stub generation from .txt file is available - enabled: false, } // Same as stable-core-platform-api-stubs-system-modules, but the stubs are generated from .txt files @@ -120,8 +106,6 @@ java_system_modules { "stable.core.platform.api.no.annotations.stubs.from-text", "core-lambda-stubs.from-text", ], - // TODO: Enable after stub generation from .txt file is available - enabled: false, } java_library { @@ -137,8 +121,6 @@ java_library { "stable.core.platform.api.stubs.from-text", ], patch_module: "java.base", - // TODO: Enable after stub generation from .txt file is available - enabled: false, } java_api_library { @@ -151,6 +133,4 @@ java_api_library { // LambdaMetaFactory depends on CallSite etc. which is part of the Core API surface "core.current.stubs.from-text", ], - // TODO: Enable after stub generation from .txt file is available - enabled: false, } diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index f477f404e..116c833e0 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -465,7 +465,7 @@ func dexpreoptBootJarsFactory() android.SingletonModule { } func RegisterDexpreoptBootJarsComponents(ctx android.RegistrationContext) { - ctx.RegisterSingletonModuleType("dex_bootjars", dexpreoptBootJarsFactory) + ctx.RegisterParallelSingletonModuleType("dex_bootjars", dexpreoptBootJarsFactory) } func SkipDexpreoptBootJars(ctx android.PathContext) bool { diff --git a/java/dexpreopt_check.go b/java/dexpreopt_check.go index 83c088cd4..7499481de 100644 --- a/java/dexpreopt_check.go +++ b/java/dexpreopt_check.go @@ -28,7 +28,7 @@ func init() { } func RegisterDexpreoptCheckBuildComponents(ctx android.RegistrationContext) { - ctx.RegisterSingletonModuleType("dexpreopt_systemserver_check", dexpreoptSystemserverCheckFactory) + ctx.RegisterParallelSingletonModuleType("dexpreopt_systemserver_check", dexpreoptSystemserverCheckFactory) } // A build-time check to verify if all compilation artifacts of system server jars are installed diff --git a/java/fuzz.go b/java/fuzz.go index 4aa6dbffd..5c5f769a5 100644 --- a/java/fuzz.go +++ b/java/fuzz.go @@ -38,7 +38,7 @@ func init() { func RegisterJavaFuzzBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("java_fuzz", JavaFuzzFactory) - ctx.RegisterSingletonType("java_fuzz_packaging", javaFuzzPackagingFactory) + ctx.RegisterParallelSingletonType("java_fuzz_packaging", javaFuzzPackagingFactory) } type JavaFuzzTest struct { @@ -150,7 +150,9 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { } hostOrTargetString := "target" - if javaFuzzModule.Host() { + if javaFuzzModule.Target().HostCross { + hostOrTargetString = "host_cross" + } else if javaFuzzModule.Host() { hostOrTargetString = "host" } diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index 96e084a20..e54275b88 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -647,7 +647,7 @@ func (s StubDexJarsByModule) addStubDexJar(ctx android.ModuleContext, module and // public version is provided by the art.module.public.api module. In those cases it is necessary // to treat all those modules as they were the same name, otherwise it will result in multiple // definitions of a single class being passed to hidden API processing which will cause an error. - if name == scope.nonUpdatablePrebuiltModule || name == scope.nonUpdatableSourceModule { + if name == scope.nonUpdatablePrebuiltModule || name == android.JavaApiLibraryName(ctx.Config(), scope.nonUpdatableSourceModule) { // Treat all *android-non-updatable* modules as if they were part of an android-non-updatable // java_sdk_library. // TODO(b/192067200): Remove once android-non-updatable is a java_sdk_library or equivalent. diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go index 52934a327..d4ee4fc9f 100644 --- a/java/hiddenapi_singleton.go +++ b/java/hiddenapi_singleton.go @@ -25,7 +25,7 @@ func init() { } func RegisterHiddenApiSingletonComponents(ctx android.RegistrationContext) { - ctx.RegisterSingletonType("hiddenapi", hiddenAPISingletonFactory) + ctx.RegisterParallelSingletonType("hiddenapi", hiddenAPISingletonFactory) } var PrepareForTestWithHiddenApiBuildComponents = android.FixtureRegisterWithContext(RegisterHiddenApiSingletonComponents) diff --git a/java/java.go b/java/java.go index 65bfce088..33846bec6 100644 --- a/java/java.go +++ b/java/java.go @@ -73,8 +73,8 @@ func registerJavaBuildComponents(ctx android.RegistrationContext) { ctx.BottomUp("jacoco_deps", jacocoDepsMutator).Parallel() }) - ctx.RegisterSingletonType("logtags", LogtagsSingleton) - ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory) + ctx.RegisterParallelSingletonType("logtags", LogtagsSingleton) + ctx.RegisterParallelSingletonType("kythe_java_extract", kytheExtractJavaFactory) } func RegisterJavaSdkMemberTypes() { @@ -1650,7 +1650,7 @@ type JavaApiLibraryProperties struct { // list of api.txt files relative to this directory that contribute to the // API surface. // This is a list of relative paths - Api_files []string + Api_files []string `android:"path"` // List of flags to be passed to the javac compiler to generate jar file Javacflags []string @@ -1832,9 +1832,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Add the api_files inputs for _, api := range al.properties.Api_files { - // Use MaybeExistentPathForSource since the api file might not exist during analysis. - // This will be provided by the orchestrator in the combined execution. - srcFiles = append(srcFiles, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), api)) + srcFiles = append(srcFiles, android.PathForModuleSrc(ctx, api)) } if srcFiles == nil { diff --git a/java/java_test.go b/java/java_test.go index 2a4913ecd..ea89e6eb8 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -2252,6 +2252,29 @@ func TestJavaApiLibraryDepApiSrcs(t *testing.T) { android.AssertStringDoesContain(t, "Command expected to contain output files list text file flag", manifestCommand, "--out __SBOX_SANDBOX_DIR__/out/sources.txt") } +func TestJavaApiLibraryFilegroupInput(t *testing.T) { + ctx, _ := testJavaWithFS(t, ` + filegroup { + name: "default_current.txt", + srcs: ["current.txt"], + } + + java_api_library { + name: "foo", + api_files: [":default_current.txt"], + } + `, + map[string][]byte{ + "current.txt": nil, + }) + + m := ctx.ModuleForTests("foo", "android_common") + outputs := fmt.Sprint(m.AllOutputs()) + if !strings.Contains(outputs, "foo/foo.jar") { + t.Errorf("Module output does not contain expected jar %s", "foo/foo.jar") + } +} + func TestTradefedOptions(t *testing.T) { result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, ` java_test_host { diff --git a/java/jdeps.go b/java/jdeps.go index a52b86708..4c8c11c5d 100644 --- a/java/jdeps.go +++ b/java/jdeps.go @@ -26,7 +26,7 @@ import ( // called. Dependency info file is generated in $OUT/module_bp_java_depend.json. func init() { - android.RegisterSingletonType("jdeps_generator", jDepsGeneratorSingleton) + android.RegisterParallelSingletonType("jdeps_generator", jDepsGeneratorSingleton) } func jDepsGeneratorSingleton() android.Singleton { diff --git a/java/lint.go b/java/lint.go index 40ef48416..a0f99707a 100644 --- a/java/lint.go +++ b/java/lint.go @@ -705,7 +705,7 @@ func (l *lintSingleton) MakeVars(ctx android.MakeVarsContext) { var _ android.SingletonMakeVarsProvider = (*lintSingleton)(nil) func init() { - android.RegisterSingletonType("lint", + android.RegisterParallelSingletonType("lint", func() android.Singleton { return &lintSingleton{} }) registerLintBuildComponents(android.InitRegistrationContext) diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go index 07fb92cfe..0d4db7ca1 100644 --- a/java/platform_bootclasspath.go +++ b/java/platform_bootclasspath.go @@ -26,7 +26,7 @@ func init() { } func registerPlatformBootclasspathBuildComponents(ctx android.RegistrationContext) { - ctx.RegisterSingletonModuleType("platform_bootclasspath", platformBootclasspathFactory) + ctx.RegisterParallelSingletonModuleType("platform_bootclasspath", platformBootclasspathFactory) } // The tags used for the dependencies between the platform bootclasspath and any configured boot diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go index d41729150..2197304a5 100644 --- a/java/platform_compat_config.go +++ b/java/platform_compat_config.go @@ -36,7 +36,7 @@ var CompatConfigSdkMemberType = &compatConfigMemberType{ } func registerPlatformCompatConfigBuildComponents(ctx android.RegistrationContext) { - ctx.RegisterSingletonType("platform_compat_config_singleton", platformCompatConfigSingletonFactory) + ctx.RegisterParallelSingletonType("platform_compat_config_singleton", platformCompatConfigSingletonFactory) ctx.RegisterModuleType("platform_compat_config", PlatformCompatConfigFactory) ctx.RegisterModuleType("prebuilt_platform_compat_config", prebuiltCompatConfigFactory) ctx.RegisterModuleType("global_compat_config", globalCompatConfigFactory) diff --git a/java/robolectric.go b/java/robolectric.go index 008b8b1c9..6bbe872bb 100644 --- a/java/robolectric.go +++ b/java/robolectric.go @@ -144,29 +144,37 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) roboTestConfig := android.PathForModuleGen(ctx, "robolectric"). Join(ctx, "com/android/tools/test_config.properties") + var ok bool + var instrumentedApp *AndroidApp + // TODO: this inserts paths to built files into the test, it should really be inserting the contents. instrumented := ctx.GetDirectDepsWithTag(instrumentationForTag) - if len(instrumented) != 1 { + if len(instrumented) == 1 { + instrumentedApp, ok = instrumented[0].(*AndroidApp) + if !ok { + ctx.PropertyErrorf("instrumentation_for", "dependency must be an android_app") + } + } else if !ctx.Config().AllowMissingDependencies() { panic(fmt.Errorf("expected exactly 1 instrumented dependency, got %d", len(instrumented))) } - instrumentedApp, ok := instrumented[0].(*AndroidApp) - if !ok { - ctx.PropertyErrorf("instrumentation_for", "dependency must be an android_app") - } - - r.manifest = instrumentedApp.mergedManifestFile - r.resourceApk = instrumentedApp.outputFile + if instrumentedApp != nil { + r.manifest = instrumentedApp.mergedManifestFile + r.resourceApk = instrumentedApp.outputFile - generateRoboTestConfig(ctx, roboTestConfig, instrumentedApp) - r.extraResources = android.Paths{roboTestConfig} + generateRoboTestConfig(ctx, roboTestConfig, instrumentedApp) + r.extraResources = android.Paths{roboTestConfig} + } r.Library.GenerateAndroidBuildActions(ctx) roboSrcJar := android.PathForModuleGen(ctx, "robolectric", ctx.ModuleName()+".srcjar") - r.generateRoboSrcJar(ctx, roboSrcJar, instrumentedApp) - r.roboSrcJar = roboSrcJar + + if instrumentedApp != nil { + r.generateRoboSrcJar(ctx, roboSrcJar, instrumentedApp) + r.roboSrcJar = roboSrcJar + } roboTestConfigJar := android.PathForModuleOut(ctx, "robolectric_samedir", "samedir_config.jar") generateSameDirRoboTestConfigJar(ctx, roboTestConfigJar) @@ -177,7 +185,10 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) // once the Make test runner is removed. roboTestConfigJar, r.outputFile, - instrumentedApp.implementationAndResourcesJar, + } + + if instrumentedApp != nil { + combinedJarJars = append(combinedJarJars, instrumentedApp.implementationAndResourcesJar) } handleLibDeps := func(dep android.Module) { @@ -213,21 +224,28 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) r.tests = append(r.tests, s) } - r.data = append(r.data, r.manifest, r.resourceApk) - - runtimes := ctx.GetDirectDepWithTag("robolectric-android-all-prebuilts", roboRuntimesTag) - installPath := android.PathForModuleInstall(ctx, r.BaseModuleName()) + var installDeps android.Paths - installedResourceApk := ctx.InstallFile(installPath, ctx.ModuleName()+".apk", r.resourceApk) - installedManifest := ctx.InstallFile(installPath, ctx.ModuleName()+"-AndroidManifest.xml", r.manifest) - installedConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig) + if r.manifest != nil { + r.data = append(r.data, r.manifest) + installedManifest := ctx.InstallFile(installPath, ctx.ModuleName()+"-AndroidManifest.xml", r.manifest) + installDeps = append(installDeps, installedManifest) + } - var installDeps android.Paths + if r.resourceApk != nil { + r.data = append(r.data, r.resourceApk) + installedResourceApk := ctx.InstallFile(installPath, ctx.ModuleName()+".apk", r.resourceApk) + installDeps = append(installDeps, installedResourceApk) + } + + runtimes := ctx.GetDirectDepWithTag("robolectric-android-all-prebuilts", roboRuntimesTag) for _, runtime := range runtimes.(*robolectricRuntimes).runtimes { installDeps = append(installDeps, runtime) } - installDeps = append(installDeps, installedResourceApk, installedManifest, installedConfig) + + installedConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig) + installDeps = append(installDeps, installedConfig) for _, data := range android.PathsForModuleSrc(ctx, r.testProperties.Data) { installedData := ctx.InstallFile(installPath, data.Rel(), data) @@ -340,7 +358,9 @@ func (r *robolectricTest) writeTestRunner(w io.Writer, module, name string, test fmt.Fprintln(w, "LOCAL_MODULE :=", name) android.AndroidMkEmitAssignList(w, "LOCAL_JAVA_LIBRARIES", []string{module}, r.libs) fmt.Fprintln(w, "LOCAL_TEST_PACKAGE :=", String(r.robolectricProperties.Instrumentation_for)) - fmt.Fprintln(w, "LOCAL_INSTRUMENT_SRCJARS :=", r.roboSrcJar.String()) + if r.roboSrcJar != nil { + fmt.Fprintln(w, "LOCAL_INSTRUMENT_SRCJARS :=", r.roboSrcJar.String()) + } android.AndroidMkEmitAssignList(w, "LOCAL_ROBOTEST_FILES", tests) if t := r.robolectricProperties.Test_options.Timeout; t != nil { fmt.Fprintln(w, "LOCAL_ROBOTEST_TIMEOUT :=", *t) diff --git a/java/sdk.go b/java/sdk.go index 8b4918add..7fa604fdb 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -28,7 +28,7 @@ import ( func init() { android.RegisterPreSingletonType("sdk_versions", sdkPreSingletonFactory) - android.RegisterSingletonType("sdk", sdkSingletonFactory) + android.RegisterParallelSingletonType("sdk", sdkSingletonFactory) android.RegisterMakeVarsProvider(pctx, sdkMakeVars) } diff --git a/java/sdk_library.go b/java/sdk_library.go index 103f1ace7..89da19a19 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -156,6 +156,9 @@ type apiScope struct { // Whether the api scope can be treated as unstable, and should skip compat checks. unstable bool + + // Represents the SDK kind of this scope. + kind android.SdkKind } // Initialize a scope, creating and adding appropriate dependency tags @@ -229,6 +232,10 @@ func (scope *apiScope) stubsLibraryModuleNameSuffix() string { return ".stubs" + scope.moduleSuffix } +func (scope *apiScope) apiLibraryModuleName(baseName string) string { + return scope.stubsLibraryModuleName(baseName) + ".from-text" +} + func (scope *apiScope) stubsLibraryModuleName(baseName string) string { return baseName + scope.stubsLibraryModuleNameSuffix() } @@ -289,6 +296,7 @@ var ( return &module.sdkLibraryProperties.Public }, sdkVersion: "current", + kind: android.SdkPublic, }) apiScopeSystem = initApiScope(&apiScope{ name: "system", @@ -301,6 +309,7 @@ var ( moduleSuffix: ".system", sdkVersion: "system_current", annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS)", + kind: android.SdkSystem, }) apiScopeTest = initApiScope(&apiScope{ name: "test", @@ -314,6 +323,7 @@ var ( sdkVersion: "test_current", annotation: "android.annotation.TestApi", unstable: true, + kind: android.SdkTest, }) apiScopeModuleLib = initApiScope(&apiScope{ name: "module-lib", @@ -331,6 +341,7 @@ var ( moduleSuffix: ".module_lib", sdkVersion: "module_current", annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES)", + kind: android.SdkModule, }) apiScopeSystemServer = initApiScope(&apiScope{ name: "system-server", @@ -361,6 +372,7 @@ var ( // com.android.* classes are okay in this interface" "--hide", "InternalClasses", }, + kind: android.SdkSystemServer, }) allApiScopes = apiScopes{ apiScopePublic, @@ -842,6 +854,13 @@ func (c *commonToSdkLibraryAndImport) stubsSourceModuleName(apiScope *apiScope) return c.namingScheme.stubsSourceModuleName(apiScope, baseName) } +// Name of the java_api_library module that generates the from-text stubs source +// and compiles to a jar file. +func (c *commonToSdkLibraryAndImport) apiLibraryModuleName(apiScope *apiScope) string { + baseName := c.module.BaseModuleName() + return c.namingScheme.apiLibraryModuleName(apiScope, baseName) +} + // The component names for different outputs of the java_sdk_library. // // They are similar to the names used for the child modules it creates @@ -1269,7 +1288,9 @@ func (module *SdkLibrary) ComponentDepsMutator(ctx android.BottomUpMutatorContex // Add dependencies to the stubs library stubModuleName := module.stubsLibraryModuleName(apiScope) // Use JavaApiLibraryName function to be redirected to stubs generated from .txt if applicable - stubModuleName = android.JavaApiLibraryName(ctx.Config(), stubModuleName) + if module.contributesToApiSurface(ctx.Config()) { + stubModuleName = android.JavaApiLibraryName(ctx.Config(), stubModuleName) + } ctx.AddVariationDependencies(nil, apiScope.stubsTag, stubModuleName) // Add a dependency on the stubs source in order to access both stubs source and api information. @@ -1477,6 +1498,11 @@ func (module *SdkLibrary) latestIncompatibilitiesModuleName(apiScope *apiScope) return latestPrebuiltApiModuleName(module.distStem()+"-incompatibilities", apiScope) } +func (module *SdkLibrary) contributesToApiSurface(c android.Config) bool { + _, exists := c.GetApiLibraries()[module.Name()] + return exists +} + func childModuleVisibility(childVisibility []string) []string { if childVisibility == nil { // No child visibility set. The child will use the visibility of the sdk_library. @@ -1758,6 +1784,46 @@ func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookC mctx.CreateModule(DroidstubsFactory, &props).(*Droidstubs).CallHookIfAvailable(mctx) } +func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) { + props := struct { + Name *string + Visibility []string + Api_contributions []string + Libs []string + Static_libs []string + Dep_api_srcs *string + }{} + + props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope)) + props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility) + + apiContributions := []string{} + + // Api surfaces are not independent of each other, but have subset relationships, + // and so does the api files. To generate from-text stubs for api surfaces other than public, + // all subset api domains' api_contriubtions must be added as well. + scope := apiScope + for scope != nil { + apiContributions = append(apiContributions, module.stubsSourceModuleName(scope)+".api.contribution") + scope = scope.extends + } + + props.Api_contributions = apiContributions + props.Libs = module.properties.Libs + props.Libs = append(props.Libs, module.sdkLibraryProperties.Stub_only_libs...) + props.Libs = append(props.Libs, "stub-annotations") + props.Static_libs = module.sdkLibraryProperties.Stub_only_static_libs + props.Dep_api_srcs = proptools.StringPtr(apiScope.kind.DefaultJavaLibraryName() + ".from-text") + + // android_module_lib_stubs_current.from-text only comprises api contributions from art, conscrypt and i18n. + // Thus, replace with android_module_lib_stubs_current_full.from-text, which comprises every api domains. + if apiScope.kind == android.SdkModule { + props.Dep_api_srcs = proptools.StringPtr(apiScope.kind.DefaultJavaLibraryName() + "_full.from-text") + } + + mctx.CreateModule(ApiLibraryFactory, &props) +} + func (module *SdkLibrary) compareAgainstLatestApi(apiScope *apiScope) bool { return !(apiScope.unstable || module.sdkLibraryProperties.Unsafe_ignore_missing_latest_api) } @@ -1954,6 +2020,10 @@ func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookCont module.createStubsSourcesAndApi(mctx, scope, module.stubsSourceModuleName(scope), scope.droidstubsArgs) module.createStubsLibrary(mctx, scope) + + if module.contributesToApiSurface(mctx.Config()) { + module.createApiLibrary(mctx, scope) + } } if module.requiresRuntimeImplementationLibrary() { @@ -2006,6 +2076,8 @@ type sdkLibraryComponentNamingScheme interface { stubsLibraryModuleName(scope *apiScope, baseName string) string stubsSourceModuleName(scope *apiScope, baseName string) string + + apiLibraryModuleName(scope *apiScope, baseName string) string } type defaultNamingScheme struct { @@ -2019,6 +2091,10 @@ func (s *defaultNamingScheme) stubsSourceModuleName(scope *apiScope, baseName st return scope.stubsSourceModuleName(baseName) } +func (s *defaultNamingScheme) apiLibraryModuleName(scope *apiScope, baseName string) string { + return scope.apiLibraryModuleName(baseName) +} + var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil) func moduleStubLinkType(name string) (stub bool, ret sdkLinkType) { diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index 1d0c13d4b..141e16bf7 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -35,6 +35,9 @@ func TestJavaSdkLibrary(t *testing.T) { "29": {"foo"}, "30": {"bar", "barney", "baz", "betty", "foo", "fred", "quuz", "wilma"}, }), + android.FixtureModifyConfig(func(config android.Config) { + config.SetApiLibraries([]string{"foo"}) + }), ).RunTestWithBp(t, ` droiddoc_exported_dir { name: "droiddoc-templates-sdk", @@ -121,6 +124,7 @@ func TestJavaSdkLibrary(t *testing.T) { result.ModuleForTests(apiScopeSystem.stubsSourceModuleName("foo"), "android_common") result.ModuleForTests(apiScopeTest.stubsSourceModuleName("foo"), "android_common") result.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo")+".api.contribution", "") + result.ModuleForTests(apiScopePublic.apiLibraryModuleName("foo"), "android_common") result.ModuleForTests("foo"+sdkXmlFileSuffix, "android_common") result.ModuleForTests("foo.api.public.28", "") result.ModuleForTests("foo.api.system.28", "") @@ -1412,3 +1416,62 @@ func TestJavaSdkLibrary_StubOnlyLibs_PassedToDroidstubs(t *testing.T) { fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs) android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs, "bar-lib") } + +func TestJavaSdkLibrary_ApiLibrary(t *testing.T) { + result := android.GroupFixturePreparers( + prepareForJavaTest, + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo"), + android.FixtureModifyConfig(func(config android.Config) { + config.SetApiLibraries([]string{"foo"}) + }), + ).RunTestWithBp(t, ` + java_sdk_library { + name: "foo", + srcs: ["a.java", "b.java"], + api_packages: ["foo"], + system: { + enabled: true, + }, + module_lib: { + enabled: true, + }, + test: { + enabled: true, + }, + } + `) + + testCases := []struct { + scope *apiScope + apiContributions []string + depApiSrcs string + }{ + { + scope: apiScopePublic, + apiContributions: []string{"foo.stubs.source.api.contribution"}, + depApiSrcs: "android_stubs_current.from-text", + }, + { + scope: apiScopeSystem, + apiContributions: []string{"foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, + depApiSrcs: "android_system_stubs_current.from-text", + }, + { + scope: apiScopeTest, + apiContributions: []string{"foo.stubs.source.test.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, + depApiSrcs: "android_test_stubs_current.from-text", + }, + { + scope: apiScopeModuleLib, + apiContributions: []string{"foo.stubs.source.module_lib.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, + depApiSrcs: "android_module_lib_stubs_current_full.from-text", + }, + } + + for _, c := range testCases { + m := result.ModuleForTests(c.scope.apiLibraryModuleName("foo"), "android_common").Module().(*ApiLibrary) + android.AssertArrayString(t, "Module expected to contain api contributions", c.apiContributions, m.properties.Api_contributions) + android.AssertStringEquals(t, "Module expected to contain full api surface api library", c.depApiSrcs, *m.properties.Dep_api_srcs) + } +} diff --git a/java/testing.go b/java/testing.go index 6671bf0c7..3a238d76f 100644 --- a/java/testing.go +++ b/java/testing.go @@ -71,7 +71,12 @@ var prepareForTestWithFrameworkDeps = android.GroupFixturePreparers( // Needed for framework defaultJavaDir + "/framework/aidl": nil, // Needed for various deps defined in GatherRequiredDepsForTest() - defaultJavaDir + "/a.java": nil, + defaultJavaDir + "/a.java": nil, + defaultJavaDir + "/api/current.txt": nil, + defaultJavaDir + "/api/system-current.txt": nil, + defaultJavaDir + "/api/test-current.txt": nil, + defaultJavaDir + "/api/module-lib-current.txt": nil, + defaultJavaDir + "/api/system-server-current.txt": nil, // Needed for R8 rules on apps "build/make/core/proguard.flags": nil, @@ -395,16 +400,20 @@ func gatherRequiredDepsForTest() string { } extraApiLibraryModules := map[string]string{ - "android_stubs_current.from-text": "api/current.txt", - "android_system_stubs_current.from-text": "api/system-current.txt", - "android_test_stubs_current.from-text": "api/test-current.txt", - "android_module_lib_stubs_current.from-text": "api/module-lib-current.txt", - "android_module_lib_stubs_current_full.from-text": "api/module-lib-current.txt", - "android_system_server_stubs_current.from-text": "api/system-server-current.txt", - "core.current.stubs.from-text": "api/current.txt", - "legacy.core.platform.api.stubs.from-text": "api/current.txt", - "stable.core.platform.api.stubs.from-text": "api/current.txt", - "core-lambda-stubs.from-text": "api/current.txt", + "android_stubs_current.from-text": "api/current.txt", + "android_system_stubs_current.from-text": "api/system-current.txt", + "android_test_stubs_current.from-text": "api/test-current.txt", + "android_module_lib_stubs_current.from-text": "api/module-lib-current.txt", + "android_module_lib_stubs_current_full.from-text": "api/module-lib-current.txt", + "android_system_server_stubs_current.from-text": "api/system-server-current.txt", + "core.current.stubs.from-text": "api/current.txt", + "legacy.core.platform.api.stubs.from-text": "api/current.txt", + "stable.core.platform.api.stubs.from-text": "api/current.txt", + "core-lambda-stubs.from-text": "api/current.txt", + "android-non-updatable.stubs.from-text": "api/current.txt", + "android-non-updatable.stubs.system.from-text": "api/system-current.txt", + "android-non-updatable.stubs.test.from-text": "api/test-current.txt", + "android-non-updatable.stubs.module_lib.from-text": "api/module-lib-current.txt", } for libName, apiFile := range extraApiLibraryModules { |