diff --git a/apex/apex_test.go b/apex/apex_test.go index 0d5bad445..219d58b31 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -7101,7 +7101,7 @@ func TestJavaSDKLibrary_WithinApex(t *testing.T) { java_library { name: "bar", srcs: ["a.java"], - libs: ["foo"], + libs: ["foo.impl"], apex_available: ["myapex"], sdk_version: "none", system_modules: "none", @@ -7154,7 +7154,7 @@ func TestJavaSDKLibrary_CrossBoundary(t *testing.T) { java_library { name: "bar", srcs: ["a.java"], - libs: ["foo"], + libs: ["foo.stubs"], sdk_version: "none", system_modules: "none", } @@ -7208,7 +7208,7 @@ func TestJavaSDKLibrary_ImportPreferred(t *testing.T) { java_library { name: "bar", srcs: ["a.java"], - libs: ["foo"], + libs: ["foo.impl"], apex_available: ["myapex"], sdk_version: "none", system_modules: "none", diff --git a/java/app_test.go b/java/app_test.go index ec97a553f..d7f5f0c62 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -3241,7 +3241,7 @@ func TestUsesLibraries(t *testing.T) { java_library { name: "static-runtime-helper", srcs: ["a.java"], - libs: ["runtime-library"], + libs: ["runtime-library.impl"], sdk_version: "current", } @@ -3305,7 +3305,7 @@ func TestUsesLibraries(t *testing.T) { name: "app", srcs: ["a.java"], libs: [ - "qux", + "qux.impl", "quuz.stubs" ], static_libs: [ diff --git a/java/base.go b/java/base.go index 86ed0e745..b64eb5b61 100644 --- a/java/base.go +++ b/java/base.go @@ -2414,18 +2414,13 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { return } - if dep, ok := module.(SdkLibraryDependency); ok { + if _, ok := module.(SdkLibraryDependency); ok { switch tag { - case sdkLibTag, libTag: - depHeaderJars := dep.SdkHeaderJars(ctx, j.SdkVersion(ctx)) - deps.classpath = append(deps.classpath, depHeaderJars...) - deps.dexClasspath = append(deps.dexClasspath, depHeaderJars...) - - // TODO: SDK libraries should export a provider with TransitiveClasspathHeaderJars - depHeaderJarsSet := android.NewDepSet(android.PREORDER, depHeaderJars, nil) - transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, depHeaderJarsSet) - case staticLibTag: - ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName) + case sdkLibTag, libTag, staticLibTag: + sdkInfo, _ := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider) + generatingLibsString := android.PrettyConcat( + getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or") + ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString) } } else if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { if sdkLinkType != javaPlatform { diff --git a/java/droiddoc.go b/java/droiddoc.go index 2929bb8d9..a7e92d9ef 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -373,8 +373,11 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName())) } case libTag, sdkLibTag: - if dep, ok := module.(SdkLibraryDependency); ok { - deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...) + if _, ok := module.(SdkLibraryDependency); ok { + sdkInfo, _ := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider) + generatingLibsString := android.PrettyConcat( + getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or") + ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString) } else if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { deps.classpath = append(deps.classpath, dep.HeaderJars...) deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...) diff --git a/java/java.go b/java/java.go index d63bbe6e1..b6d617377 100644 --- a/java/java.go +++ b/java/java.go @@ -2700,13 +2700,13 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars) } } - } else if dep, ok := module.(SdkLibraryDependency); ok { + } else if _, ok := module.(SdkLibraryDependency); ok { switch tag { case libTag, sdkLibTag: - depHeaderJars := dep.SdkHeaderJars(ctx, j.SdkVersion(ctx)) - flags.classpath = append(flags.classpath, depHeaderJars...) - transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, - android.NewDepSet(android.PREORDER, depHeaderJars, nil)) + sdkInfo, _ := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider) + generatingLibsString := android.PrettyConcat( + getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or") + ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString) } } diff --git a/java/java_test.go b/java/java_test.go index c13db3e30..e0fd0f24e 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -670,7 +670,7 @@ func TestPrebuilts(t *testing.T) { java_library { name: "foo", srcs: ["a.java", ":stubs-source"], - libs: ["bar", "sdklib"], + libs: ["bar", "sdklib.stubs"], static_libs: ["baz"], } diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go index 00613eee3..527e479f2 100644 --- a/java/prebuilt_apis.go +++ b/java/prebuilt_apis.go @@ -124,8 +124,8 @@ func parseFinalizedPrebuiltPath(ctx android.LoadHookContext, p string, allowIncr return } -func prebuiltApiModuleName(mctx android.LoadHookContext, module, scope, version string) string { - return fmt.Sprintf("%s_%s_%s_%s", mctx.ModuleName(), scope, version, module) +func prebuiltApiModuleName(moduleName, module, scope, version string) string { + return fmt.Sprintf("%s_%s_%s_%s", moduleName, scope, version, module) } func createImport(mctx android.LoadHookContext, module, scope, version, path, sdkVersion string, compileDex bool) { props := struct { @@ -135,7 +135,7 @@ func createImport(mctx android.LoadHookContext, module, scope, version, path, sd Installable *bool Compile_dex *bool }{ - Name: proptools.StringPtr(prebuiltApiModuleName(mctx, module, scope, version)), + Name: proptools.StringPtr(prebuiltApiModuleName(mctx.ModuleName(), module, scope, version)), Jars: []string{path}, Sdk_version: proptools.StringPtr(sdkVersion), Installable: proptools.BoolPtr(false), @@ -257,8 +257,8 @@ func createSystemModules(mctx android.LoadHookContext, version, scope string) { Name *string Libs []string }{} - props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx, "system_modules", scope, version)) - props.Libs = append(props.Libs, prebuiltApiModuleName(mctx, "core-for-system-modules", scope, version)) + props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx.ModuleName(), "system_modules", scope, version)) + props.Libs = append(props.Libs, prebuiltApiModuleName(mctx.ModuleName(), "core-for-system-modules", scope, version)) mctx.CreateModule(systemModulesImportFactory, &props) } diff --git a/java/sdk_library.go b/java/sdk_library.go index 9f0564a9c..c3ffb46d5 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -268,10 +268,6 @@ func (scope *apiScope) stubsSourceModuleName(baseName string) string { return baseName + ".stubs.source" + scope.moduleSuffix } -func (scope *apiScope) apiModuleName(baseName string) string { - return baseName + ".api" + scope.moduleSuffix -} - func (scope *apiScope) String() string { return scope.name } @@ -1082,21 +1078,6 @@ func (c *commonToSdkLibraryAndImport) findClosestScopePath(scope *apiScope) *sco return nil } -func (c *commonToSdkLibraryAndImport) selectHeaderJarsForSdkVersion(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths { - - // If a specific numeric version has been requested then use prebuilt versions of the sdk. - if !sdkVersion.ApiLevel.IsPreview() { - return PrebuiltJars(ctx, c.module.RootLibraryName(), sdkVersion) - } - - paths := c.selectScopePaths(ctx, sdkVersion.Kind) - if paths == nil { - return nil - } - - return paths.stubsHeaderPath -} - // selectScopePaths returns the *scopePaths appropriate for the specific kind. // // If the module does not support the specific kind then it will return the *scopePaths for the @@ -1263,12 +1244,6 @@ var _ SdkLibraryComponentDependency = (*SdkLibraryImport)(nil) type SdkLibraryDependency interface { SdkLibraryComponentDependency - // Get the header jars appropriate for the supplied sdk_version. - // - // These are turbine generated jars so they only change if the externals of the - // class changes but it does not contain and implementation or JavaDoc. - SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths - // SdkApiStubDexJar returns the dex jar for the stubs for the prebuilt // java_sdk_library_import module. It is needed by the hiddenapi processing tool which // processes dex files. @@ -1285,9 +1260,36 @@ type SdkLibraryDependency interface { // sharedLibrary returns true if this can be used as a shared library. sharedLibrary() bool + // getImplLibraryModule returns the pointer to the implementation library submodule of this + // sdk library. getImplLibraryModule() *Library } +type SdkLibraryInfo struct { + // GeneratingLibs is the names of the library modules that this sdk library + // generates. Note that this only includes the name of the modules that other modules can + // depend on, and is not a holistic list of generated modules. + GeneratingLibs []string +} + +var SdkLibraryInfoProvider = blueprint.NewProvider[SdkLibraryInfo]() + +func getGeneratingLibs(ctx android.ModuleContext, sdkVersion android.SdkSpec, sdkLibraryModuleName string, sdkInfo SdkLibraryInfo) []string { + apiLevel := sdkVersion.ApiLevel + if apiLevel.IsPreview() { + return sdkInfo.GeneratingLibs + } + + generatingPrebuilts := []string{} + for _, apiScope := range AllApiScopes { + scopePrebuiltModuleName := prebuiltApiModuleName("sdk", sdkLibraryModuleName, apiScope.name, apiLevel.String()) + if ctx.OtherModuleExists(scopePrebuiltModuleName) { + generatingPrebuilts = append(generatingPrebuilts, scopePrebuiltModuleName) + } + } + return generatingPrebuilts +} + type SdkLibrary struct { Library @@ -1610,9 +1612,22 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) } android.SetProvider(ctx, android.AdditionalSdkInfoProvider, android.AdditionalSdkInfo{additionalSdkInfo}) module.setOutputFiles(ctx) + + var generatingLibs []string + for _, apiScope := range AllApiScopes { + if _, ok := module.scopePaths[apiScope]; ok { + generatingLibs = append(generatingLibs, module.stubsLibraryModuleName(apiScope)) + } + } + if module.requiresRuntimeImplementationLibrary() && module.implLibraryModule != nil { + generatingLibs = append(generatingLibs, module.implLibraryModuleName()) setOutputFiles(ctx, module.implLibraryModule.Module) } + + android.SetProvider(ctx, SdkLibraryInfoProvider, SdkLibraryInfo{ + GeneratingLibs: generatingLibs, + }) } func (module *SdkLibrary) BuiltInstalledForApex() []dexpreopterInstall { @@ -2192,72 +2207,6 @@ func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) { mctx.CreateModule(sdkLibraryXmlFactory, &props) } -func PrebuiltJars(ctx android.BaseModuleContext, baseName string, s android.SdkSpec) android.Paths { - var ver android.ApiLevel - var kind android.SdkKind - if s.UsePrebuilt(ctx) { - ver = s.ApiLevel - kind = s.Kind - } else { - // We don't have prebuilt SDK for the specific sdkVersion. - // Instead of breaking the build, fallback to use "system_current" - ver = android.FutureApiLevel - kind = android.SdkSystem - } - - dir := filepath.Join("prebuilts", "sdk", ver.String(), kind.String()) - jar := filepath.Join(dir, baseName+".jar") - jarPath := android.ExistentPathForSource(ctx, jar) - if !jarPath.Valid() { - if ctx.Config().AllowMissingDependencies() { - return android.Paths{android.PathForSource(ctx, jar)} - } else { - ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", s.Raw, jar) - } - return nil - } - return android.Paths{jarPath.Path()} -} - -// Check to see if the other module is within the same set of named APEXes as this module. -// -// If either this or the other module are on the platform then this will return -// false. -func withinSameApexesAs(ctx android.BaseModuleContext, other android.Module) bool { - apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) - otherApexInfo, _ := android.OtherModuleProvider(ctx, other, android.ApexInfoProvider) - return len(otherApexInfo.InApexVariants) > 0 && reflect.DeepEqual(apexInfo.InApexVariants, otherApexInfo.InApexVariants) -} - -func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths { - // If the client doesn't set sdk_version, but if this library prefers stubs over - // the impl library, let's provide the widest API surface possible. To do so, - // force override sdk_version to module_current so that the closest possible API - // surface could be found in selectHeaderJarsForSdkVersion - if module.defaultsToStubs() && !sdkVersion.Specified() { - sdkVersion = android.SdkSpecFrom(ctx, "module_current") - } - - // Only provide access to the implementation library if it is actually built. - if module.requiresRuntimeImplementationLibrary() { - // Check any special cases for java_sdk_library. - // - // Only allow access to the implementation library in the following condition: - // * No sdk_version specified on the referencing module. - // * The referencing module is in the same apex as this. - if sdkVersion.Kind == android.SdkPrivate || withinSameApexesAs(ctx, module) { - return module.implLibraryHeaderJars - } - } - - return module.selectHeaderJarsForSdkVersion(ctx, sdkVersion) -} - -// to satisfy SdkLibraryDependency interface -func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths { - return module.sdkJars(ctx, sdkVersion) -} - var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries") func javaSdkLibraries(config android.Config) *[]string { @@ -2376,10 +2325,6 @@ func (module *SdkLibrary) requiresRuntimeImplementationLibrary() bool { return !proptools.Bool(module.sdkLibraryProperties.Api_only) } -func (module *SdkLibrary) defaultsToStubs() bool { - return proptools.Bool(module.sdkLibraryProperties.Default_to_stubs) -} - func moduleStubLinkType(j *Module) (stub bool, ret sdkLinkType) { kind := android.ToSdkKind(proptools.String(j.properties.Stub_contributing_api)) switch kind { @@ -2860,32 +2805,25 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo } } - module.setOutputFiles(ctx) - if module.implLibraryModule != nil { - setOutputFiles(ctx, module.implLibraryModule.Module) - } -} - -func (module *SdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec, headerJars bool) android.Paths { - - // For consistency with SdkLibrary make the implementation jar available to libraries that - // are within the same APEX. - implLibraryModule := module.implLibraryModule - if implLibraryModule != nil && withinSameApexesAs(ctx, module) { - if headerJars { - return implLibraryModule.HeaderJars() - } else { - return implLibraryModule.ImplementationJars() + var generatingLibs []string + for _, apiScope := range AllApiScopes { + if scopeProperties, ok := module.scopeProperties[apiScope]; ok { + if len(scopeProperties.Jars) == 0 { + continue + } + generatingLibs = append(generatingLibs, module.stubsLibraryModuleName(apiScope)) } } - return module.selectHeaderJarsForSdkVersion(ctx, sdkVersion) -} + module.setOutputFiles(ctx) + if module.implLibraryModule != nil { + generatingLibs = append(generatingLibs, module.implLibraryModuleName()) + setOutputFiles(ctx, module.implLibraryModule.Module) + } -// to satisfy SdkLibraryDependency interface -func (module *SdkLibraryImport) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths { - // This module is just a wrapper for the prebuilt stubs. - return module.sdkJars(ctx, sdkVersion, true) + android.SetProvider(ctx, SdkLibraryInfoProvider, SdkLibraryInfo{ + GeneratingLibs: generatingLibs, + }) } // to satisfy UsesLibraryDependency interface diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index 31fbc5a58..6031d7230 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -22,8 +22,6 @@ import ( "testing" "android/soong/android" - - "github.com/google/blueprint/proptools" ) func TestJavaSdkLibrary(t *testing.T) { @@ -55,7 +53,7 @@ func TestJavaSdkLibrary(t *testing.T) { java_library { name: "baz", srcs: ["c.java"], - libs: ["foo", "bar.stubs"], + libs: ["foo.stubs.system", "bar.stubs"], sdk_version: "system_current", } java_sdk_library { @@ -92,25 +90,25 @@ func TestJavaSdkLibrary(t *testing.T) { java_library { name: "qux", srcs: ["c.java"], - libs: ["baz", "fred", "quuz.stubs", "wilma", "barney", "betty"], + libs: ["baz", "fred.stubs", "quuz.stubs", "wilma.stubs", "barney.stubs.system", "betty.stubs.system"], sdk_version: "system_current", } java_library { name: "baz-test", srcs: ["c.java"], - libs: ["foo"], + libs: ["foo.stubs.test"], sdk_version: "test_current", } java_library { name: "baz-29", srcs: ["c.java"], - libs: ["foo"], + libs: ["sdk_system_29_foo"], sdk_version: "system_29", } java_library { name: "baz-module-30", srcs: ["c.java"], - libs: ["foo"], + libs: ["sdk_module-lib_30_foo"], sdk_version: "module_30", } `) @@ -162,11 +160,11 @@ func TestJavaSdkLibrary(t *testing.T) { baz29Javac := result.ModuleForTests("baz-29", "android_common").Rule("javac") // tests if baz-29 is actually linked to the system 29 stubs lib - android.AssertStringDoesContain(t, "baz-29 javac classpath", baz29Javac.Args["classpath"], "prebuilts/sdk/29/system/foo.jar") + android.AssertStringDoesContain(t, "baz-29 javac classpath", baz29Javac.Args["classpath"], "prebuilts/sdk/sdk_system_29_foo/android_common/combined/sdk_system_29_foo.jar") bazModule30Javac := result.ModuleForTests("baz-module-30", "android_common").Rule("javac") // tests if "baz-module-30" is actually linked to the module 30 stubs lib - android.AssertStringDoesContain(t, "baz-module-30 javac classpath", bazModule30Javac.Args["classpath"], "prebuilts/sdk/30/module-lib/foo.jar") + android.AssertStringDoesContain(t, "baz-module-30 javac classpath", bazModule30Javac.Args["classpath"], "prebuilts/sdk/sdk_module-lib_30_foo/android_common/combined/sdk_module-lib_30_foo.jar") // test if baz has exported SDK lib names foo and bar to qux qux := result.ModuleForTests("qux", "android_common") @@ -445,7 +443,7 @@ func TestJavaSdkLibrary_DoNotAccessImplWhenItIsNotBuilt(t *testing.T) { java_library { name: "bar", srcs: ["b.java"], - libs: ["foo"], + libs: ["foo.stubs"], } `) @@ -763,7 +761,7 @@ func TestJavaSdkLibrary_SystemServer_AccessToStubScopeLibs(t *testing.T) { java_library { name: "bar", srcs: ["a.java"], - libs: ["foo-public", "foo-system", "foo-module-lib", "foo-system-server"], + libs: ["foo-public.stubs", "foo-system.stubs.system", "foo-module-lib.stubs.module_lib", "foo-system-server.stubs.system_server"], sdk_version: "system_server_current", } `) @@ -789,102 +787,26 @@ func TestJavaSdkLibrary_SystemServer_AccessToStubScopeLibs(t *testing.T) { } } -func TestJavaSdkLibrary_MissingScope(t *testing.T) { - prepareForJavaTest. - ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`requires api scope module-lib from foo but it only has \[\] available`)). - RunTestWithBp(t, ` - java_sdk_library { - name: "foo", - srcs: ["a.java"], - public: { - enabled: false, - }, - } - - java_library { - name: "baz", - srcs: ["a.java"], - libs: ["foo"], - sdk_version: "module_current", - } - `) -} - -func TestJavaSdkLibrary_FallbackScope(t *testing.T) { - android.GroupFixturePreparers( - prepareForJavaTest, - PrepareForTestWithJavaSdkLibraryFiles, - FixtureWithLastReleaseApis("foo"), - ).RunTestWithBp(t, ` - java_sdk_library { - name: "foo", - srcs: ["a.java"], - system: { - enabled: true, - }, - } - - java_library { - name: "baz", - srcs: ["a.java"], - libs: ["foo"], - // foo does not have module-lib scope so it should fallback to system - sdk_version: "module_current", - } - `) -} - -func TestJavaSdkLibrary_DefaultToStubs(t *testing.T) { - result := android.GroupFixturePreparers( - prepareForJavaTest, - PrepareForTestWithJavaSdkLibraryFiles, - FixtureWithLastReleaseApis("foo"), - ).RunTestWithBp(t, ` - java_sdk_library { - name: "foo", - srcs: ["a.java"], - system: { - enabled: true, - }, - default_to_stubs: true, - } - - java_library { - name: "baz", - srcs: ["a.java"], - libs: ["foo"], - // does not have sdk_version set, should fallback to module, - // which will then fallback to system because the module scope - // is not enabled. - } - `) - // The baz library should depend on the system stubs jar. - bazLibrary := result.ModuleForTests("baz", "android_common").Rule("javac") - if expected, actual := `^-classpath .*:out/soong/[^:]*/turbine-combined/foo\.stubs.system\.jar$`, bazLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { - t.Errorf("expected %q, found %#q", expected, actual) - } -} - func TestJavaSdkLibraryImport(t *testing.T) { result := prepareForJavaTest.RunTestWithBp(t, ` java_library { name: "foo", srcs: ["a.java"], - libs: ["sdklib"], + libs: ["sdklib.stubs"], sdk_version: "current", } java_library { name: "foo.system", srcs: ["a.java"], - libs: ["sdklib"], + libs: ["sdklib.stubs.system"], sdk_version: "system_current", } java_library { name: "foo.test", srcs: ["a.java"], - libs: ["sdklib"], + libs: ["sdklib.stubs.test"], sdk_version: "test_current", } @@ -1017,7 +939,7 @@ func testJavaSdkLibraryImport_Preferred(t *testing.T, prefer string, preparer an java_library { name: "public", srcs: ["a.java"], - libs: ["sdklib"], + libs: ["sdklib.stubs"], sdk_version: "current", } `) @@ -1190,155 +1112,6 @@ func TestSdkLibraryImport_MetadataModuleSupersedesPreferred(t *testing.T) { } } -func TestJavaSdkLibraryEnforce(t *testing.T) { - partitionToBpOption := func(partition string) string { - switch partition { - case "system": - return "" - case "vendor": - return "soc_specific: true," - case "product": - return "product_specific: true," - default: - panic("Invalid partition group name: " + partition) - } - } - - type testConfigInfo struct { - libraryType string - fromPartition string - toPartition string - enforceProductInterface bool - enforceJavaSdkLibraryCheck bool - allowList []string - } - - createPreparer := func(info testConfigInfo) android.FixturePreparer { - bpFileTemplate := ` - java_library { - name: "foo", - srcs: ["foo.java"], - libs: ["bar"], - sdk_version: "current", - %s - } - - %s { - name: "bar", - srcs: ["bar.java"], - sdk_version: "current", - %s - } - ` - - bpFile := fmt.Sprintf(bpFileTemplate, - partitionToBpOption(info.fromPartition), - info.libraryType, - partitionToBpOption(info.toPartition)) - - return android.GroupFixturePreparers( - PrepareForTestWithJavaSdkLibraryFiles, - FixtureWithLastReleaseApis("bar"), - android.FixtureWithRootAndroidBp(bpFile), - android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { - variables.EnforceProductPartitionInterface = proptools.BoolPtr(info.enforceProductInterface) - variables.EnforceInterPartitionJavaSdkLibrary = proptools.BoolPtr(info.enforceJavaSdkLibraryCheck) - variables.InterPartitionJavaLibraryAllowList = info.allowList - }), - ) - } - - runTest := func(t *testing.T, info testConfigInfo, expectedErrorPattern string) { - t.Run(fmt.Sprintf("%v", info), func(t *testing.T) { - errorHandler := android.FixtureExpectsNoErrors - if expectedErrorPattern != "" { - errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(expectedErrorPattern) - } - android.GroupFixturePreparers( - prepareForJavaTest, - createPreparer(info), - ). - ExtendWithErrorHandler(errorHandler). - RunTest(t) - }) - } - - errorMessage := "is not allowed across the partitions" - - runTest(t, testConfigInfo{ - libraryType: "java_library", - fromPartition: "product", - toPartition: "system", - enforceProductInterface: true, - enforceJavaSdkLibraryCheck: false, - }, "") - - runTest(t, testConfigInfo{ - libraryType: "java_library", - fromPartition: "product", - toPartition: "system", - enforceProductInterface: false, - enforceJavaSdkLibraryCheck: true, - }, "") - - runTest(t, testConfigInfo{ - libraryType: "java_library", - fromPartition: "product", - toPartition: "system", - enforceProductInterface: true, - enforceJavaSdkLibraryCheck: true, - }, errorMessage) - - runTest(t, testConfigInfo{ - libraryType: "java_library", - fromPartition: "vendor", - toPartition: "system", - enforceProductInterface: true, - enforceJavaSdkLibraryCheck: true, - }, errorMessage) - - runTest(t, testConfigInfo{ - libraryType: "java_library", - fromPartition: "vendor", - toPartition: "system", - enforceProductInterface: true, - enforceJavaSdkLibraryCheck: true, - allowList: []string{"bar"}, - }, "") - - runTest(t, testConfigInfo{ - libraryType: "java_library", - fromPartition: "vendor", - toPartition: "product", - enforceProductInterface: true, - enforceJavaSdkLibraryCheck: true, - }, errorMessage) - - runTest(t, testConfigInfo{ - libraryType: "java_sdk_library", - fromPartition: "product", - toPartition: "system", - enforceProductInterface: true, - enforceJavaSdkLibraryCheck: true, - }, "") - - runTest(t, testConfigInfo{ - libraryType: "java_sdk_library", - fromPartition: "vendor", - toPartition: "system", - enforceProductInterface: true, - enforceJavaSdkLibraryCheck: true, - }, "") - - runTest(t, testConfigInfo{ - libraryType: "java_sdk_library", - fromPartition: "vendor", - toPartition: "product", - enforceProductInterface: true, - enforceJavaSdkLibraryCheck: true, - }, "") -} - func TestJavaSdkLibraryDist(t *testing.T) { result := android.GroupFixturePreparers( PrepareForTestWithJavaBuildComponents, @@ -1657,7 +1430,7 @@ func TestSdkLibraryDependency(t *testing.T) { name: "bar", srcs: ["c.java", "b.java"], libs: [ - "foo", + "foo.stubs", ], uses_libs: [ "foo", @@ -1752,7 +1525,7 @@ func TestStubResolutionOfJavaSdkLibraryInLibs(t *testing.T) { name: "mymodule", srcs: ["a.java"], sdk_version: "current", - libs: ["sdklib",], // this should be dynamically resolved to sdklib.stubs (source) or prebuilt_sdklib.stubs (prebuilt) + libs: ["sdklib.stubs",], // this should be dynamically resolved to sdklib.stubs (source) or prebuilt_sdklib.stubs (prebuilt) } ` @@ -1893,3 +1666,111 @@ func TestStubLinkType(t *testing.T) { } `) } + +func TestSdkLibDirectDependency(t *testing.T) { + android.GroupFixturePreparers( + prepareForJavaTest, + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo", "bar"), + ).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern([]string{ + `module "baz" variant "android_common": cannot depend directly on java_sdk_library ` + + `"foo"; try depending on "foo.stubs", or "foo.impl" instead`, + `module "baz" variant "android_common": cannot depend directly on java_sdk_library ` + + `"prebuilt_bar"; try depending on "bar.stubs", or "bar.impl" instead`, + }), + ).RunTestWithBp(t, ` + java_sdk_library { + name: "foo", + srcs: ["a.java"], + sdk_version: "current", + public: { + enabled: true, + }, + } + + java_sdk_library_import { + name: "foo", + public: { + jars: ["a.jar"], + stub_srcs: ["a.java"], + current_api: "current.txt", + removed_api: "removed.txt", + annotations: "annotations.zip", + }, + } + + java_sdk_library { + name: "bar", + srcs: ["a.java"], + sdk_version: "current", + public: { + enabled: true, + }, + } + + java_sdk_library_import { + name: "bar", + prefer: true, + public: { + jars: ["a.jar"], + stub_srcs: ["a.java"], + current_api: "current.txt", + removed_api: "removed.txt", + annotations: "annotations.zip", + }, + } + + java_library { + name: "baz", + srcs: ["b.java"], + libs: [ + "foo", + "bar", + ], + } + `) +} + +func TestSdkLibDirectDependencyWithPrebuiltSdk(t *testing.T) { + android.GroupFixturePreparers( + prepareForJavaTest, + PrepareForTestWithJavaSdkLibraryFiles, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.Platform_sdk_version = intPtr(34) + variables.Platform_sdk_codename = stringPtr("VanillaIceCream") + variables.Platform_version_active_codenames = []string{"VanillaIceCream"} + variables.Platform_systemsdk_versions = []string{"33", "34", "VanillaIceCream"} + variables.DeviceSystemSdkVersions = []string{"VanillaIceCream"} + }), + FixtureWithPrebuiltApis(map[string][]string{ + "33": {"foo"}, + "34": {"foo"}, + "35": {"foo"}, + }), + ).ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern( + `module "baz" variant "android_common": cannot depend directly on java_sdk_library "foo"; `+ + `try depending on "sdk_public_33_foo", "sdk_system_33_foo", "sdk_test_33_foo", `+ + `"sdk_module-lib_33_foo", or "sdk_system-server_33_foo" instead`), + ).RunTestWithBp(t, ` + java_sdk_library { + name: "foo", + srcs: ["a.java"], + sdk_version: "current", + public: { + enabled: true, + }, + system: { + enabled: true, + }, + } + + java_library { + name: "baz", + srcs: ["b.java"], + libs: [ + "foo", + ], + sdk_version: "system_33", + } + `) +}