diff options
Diffstat (limited to 'java')
| -rw-r--r-- | java/aar.go | 30 | ||||
| -rw-r--r-- | java/app_test.go | 37 | ||||
| -rw-r--r-- | java/config/Android.bp | 1 | ||||
| -rw-r--r-- | java/config/droidstubs.go | 85 | ||||
| -rw-r--r-- | java/core-libraries/Android.bp | 1 | ||||
| -rw-r--r-- | java/droidstubs.go | 48 | ||||
| -rw-r--r-- | java/droidstubs_test.go | 2 | ||||
| -rw-r--r-- | java/java.go | 43 | ||||
| -rw-r--r-- | java/java_test.go | 216 | ||||
| -rw-r--r-- | java/sdk_library.go | 10 |
10 files changed, 384 insertions, 89 deletions
diff --git a/java/aar.go b/java/aar.go index 85a6fbb96..368f2416a 100644 --- a/java/aar.go +++ b/java/aar.go @@ -66,6 +66,9 @@ type aaptProperties struct { // ones. Aapt_include_all_resources *bool + // list of files to use as assets. + Assets []string `android:"path"` + // list of directories relative to the Blueprints file containing assets. // Defaults to ["assets"] if a directory called assets exists. Set to [] // to disable the default. @@ -192,6 +195,11 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkConte linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...) // Find implicit or explicit asset and resource dirs + assets := android.PathsRelativeToModuleSourceDir(android.SourceInput{ + Context: ctx, + Paths: a.aaptProperties.Assets, + IncludeDirs: false, + }) assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets") resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res") resourceZips := android.PathsForModuleSrc(ctx, a.aaptProperties.Resource_zips) @@ -226,6 +234,28 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkConte assetDirStrings = append(assetDirStrings, filepath.Dir(a.noticeFile.Path().String())) assetDeps = append(assetDeps, a.noticeFile.Path()) } + if len(assets) > 0 { + // aapt2 doesn't support adding individual asset files. Create a temp directory to hold asset + // files and pass it to aapt2. + tmpAssetDir := android.PathForModuleOut(ctx, "tmp_asset_dir") + + rule := android.NewRuleBuilder(pctx, ctx) + rule.Command(). + Text("rm -rf").Text(tmpAssetDir.String()). + Text("&&"). + Text("mkdir -p").Text(tmpAssetDir.String()) + + for _, asset := range assets { + output := tmpAssetDir.Join(ctx, asset.Rel()) + assetDeps = append(assetDeps, output) + rule.Command().Text("mkdir -p").Text(filepath.Dir(output.String())) + rule.Command().Text("cp").Input(asset).Output(output) + } + + rule.Build("tmp_asset_dir", "tmp_asset_dir") + + assetDirStrings = append(assetDirStrings, tmpAssetDir.String()) + } linkFlags = append(linkFlags, "--manifest "+manifestPath.String()) linkDeps = append(linkDeps, manifestPath) diff --git a/java/app_test.go b/java/app_test.go index e38a7247b..4d3b2dc4d 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -608,6 +608,15 @@ func TestLibraryAssets(t *testing.T) { asset_dirs: ["assets_b"], } + android_library { + name: "lib5", + sdk_version: "current", + assets: [ + "path/to/asset_file_1", + "path/to/asset_file_2", + ], + } + android_library_import { name: "import", sdk_version: "current", @@ -616,9 +625,11 @@ func TestLibraryAssets(t *testing.T) { ` testCases := []struct { - name string - assetFlag string - assetPackages []string + name string + assetFlag string + assetPackages []string + tmpAssetDirInputs []string + tmpAssetDirOutputs []string }{ { name: "foo", @@ -644,6 +655,18 @@ func TestLibraryAssets(t *testing.T) { name: "lib4", assetFlag: "-A assets_b", }, + { + name: "lib5", + assetFlag: "-A out/soong/.intermediates/lib5/android_common/tmp_asset_dir", + tmpAssetDirInputs: []string{ + "path/to/asset_file_1", + "path/to/asset_file_2", + }, + tmpAssetDirOutputs: []string{ + "out/soong/.intermediates/lib5/android_common/tmp_asset_dir/path/to/asset_file_1", + "out/soong/.intermediates/lib5/android_common/tmp_asset_dir/path/to/asset_file_2", + }, + }, } ctx := testApp(t, bp) @@ -671,6 +694,14 @@ func TestLibraryAssets(t *testing.T) { mergeAssets := m.Output("package-res.apk") android.AssertPathsRelativeToTopEquals(t, "mergeAssets inputs", test.assetPackages, mergeAssets.Inputs) } + + if len(test.tmpAssetDirInputs) > 0 { + rule := m.Rule("tmp_asset_dir") + inputs := rule.Implicits + outputs := append(android.WritablePaths{rule.Output}, rule.ImplicitOutputs...).Paths() + android.AssertPathsRelativeToTopEquals(t, "tmp_asset_dir inputs", test.tmpAssetDirInputs, inputs) + android.AssertPathsRelativeToTopEquals(t, "tmp_asset_dir outputs", test.tmpAssetDirOutputs, outputs) + } }) } } diff --git a/java/config/Android.bp b/java/config/Android.bp index 194e2c6ed..bfe83ab8c 100644 --- a/java/config/Android.bp +++ b/java/config/Android.bp @@ -12,6 +12,7 @@ bootstrap_go_package { ], srcs: [ "config.go", + "droidstubs.go", "error_prone.go", "kotlin.go", "makevars.go", diff --git a/java/config/droidstubs.go b/java/config/droidstubs.go new file mode 100644 index 000000000..59cee1d61 --- /dev/null +++ b/java/config/droidstubs.go @@ -0,0 +1,85 @@ +// Copyright 2023 Google Inc. All rights reserved. +// +// 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 config + +import "strings" + +var ( + metalavaFlags = []string{ + "--color", + "--quiet", + "--format=v2", + "--repeat-errors-max 10", + "--hide UnresolvedImport", + "--hide InvalidNullabilityOverride", + // b/223382732 + "--hide ChangedDefault", + + // Force metalava to ignore classes on the classpath when an API file contains missing classes. + // See b/285140653 for more information. + "--api-class-resolution api", + + // Force metalava to sort overloaded methods by their order in the source code. + // See b/285312164 for more information. + // And add concrete overrides of abstract methods, see b/299366704 for more + // information. + "--format-defaults overloaded-method-order=source,add-additional-overrides=yes", + } + + MetalavaFlags = strings.Join(metalavaFlags, " ") + + metalavaAnnotationsFlags = []string{ + "--include-annotations", + "--exclude-annotation androidx.annotation.RequiresApi", + } + + MetalavaAnnotationsFlags = strings.Join(metalavaAnnotationsFlags, " ") + + metalavaAnnotationsWarningsFlags = []string{ + // TODO(tnorbye): find owners to fix these warnings when annotation was enabled. + "--hide HiddenTypedefConstant", + "--hide SuperfluousPrefix", + "--hide AnnotationExtraction", + // b/222738070 + "--hide BannedThrow", + // b/223382732 + "--hide ChangedDefault", + } + + MetalavaAnnotationsWarningsFlags = strings.Join(metalavaAnnotationsWarningsFlags, " ") + + metalavaHideFlaggedApis = []string{ + "--hide-annotation", + "android.annotation.FlaggedApi", + } + + MetalavaHideFlaggedApis = strings.Join(metalavaHideFlaggedApis, " ") +) + +const ( + MetalavaAddOpens = "-J--add-opens=java.base/java.util=ALL-UNNAMED" +) + +func init() { + exportedVars.ExportStringList("MetalavaFlags", metalavaFlags) + + exportedVars.ExportString("MetalavaAddOpens", MetalavaAddOpens) + + exportedVars.ExportStringList("MetalavaHideFlaggedApis", metalavaHideFlaggedApis) + + exportedVars.ExportStringListStaticVariable("MetalavaAnnotationsFlags", metalavaAnnotationsFlags) + + exportedVars.ExportStringListStaticVariable("MetalavaAnnotationWarningsFlags", metalavaAnnotationsWarningsFlags) +} diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp index 4380f4f5c..8b7387a85 100644 --- a/java/core-libraries/Android.bp +++ b/java/core-libraries/Android.bp @@ -66,6 +66,7 @@ java_api_library { libs: [ "stub-annotations", ], + enable_validation: false, } java_library { diff --git a/java/droidstubs.go b/java/droidstubs.go index 5432ce7f5..8039d0515 100644 --- a/java/droidstubs.go +++ b/java/droidstubs.go @@ -122,7 +122,7 @@ type DroidstubsProperties struct { Generate_stubs *bool // if set to true, provides a hint to the build system that this rule uses a lot of memory, - // whicih can be used for scheduling purposes + // which can be used for scheduling purposes High_mem *bool // if set to true, Metalava will allow framework SDK to contain API levels annotations. @@ -171,6 +171,10 @@ type ApiStubsProvider interface { ApiStubsSrcProvider } +type currentApiTimestampProvider interface { + CurrentApiTimestamp() android.Path +} + // droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be // documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to // a droiddoc module to generate documentation. @@ -238,10 +242,15 @@ func (d *Droidstubs) StubsSrcJar() android.Path { return d.stubsSrcJar } +func (d *Droidstubs) CurrentApiTimestamp() android.Path { + return d.checkCurrentApiTimestamp +} + var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"} var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"} var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"} var metalavaAPILevelsModuleTag = dependencyTag{name: "metalava-api-levels-module-tag"} +var metalavaCurrentApiTimestampTag = dependencyTag{name: "metalava-current-api-timestamp-tag"} func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) { d.Javadoc.addDeps(ctx) @@ -313,9 +322,7 @@ func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuil func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) { if Bool(d.properties.Annotations_enabled) { - cmd.Flag("--include-annotations") - - cmd.FlagWithArg("--exclude-annotation ", "androidx.annotation.RequiresApi") + cmd.Flag(config.MetalavaAnnotationsFlags) validatingNullability := strings.Contains(String(d.Javadoc.properties.Args), "--validate-nullability-from-merged-stubs") || @@ -343,14 +350,7 @@ func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.Ru d.mergeAnnoDirFlags(ctx, cmd) } - // TODO(tnorbye): find owners to fix these warnings when annotation was enabled. - cmd.FlagWithArg("--hide ", "HiddenTypedefConstant"). - FlagWithArg("--hide ", "SuperfluousPrefix"). - FlagWithArg("--hide ", "AnnotationExtraction"). - // b/222738070 - FlagWithArg("--hide ", "BannedThrow"). - // b/223382732 - FlagWithArg("--hide ", "ChangedDefault") + cmd.Flag(config.MetalavaAnnotationsWarningsFlags) } } @@ -510,7 +510,7 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")). Flag(config.JavacVmFlags). - Flag("-J--add-opens=java.base/java.util=ALL-UNNAMED"). + Flag(config.MetalavaAddOpens). FlagWithArg("--java-source ", javaVersion.String()). FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "metalava.rsp"), srcs). FlagWithInput("@", srcJarList) @@ -523,27 +523,9 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi cmd.FlagWithInputList("--classpath ", combinedPaths, ":") } - cmd.Flag("--color"). - Flag("--quiet"). - Flag("--format=v2"). - FlagWithArg("--repeat-errors-max ", "10"). - FlagWithArg("--hide ", "UnresolvedImport"). - FlagWithArg("--hide ", "InvalidNullabilityOverride"). - // b/223382732 - FlagWithArg("--hide ", "ChangedDefault") - - // Force metalava to ignore classes on the classpath when an API file contains missing classes. - // See b/285140653 for more information. - cmd.FlagWithArg("--api-class-resolution ", "api") - - // Force metalava to sort overloaded methods by their order in the source code. - // See b/285312164 for more information. - // And add concrete overrides of abstract methods, see b/299366704 for more - // information. - cmd.FlagWithArg("--format-defaults ", "overloaded-method-order=source,add-additional-overrides=yes") - + cmd.Flag(config.MetalavaFlags) if ctx.DeviceConfig().HideFlaggedApis() { - cmd.FlagWithArg("--hide-annotation ", "android.annotation.FlaggedApi") + cmd.Flag(config.MetalavaHideFlaggedApis) } return cmd diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go index e149b9893..f86e1acef 100644 --- a/java/droidstubs_test.go +++ b/java/droidstubs_test.go @@ -392,7 +392,7 @@ func TestGeneratedApiContributionVisibilityTest(t *testing.T) { removed_api_file: "A/removed.txt", } }, - visibility: ["//a"], + visibility: ["//a", "//b"], } `, map[string][]byte{ diff --git a/java/java.go b/java/java.go index 3b20ea406..990a084f7 100644 --- a/java/java.go +++ b/java/java.go @@ -1664,6 +1664,8 @@ type ApiLibrary struct { extractedSrcJar android.WritablePath // .dex of stubs, used for hiddenapi processing dexJarFile OptionalDexJarPath + + validationPaths android.Paths } type JavaApiLibraryProperties struct { @@ -1699,6 +1701,12 @@ type JavaApiLibraryProperties struct { // The jar will also be passed to metalava as a classpath to // generate compilable stubs. System_modules *string + + // If true, the module runs validation on the API signature files provided + // by the modules passed via api_contributions by checking if the files are + // in sync with the source Java files. However, the environment variable + // DISABLE_STUB_VALIDATION has precedence over this property. + Enable_validation *bool } func ApiLibraryFactory() android.Module { @@ -1787,6 +1795,12 @@ func (al *ApiLibrary) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBui } } +func (al *ApiLibrary) addValidation(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, validationPaths android.Paths) { + for _, validationPath := range validationPaths { + cmd.Validation(validationPath) + } +} + // This method extracts the stub class files from the stub jar file provided // from full_api_surface_stub module instead of compiling the srcjar generated from invoking metalava. // This method is used because metalava can generate compilable from-text stubs only when @@ -1823,8 +1837,28 @@ func (al *ApiLibrary) extractApiSrcs(ctx android.ModuleContext, rule *android.Ru func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { apiContributions := al.properties.Api_contributions + addValidations := !ctx.Config().IsEnvTrue("DISABLE_STUB_VALIDATION") && + proptools.BoolDefault(al.properties.Enable_validation, true) for _, apiContributionName := range apiContributions { ctx.AddDependency(ctx.Module(), javaApiContributionTag, apiContributionName) + + // Add the java_api_contribution module generating droidstubs module + // as dependency when validation adding conditions are met and + // the java_api_contribution module name has ".api.contribution" suffix. + // All droidstubs-generated modules possess the suffix in the name, + // but there is no such guarantee for tests. + if addValidations { + if strings.HasSuffix(apiContributionName, ".api.contribution") { + ctx.AddDependency(ctx.Module(), metalavaCurrentApiTimestampTag, strings.TrimSuffix(apiContributionName, ".api.contribution")) + } else { + ctx.ModuleErrorf("Validation is enabled for module %s but a "+ + "current timestamp provider is not found for the api "+ + "contribution %s", + ctx.ModuleName(), + apiContributionName, + ) + } + } } ctx.AddVariationDependencies(nil, libTag, al.properties.Libs...) ctx.AddVariationDependencies(nil, staticLibTag, al.properties.Static_libs...) @@ -1862,8 +1896,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { android.PathForModuleOut(ctx, "metalava.sbox.textproto")). SandboxInputs() - var stubsDir android.OptionalPath - stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, "metalava", "stubsDir")) + stubsDir := android.OptionalPathForPath(android.PathForModuleOut(ctx, "metalava", "stubsDir")) rule.Command().Text("rm -rf").Text(stubsDir.String()) rule.Command().Text("mkdir -p").Text(stubsDir.String()) @@ -1895,6 +1928,10 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { case systemModulesTag: module := dep.(SystemModulesProvider) systemModulesPaths = append(systemModulesPaths, module.HeaderJars()...) + case metalavaCurrentApiTimestampTag: + if currentApiTimestampProvider, ok := dep.(currentApiTimestampProvider); ok { + al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp()) + } } }) @@ -1918,6 +1955,8 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { cmd.FlagWithInput("--migrate-nullness ", previousApi) } + al.addValidation(ctx, cmd, al.validationPaths) + al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar") al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, "metalava", "stubs.jar") al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName())) diff --git a/java/java_test.go b/java/java_test.go index 6b8b735f7..c4fc55bc4 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -1847,9 +1847,17 @@ func TestDeviceBinaryWrapperGeneration(t *testing.T) { } func TestJavaApiContributionEmptyApiFile(t *testing.T) { - testJavaError(t, + android.GroupFixturePreparers( + prepareForJavaTest, + android.FixtureMergeEnv( + map[string]string{ + "DISABLE_STUB_VALIDATION": "true", + }, + ), + ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( "Error: foo has an empty api file.", - `java_api_contribution { + )).RunTestWithBp(t, ` + java_api_contribution { name: "foo", } java_api_library { @@ -1874,7 +1882,20 @@ func TestJavaApiLibraryAndProviderLink(t *testing.T) { api_surface: "public", } ` - ctx, _ := testJavaWithFS(t, ` + ctx := android.GroupFixturePreparers( + prepareForJavaTest, + android.FixtureMergeMockFs( + map[string][]byte{ + "a/Android.bp": []byte(provider_bp_a), + "b/Android.bp": []byte(provider_bp_b), + }, + ), + android.FixtureMergeEnv( + map[string]string{ + "DISABLE_STUB_VALIDATION": "true", + }, + ), + ).RunTestWithBp(t, ` java_api_library { name: "bar1", api_surface: "public", @@ -1886,11 +1907,7 @@ func TestJavaApiLibraryAndProviderLink(t *testing.T) { api_surface: "system", api_contributions: ["foo1", "foo2"], } - `, - map[string][]byte{ - "a/Android.bp": []byte(provider_bp_a), - "b/Android.bp": []byte(provider_bp_b), - }) + `) testcases := []struct { moduleName string @@ -1944,7 +1961,22 @@ func TestJavaApiLibraryAndDefaultsLink(t *testing.T) { api_surface: "system", } ` - ctx, _ := testJavaWithFS(t, ` + ctx := android.GroupFixturePreparers( + prepareForJavaTest, + android.FixtureMergeMockFs( + map[string][]byte{ + "a/Android.bp": []byte(provider_bp_a), + "b/Android.bp": []byte(provider_bp_b), + "c/Android.bp": []byte(provider_bp_c), + "d/Android.bp": []byte(provider_bp_d), + }, + ), + android.FixtureMergeEnv( + map[string]string{ + "DISABLE_STUB_VALIDATION": "true", + }, + ), + ).RunTestWithBp(t, ` java_defaults { name: "baz1", api_surface: "public", @@ -1975,13 +2007,7 @@ func TestJavaApiLibraryAndDefaultsLink(t *testing.T) { defaults:["baz1", "baz2"], api_contributions: ["foo4"], } - `, - map[string][]byte{ - "a/Android.bp": []byte(provider_bp_a), - "b/Android.bp": []byte(provider_bp_b), - "c/Android.bp": []byte(provider_bp_c), - "d/Android.bp": []byte(provider_bp_d), - }) + `) testcases := []struct { moduleName string @@ -2026,7 +2052,20 @@ func TestJavaApiLibraryJarGeneration(t *testing.T) { api_surface: "public", } ` - ctx, _ := testJavaWithFS(t, ` + ctx := android.GroupFixturePreparers( + prepareForJavaTest, + android.FixtureMergeMockFs( + map[string][]byte{ + "a/Android.bp": []byte(provider_bp_a), + "b/Android.bp": []byte(provider_bp_b), + }, + ), + android.FixtureMergeEnv( + map[string]string{ + "DISABLE_STUB_VALIDATION": "true", + }, + ), + ).RunTestWithBp(t, ` java_api_library { name: "bar1", api_surface: "public", @@ -2038,11 +2077,7 @@ func TestJavaApiLibraryJarGeneration(t *testing.T) { api_surface: "system", api_contributions: ["foo1", "foo2"], } - `, - map[string][]byte{ - "a/Android.bp": []byte(provider_bp_a), - "b/Android.bp": []byte(provider_bp_b), - }) + `) testcases := []struct { moduleName string @@ -2094,7 +2129,24 @@ func TestJavaApiLibraryLibsLink(t *testing.T) { } ` - ctx, _ := testJavaWithFS(t, ` + ctx := android.GroupFixturePreparers( + prepareForJavaTest, + android.FixtureMergeMockFs( + map[string][]byte{ + "a/Android.bp": []byte(provider_bp_a), + "b/Android.bp": []byte(provider_bp_b), + "c/Android.bp": []byte(lib_bp_a), + "c/Lib.java": {}, + "d/Android.bp": []byte(lib_bp_b), + "d/Lib.java": {}, + }, + ), + android.FixtureMergeEnv( + map[string]string{ + "DISABLE_STUB_VALIDATION": "true", + }, + ), + ).RunTestWithBp(t, ` java_api_library { name: "bar1", api_surface: "public", @@ -2108,15 +2160,7 @@ func TestJavaApiLibraryLibsLink(t *testing.T) { api_contributions: ["foo1", "foo2"], libs: ["lib1", "lib2", "bar1"], } - `, - map[string][]byte{ - "a/Android.bp": []byte(provider_bp_a), - "b/Android.bp": []byte(provider_bp_b), - "c/Android.bp": []byte(lib_bp_a), - "c/Lib.java": {}, - "d/Android.bp": []byte(lib_bp_b), - "d/Lib.java": {}, - }) + `) testcases := []struct { moduleName string @@ -2171,7 +2215,24 @@ func TestJavaApiLibraryStaticLibsLink(t *testing.T) { } ` - ctx, _ := testJavaWithFS(t, ` + ctx := android.GroupFixturePreparers( + prepareForJavaTest, + android.FixtureMergeMockFs( + map[string][]byte{ + "a/Android.bp": []byte(provider_bp_a), + "b/Android.bp": []byte(provider_bp_b), + "c/Android.bp": []byte(lib_bp_a), + "c/Lib.java": {}, + "d/Android.bp": []byte(lib_bp_b), + "d/Lib.java": {}, + }, + ), + android.FixtureMergeEnv( + map[string]string{ + "DISABLE_STUB_VALIDATION": "true", + }, + ), + ).RunTestWithBp(t, ` java_api_library { name: "bar1", api_surface: "public", @@ -2185,15 +2246,7 @@ func TestJavaApiLibraryStaticLibsLink(t *testing.T) { api_contributions: ["foo1", "foo2"], static_libs: ["lib1", "lib2", "bar1"], } - `, - map[string][]byte{ - "a/Android.bp": []byte(provider_bp_a), - "b/Android.bp": []byte(provider_bp_b), - "c/Android.bp": []byte(lib_bp_a), - "c/Lib.java": {}, - "d/Android.bp": []byte(lib_bp_b), - "d/Lib.java": {}, - }) + `) testcases := []struct { moduleName string @@ -2242,19 +2295,28 @@ func TestJavaApiLibraryFullApiSurfaceStub(t *testing.T) { } ` - ctx, _ := testJavaWithFS(t, ` + ctx := android.GroupFixturePreparers( + prepareForJavaTest, + android.FixtureMergeMockFs( + map[string][]byte{ + "a/Android.bp": []byte(provider_bp_a), + "b/Android.bp": []byte(provider_bp_b), + "c/Android.bp": []byte(lib_bp_a), + }, + ), + android.FixtureMergeEnv( + map[string]string{ + "DISABLE_STUB_VALIDATION": "true", + }, + ), + ).RunTestWithBp(t, ` java_api_library { name: "bar1", api_surface: "public", api_contributions: ["foo1"], full_api_surface_stub: "lib1", } - `, - map[string][]byte{ - "a/Android.bp": []byte(provider_bp_a), - "b/Android.bp": []byte(provider_bp_b), - "c/Android.bp": []byte(lib_bp_a), - }) + `) m := ctx.ModuleForTests("bar1", "android_common") manifest := m.Output("metalava.sbox.textproto") @@ -2402,7 +2464,14 @@ func TestHeadersOnly(t *testing.T) { } func TestJavaApiContributionImport(t *testing.T) { - ctx, _ := testJava(t, ` + ctx := android.GroupFixturePreparers( + prepareForJavaTest, + android.FixtureMergeEnv( + map[string]string{ + "DISABLE_STUB_VALIDATION": "true", + }, + ), + ).RunTestWithBp(t, ` java_api_library { name: "foo", api_contributions: ["bar"], @@ -2483,3 +2552,50 @@ func TestSdkLibraryProvidesSystemModulesToApiLibrary(t *testing.T) { classPathFlag := "--classpath __SBOX_SANDBOX_DIR__/out/.intermediates/bar/android_common/turbine-combined/bar.jar" android.AssertStringDoesContain(t, "command expected to contain classpath flag", manifestCommand, classPathFlag) } + +func TestApiLibraryDroidstubsDependency(t *testing.T) { + result := android.GroupFixturePreparers( + prepareForJavaTest, + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo"), + android.FixtureModifyConfig(func(config android.Config) { + config.SetApiLibraries([]string{"foo"}) + }), + android.FixtureMergeMockFs( + map[string][]byte{ + "A.java": nil, + }, + ), + ).RunTestWithBp(t, ` + java_api_library { + name: "foo", + api_contributions: [ + "api-stubs-docs-non-updatable.api.contribution", + ], + enable_validation: true, + } + java_api_library { + name: "bar", + api_contributions: [ + "api-stubs-docs-non-updatable.api.contribution", + ], + enable_validation: false, + } + `) + + currentApiTimestampPath := "api-stubs-docs-non-updatable/android_common/metalava/check_current_api.timestamp" + foo := result.ModuleForTests("foo", "android_common").Module().(*ApiLibrary) + fooValidationPathsString := strings.Join(foo.validationPaths.Strings(), " ") + bar := result.ModuleForTests("bar", "android_common").Module().(*ApiLibrary) + barValidationPathsString := strings.Join(bar.validationPaths.Strings(), " ") + android.AssertStringDoesContain(t, + "Module expected to have validation", + fooValidationPathsString, + currentApiTimestampPath, + ) + android.AssertStringDoesNotContain(t, + "Module expected to not have validation", + barValidationPathsString, + currentApiTimestampPath, + ) +} diff --git a/java/sdk_library.go b/java/sdk_library.go index f72c6086f..041aeb786 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1838,6 +1838,7 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, Static_libs []string Full_api_surface_stub *string System_modules *string + Enable_validation *bool }{} props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope)) @@ -1876,7 +1877,16 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, props.Full_api_surface_stub = proptools.StringPtr(apiScope.kind.DefaultJavaLibraryName() + "_full.from-text") } + // java_sdk_library modules that set sdk_version as none does not depend on other api + // domains. Therefore, java_api_library created from such modules should not depend on + // full_api_surface_stubs but create and compile stubs by the java_api_library module + // itself. + if module.SdkVersion(mctx).Kind == android.SdkNone { + props.Full_api_surface_stub = nil + } + props.System_modules = module.deviceProperties.System_modules + props.Enable_validation = proptools.BoolPtr(true) mctx.CreateModule(ApiLibraryFactory, &props) } |