Merge changes Ica0cb5a5,If432cdc6,Idb4b0b0a into main

* changes:
  Revert^2 "Remove java_sdk_library "magic""
  Revert^2 "Restrict java_sdk_library in libs of java_import and droidstubs modules"
  Revert^2 "Restrict java_sdk_library in libs"
This commit is contained in:
Jihoon Kang
2024-09-23 17:09:43 +00:00
committed by Gerrit Code Review
9 changed files with 205 additions and 388 deletions

View File

@@ -7101,7 +7101,7 @@ func TestJavaSDKLibrary_WithinApex(t *testing.T) {
java_library { java_library {
name: "bar", name: "bar",
srcs: ["a.java"], srcs: ["a.java"],
libs: ["foo"], libs: ["foo.impl"],
apex_available: ["myapex"], apex_available: ["myapex"],
sdk_version: "none", sdk_version: "none",
system_modules: "none", system_modules: "none",
@@ -7154,7 +7154,7 @@ func TestJavaSDKLibrary_CrossBoundary(t *testing.T) {
java_library { java_library {
name: "bar", name: "bar",
srcs: ["a.java"], srcs: ["a.java"],
libs: ["foo"], libs: ["foo.stubs"],
sdk_version: "none", sdk_version: "none",
system_modules: "none", system_modules: "none",
} }
@@ -7208,7 +7208,7 @@ func TestJavaSDKLibrary_ImportPreferred(t *testing.T) {
java_library { java_library {
name: "bar", name: "bar",
srcs: ["a.java"], srcs: ["a.java"],
libs: ["foo"], libs: ["foo.impl"],
apex_available: ["myapex"], apex_available: ["myapex"],
sdk_version: "none", sdk_version: "none",
system_modules: "none", system_modules: "none",

View File

@@ -3241,7 +3241,7 @@ func TestUsesLibraries(t *testing.T) {
java_library { java_library {
name: "static-runtime-helper", name: "static-runtime-helper",
srcs: ["a.java"], srcs: ["a.java"],
libs: ["runtime-library"], libs: ["runtime-library.impl"],
sdk_version: "current", sdk_version: "current",
} }
@@ -3305,7 +3305,7 @@ func TestUsesLibraries(t *testing.T) {
name: "app", name: "app",
srcs: ["a.java"], srcs: ["a.java"],
libs: [ libs: [
"qux", "qux.impl",
"quuz.stubs" "quuz.stubs"
], ],
static_libs: [ static_libs: [

View File

@@ -2414,18 +2414,13 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
return return
} }
if dep, ok := module.(SdkLibraryDependency); ok { if _, ok := module.(SdkLibraryDependency); ok {
switch tag { switch tag {
case sdkLibTag, libTag: case sdkLibTag, libTag, staticLibTag:
depHeaderJars := dep.SdkHeaderJars(ctx, j.SdkVersion(ctx)) sdkInfo, _ := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider)
deps.classpath = append(deps.classpath, depHeaderJars...) generatingLibsString := android.PrettyConcat(
deps.dexClasspath = append(deps.dexClasspath, depHeaderJars...) 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)
// 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)
} }
} else if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { } else if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
if sdkLinkType != javaPlatform { if sdkLinkType != javaPlatform {

View File

@@ -373,8 +373,11 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName())) panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
} }
case libTag, sdkLibTag: case libTag, sdkLibTag:
if dep, ok := module.(SdkLibraryDependency); ok { if _, ok := module.(SdkLibraryDependency); ok {
deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...) 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 { } else if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
deps.classpath = append(deps.classpath, dep.HeaderJars...) deps.classpath = append(deps.classpath, dep.HeaderJars...)
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...) deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)

View File

@@ -2700,13 +2700,13 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars) transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
} }
} }
} else if dep, ok := module.(SdkLibraryDependency); ok { } else if _, ok := module.(SdkLibraryDependency); ok {
switch tag { switch tag {
case libTag, sdkLibTag: case libTag, sdkLibTag:
depHeaderJars := dep.SdkHeaderJars(ctx, j.SdkVersion(ctx)) sdkInfo, _ := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider)
flags.classpath = append(flags.classpath, depHeaderJars...) generatingLibsString := android.PrettyConcat(
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or")
android.NewDepSet(android.PREORDER, depHeaderJars, nil)) ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString)
} }
} }

View File

@@ -670,7 +670,7 @@ func TestPrebuilts(t *testing.T) {
java_library { java_library {
name: "foo", name: "foo",
srcs: ["a.java", ":stubs-source"], srcs: ["a.java", ":stubs-source"],
libs: ["bar", "sdklib"], libs: ["bar", "sdklib.stubs"],
static_libs: ["baz"], static_libs: ["baz"],
} }

View File

@@ -124,8 +124,8 @@ func parseFinalizedPrebuiltPath(ctx android.LoadHookContext, p string, allowIncr
return return
} }
func prebuiltApiModuleName(mctx android.LoadHookContext, module, scope, version string) string { func prebuiltApiModuleName(moduleName, module, scope, version string) string {
return fmt.Sprintf("%s_%s_%s_%s", mctx.ModuleName(), scope, version, module) return fmt.Sprintf("%s_%s_%s_%s", moduleName, scope, version, module)
} }
func createImport(mctx android.LoadHookContext, module, scope, version, path, sdkVersion string, compileDex bool) { func createImport(mctx android.LoadHookContext, module, scope, version, path, sdkVersion string, compileDex bool) {
props := struct { props := struct {
@@ -135,7 +135,7 @@ func createImport(mctx android.LoadHookContext, module, scope, version, path, sd
Installable *bool Installable *bool
Compile_dex *bool Compile_dex *bool
}{ }{
Name: proptools.StringPtr(prebuiltApiModuleName(mctx, module, scope, version)), Name: proptools.StringPtr(prebuiltApiModuleName(mctx.ModuleName(), module, scope, version)),
Jars: []string{path}, Jars: []string{path},
Sdk_version: proptools.StringPtr(sdkVersion), Sdk_version: proptools.StringPtr(sdkVersion),
Installable: proptools.BoolPtr(false), Installable: proptools.BoolPtr(false),
@@ -257,8 +257,8 @@ func createSystemModules(mctx android.LoadHookContext, version, scope string) {
Name *string Name *string
Libs []string Libs []string
}{} }{}
props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx, "system_modules", scope, version)) props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx.ModuleName(), "system_modules", scope, version))
props.Libs = append(props.Libs, prebuiltApiModuleName(mctx, "core-for-system-modules", scope, version)) props.Libs = append(props.Libs, prebuiltApiModuleName(mctx.ModuleName(), "core-for-system-modules", scope, version))
mctx.CreateModule(systemModulesImportFactory, &props) mctx.CreateModule(systemModulesImportFactory, &props)
} }

View File

@@ -268,10 +268,6 @@ func (scope *apiScope) stubsSourceModuleName(baseName string) string {
return baseName + ".stubs.source" + scope.moduleSuffix return baseName + ".stubs.source" + scope.moduleSuffix
} }
func (scope *apiScope) apiModuleName(baseName string) string {
return baseName + ".api" + scope.moduleSuffix
}
func (scope *apiScope) String() string { func (scope *apiScope) String() string {
return scope.name return scope.name
} }
@@ -1082,21 +1078,6 @@ func (c *commonToSdkLibraryAndImport) findClosestScopePath(scope *apiScope) *sco
return nil 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. // 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 // 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 { type SdkLibraryDependency interface {
SdkLibraryComponentDependency 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 // 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 // java_sdk_library_import module. It is needed by the hiddenapi processing tool which
// processes dex files. // processes dex files.
@@ -1285,9 +1260,36 @@ type SdkLibraryDependency interface {
// sharedLibrary returns true if this can be used as a shared library. // sharedLibrary returns true if this can be used as a shared library.
sharedLibrary() bool sharedLibrary() bool
// getImplLibraryModule returns the pointer to the implementation library submodule of this
// sdk library.
getImplLibraryModule() *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 { type SdkLibrary struct {
Library Library
@@ -1610,9 +1612,22 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
} }
android.SetProvider(ctx, android.AdditionalSdkInfoProvider, android.AdditionalSdkInfo{additionalSdkInfo}) android.SetProvider(ctx, android.AdditionalSdkInfoProvider, android.AdditionalSdkInfo{additionalSdkInfo})
module.setOutputFiles(ctx) 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 { if module.requiresRuntimeImplementationLibrary() && module.implLibraryModule != nil {
generatingLibs = append(generatingLibs, module.implLibraryModuleName())
setOutputFiles(ctx, module.implLibraryModule.Module) setOutputFiles(ctx, module.implLibraryModule.Module)
} }
android.SetProvider(ctx, SdkLibraryInfoProvider, SdkLibraryInfo{
GeneratingLibs: generatingLibs,
})
} }
func (module *SdkLibrary) BuiltInstalledForApex() []dexpreopterInstall { func (module *SdkLibrary) BuiltInstalledForApex() []dexpreopterInstall {
@@ -2192,72 +2207,6 @@ func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) {
mctx.CreateModule(sdkLibraryXmlFactory, &props) 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") var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
func javaSdkLibraries(config android.Config) *[]string { func javaSdkLibraries(config android.Config) *[]string {
@@ -2376,10 +2325,6 @@ func (module *SdkLibrary) requiresRuntimeImplementationLibrary() bool {
return !proptools.Bool(module.sdkLibraryProperties.Api_only) 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) { func moduleStubLinkType(j *Module) (stub bool, ret sdkLinkType) {
kind := android.ToSdkKind(proptools.String(j.properties.Stub_contributing_api)) kind := android.ToSdkKind(proptools.String(j.properties.Stub_contributing_api))
switch kind { switch kind {
@@ -2860,32 +2805,25 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
} }
} }
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))
}
}
module.setOutputFiles(ctx) module.setOutputFiles(ctx)
if module.implLibraryModule != nil { if module.implLibraryModule != nil {
generatingLibs = append(generatingLibs, module.implLibraryModuleName())
setOutputFiles(ctx, module.implLibraryModule.Module) setOutputFiles(ctx, module.implLibraryModule.Module)
} }
}
func (module *SdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec, headerJars bool) android.Paths { android.SetProvider(ctx, SdkLibraryInfoProvider, SdkLibraryInfo{
GeneratingLibs: generatingLibs,
// 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()
}
}
return module.selectHeaderJarsForSdkVersion(ctx, sdkVersion)
}
// 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)
} }
// to satisfy UsesLibraryDependency interface // to satisfy UsesLibraryDependency interface

View File

@@ -22,8 +22,6 @@ import (
"testing" "testing"
"android/soong/android" "android/soong/android"
"github.com/google/blueprint/proptools"
) )
func TestJavaSdkLibrary(t *testing.T) { func TestJavaSdkLibrary(t *testing.T) {
@@ -55,7 +53,7 @@ func TestJavaSdkLibrary(t *testing.T) {
java_library { java_library {
name: "baz", name: "baz",
srcs: ["c.java"], srcs: ["c.java"],
libs: ["foo", "bar.stubs"], libs: ["foo.stubs.system", "bar.stubs"],
sdk_version: "system_current", sdk_version: "system_current",
} }
java_sdk_library { java_sdk_library {
@@ -92,25 +90,25 @@ func TestJavaSdkLibrary(t *testing.T) {
java_library { java_library {
name: "qux", name: "qux",
srcs: ["c.java"], 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", sdk_version: "system_current",
} }
java_library { java_library {
name: "baz-test", name: "baz-test",
srcs: ["c.java"], srcs: ["c.java"],
libs: ["foo"], libs: ["foo.stubs.test"],
sdk_version: "test_current", sdk_version: "test_current",
} }
java_library { java_library {
name: "baz-29", name: "baz-29",
srcs: ["c.java"], srcs: ["c.java"],
libs: ["foo"], libs: ["sdk_system_29_foo"],
sdk_version: "system_29", sdk_version: "system_29",
} }
java_library { java_library {
name: "baz-module-30", name: "baz-module-30",
srcs: ["c.java"], srcs: ["c.java"],
libs: ["foo"], libs: ["sdk_module-lib_30_foo"],
sdk_version: "module_30", sdk_version: "module_30",
} }
`) `)
@@ -162,11 +160,11 @@ func TestJavaSdkLibrary(t *testing.T) {
baz29Javac := result.ModuleForTests("baz-29", "android_common").Rule("javac") baz29Javac := result.ModuleForTests("baz-29", "android_common").Rule("javac")
// tests if baz-29 is actually linked to the system 29 stubs lib // 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") bazModule30Javac := result.ModuleForTests("baz-module-30", "android_common").Rule("javac")
// tests if "baz-module-30" is actually linked to the module 30 stubs lib // 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 // test if baz has exported SDK lib names foo and bar to qux
qux := result.ModuleForTests("qux", "android_common") qux := result.ModuleForTests("qux", "android_common")
@@ -445,7 +443,7 @@ func TestJavaSdkLibrary_DoNotAccessImplWhenItIsNotBuilt(t *testing.T) {
java_library { java_library {
name: "bar", name: "bar",
srcs: ["b.java"], srcs: ["b.java"],
libs: ["foo"], libs: ["foo.stubs"],
} }
`) `)
@@ -763,7 +761,7 @@ func TestJavaSdkLibrary_SystemServer_AccessToStubScopeLibs(t *testing.T) {
java_library { java_library {
name: "bar", name: "bar",
srcs: ["a.java"], 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", 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) { func TestJavaSdkLibraryImport(t *testing.T) {
result := prepareForJavaTest.RunTestWithBp(t, ` result := prepareForJavaTest.RunTestWithBp(t, `
java_library { java_library {
name: "foo", name: "foo",
srcs: ["a.java"], srcs: ["a.java"],
libs: ["sdklib"], libs: ["sdklib.stubs"],
sdk_version: "current", sdk_version: "current",
} }
java_library { java_library {
name: "foo.system", name: "foo.system",
srcs: ["a.java"], srcs: ["a.java"],
libs: ["sdklib"], libs: ["sdklib.stubs.system"],
sdk_version: "system_current", sdk_version: "system_current",
} }
java_library { java_library {
name: "foo.test", name: "foo.test",
srcs: ["a.java"], srcs: ["a.java"],
libs: ["sdklib"], libs: ["sdklib.stubs.test"],
sdk_version: "test_current", sdk_version: "test_current",
} }
@@ -1017,7 +939,7 @@ func testJavaSdkLibraryImport_Preferred(t *testing.T, prefer string, preparer an
java_library { java_library {
name: "public", name: "public",
srcs: ["a.java"], srcs: ["a.java"],
libs: ["sdklib"], libs: ["sdklib.stubs"],
sdk_version: "current", 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) { func TestJavaSdkLibraryDist(t *testing.T) {
result := android.GroupFixturePreparers( result := android.GroupFixturePreparers(
PrepareForTestWithJavaBuildComponents, PrepareForTestWithJavaBuildComponents,
@@ -1657,7 +1430,7 @@ func TestSdkLibraryDependency(t *testing.T) {
name: "bar", name: "bar",
srcs: ["c.java", "b.java"], srcs: ["c.java", "b.java"],
libs: [ libs: [
"foo", "foo.stubs",
], ],
uses_libs: [ uses_libs: [
"foo", "foo",
@@ -1752,7 +1525,7 @@ func TestStubResolutionOfJavaSdkLibraryInLibs(t *testing.T) {
name: "mymodule", name: "mymodule",
srcs: ["a.java"], srcs: ["a.java"],
sdk_version: "current", 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",
}
`)
}