Merge "Merge the "big 3" metalava invocations into one" into rvc-dev
diff --git a/java/app.go b/java/app.go
index eac76fd..ce618c3 100755
--- a/java/app.go
+++ b/java/app.go
@@ -129,6 +129,9 @@
// or an android_app_certificate module name in the form ":module".
Certificate *string
+ // Name of the signing certificate lineage file.
+ Lineage *string
+
// the package name of this app. The package name in the manifest file is used if one was not given.
Package_name *string
@@ -586,7 +589,11 @@
if v4SigningRequested {
v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
}
- CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile)
+ var lineageFile android.Path
+ if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
+ lineageFile = android.PathForModuleSrc(ctx, lineage)
+ }
+ CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile)
a.outputFile = packageFile
if v4SigningRequested {
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
@@ -598,7 +605,7 @@
if v4SigningRequested {
v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
}
- CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile)
+ CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile)
a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
if v4SigningRequested {
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
@@ -1249,7 +1256,7 @@
}
a.certificate = certificates[0]
signed := android.PathForModuleOut(ctx, "signed", apkFilename)
- SignAppPackage(ctx, signed, dexOutput, certificates, nil)
+ SignAppPackage(ctx, signed, dexOutput, certificates, nil, nil)
a.outputFile = signed
} else {
alignedApk := android.PathForModuleOut(ctx, "zip-aligned", apkFilename)
@@ -1488,7 +1495,7 @@
_, certificates := collectAppDeps(ctx, false, false)
certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx)
signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk")
- SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil)
+ SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil, nil)
r.certificate = certificates[0]
r.outputFile = signed
diff --git a/java/app_builder.go b/java/app_builder.go
index b2780bc..e8c16c2 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -45,7 +45,7 @@
})
func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
- packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, v4SignatureFile android.WritablePath) {
+ packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, v4SignatureFile android.WritablePath, lineageFile android.Path) {
unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk"
unsignedApk := android.PathForModuleOut(ctx, unsignedApkName)
@@ -66,10 +66,10 @@
Implicits: deps,
})
- SignAppPackage(ctx, outputFile, unsignedApk, certificates, v4SignatureFile)
+ SignAppPackage(ctx, outputFile, unsignedApk, certificates, v4SignatureFile, lineageFile)
}
-func SignAppPackage(ctx android.ModuleContext, signedApk android.WritablePath, unsignedApk android.Path, certificates []Certificate, v4SignatureFile android.WritablePath) {
+func SignAppPackage(ctx android.ModuleContext, signedApk android.WritablePath, unsignedApk android.Path, certificates []Certificate, v4SignatureFile android.WritablePath, lineageFile android.Path) {
var certificateArgs []string
var deps android.Paths
@@ -79,10 +79,14 @@
}
outputFiles := android.WritablePaths{signedApk}
- var flag string = ""
+ var flags []string
if v4SignatureFile != nil {
outputFiles = append(outputFiles, v4SignatureFile)
- flag = "--enable-v4"
+ flags = append(flags, "--enable-v4")
+ }
+
+ if lineageFile != nil {
+ flags = append(flags, "--lineage", lineageFile.String())
}
ctx.Build(pctx, android.BuildParams{
@@ -93,7 +97,7 @@
Implicits: deps,
Args: map[string]string{
"certificates": strings.Join(certificateArgs, " "),
- "flags": flag,
+ "flags": strings.Join(flags, " "),
},
})
}
diff --git a/java/app_test.go b/java/app_test.go
index f2cbbfb..75d1c90 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1115,7 +1115,8 @@
name string
bp string
certificateOverride string
- expected string
+ expectedLineage string
+ expectedCertificate string
}{
{
name: "default",
@@ -1127,7 +1128,8 @@
}
`,
certificateOverride: "",
- expected: "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8",
+ expectedLineage: "",
+ expectedCertificate: "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8",
},
{
name: "module certificate property",
@@ -1145,7 +1147,8 @@
}
`,
certificateOverride: "",
- expected: "cert/new_cert.x509.pem cert/new_cert.pk8",
+ expectedLineage: "",
+ expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8",
},
{
name: "path certificate property",
@@ -1158,7 +1161,8 @@
}
`,
certificateOverride: "",
- expected: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+ expectedLineage: "",
+ expectedCertificate: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
},
{
name: "certificate overrides",
@@ -1176,7 +1180,28 @@
}
`,
certificateOverride: "foo:new_certificate",
- expected: "cert/new_cert.x509.pem cert/new_cert.pk8",
+ expectedLineage: "",
+ expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8",
+ },
+ {
+ name: "certificate lineage",
+ bp: `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ certificate: ":new_certificate",
+ lineage: "lineage.bin",
+ sdk_version: "current",
+ }
+
+ android_app_certificate {
+ name: "new_certificate",
+ certificate: "cert/new_cert",
+ }
+ `,
+ certificateOverride: "",
+ expectedLineage: "--lineage lineage.bin",
+ expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8",
},
}
@@ -1192,9 +1217,14 @@
foo := ctx.ModuleForTests("foo", "android_common")
signapk := foo.Output("foo.apk")
- signFlags := signapk.Args["certificates"]
- if test.expected != signFlags {
- t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expected, signFlags)
+ signCertificateFlags := signapk.Args["certificates"]
+ if test.expectedCertificate != signCertificateFlags {
+ t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expectedCertificate, signCertificateFlags)
+ }
+
+ signFlags := signapk.Args["flags"]
+ if test.expectedLineage != signFlags {
+ t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expectedLineage, signFlags)
}
})
}
@@ -1368,6 +1398,7 @@
name: "bar",
base: "foo",
certificate: ":new_certificate",
+ lineage: "lineage.bin",
logging_parent: "bah",
}
@@ -1388,7 +1419,8 @@
variantName string
apkName string
apkPath string
- signFlag string
+ certFlag string
+ lineageFlag string
overrides []string
aaptFlag string
logging_parent string
@@ -1397,7 +1429,8 @@
moduleName: "foo",
variantName: "android_common",
apkPath: "/target/product/test_device/system/app/foo/foo.apk",
- signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+ certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+ lineageFlag: "",
overrides: []string{"qux"},
aaptFlag: "",
logging_parent: "",
@@ -1406,7 +1439,8 @@
moduleName: "bar",
variantName: "android_common_bar",
apkPath: "/target/product/test_device/system/app/bar/bar.apk",
- signFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
+ certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
+ lineageFlag: "--lineage lineage.bin",
overrides: []string{"qux", "foo"},
aaptFlag: "",
logging_parent: "bah",
@@ -1415,7 +1449,8 @@
moduleName: "baz",
variantName: "android_common_baz",
apkPath: "/target/product/test_device/system/app/baz/baz.apk",
- signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+ certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+ lineageFlag: "",
overrides: []string{"qux", "foo"},
aaptFlag: "--rename-manifest-package org.dandroid.bp",
logging_parent: "",
@@ -1440,9 +1475,15 @@
// Check the certificate paths
signapk := variant.Output(expected.moduleName + ".apk")
- signFlag := signapk.Args["certificates"]
- if expected.signFlag != signFlag {
- t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected.signFlag, signFlag)
+ certFlag := signapk.Args["certificates"]
+ if expected.certFlag != certFlag {
+ t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected.certFlag, certFlag)
+ }
+
+ // Check the lineage flags
+ lineageFlag := signapk.Args["flags"]
+ if expected.lineageFlag != lineageFlag {
+ t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected.lineageFlag, lineageFlag)
}
// Check if the overrides field values are correctly aggregated.
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 07c626c..5cd1048 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -331,10 +331,18 @@
apiToCheck.Removed_api_file = nil
}
+// Used by xsd_config
type ApiFilePath interface {
ApiFilePath() android.Path
}
+// Provider of information about API stubs, used by java_sdk_library.
+type ApiStubsProvider interface {
+ ApiFilePath
+ RemovedApiFilePath() android.Path
+ StubsSrcJar() android.Path
+}
+
//
// Javadoc
//
@@ -1180,6 +1188,14 @@
return d.apiFilePath
}
+func (d *Droidstubs) RemovedApiFilePath() android.Path {
+ return d.removedApiFile
+}
+
+func (d *Droidstubs) StubsSrcJar() android.Path {
+ return d.stubsSrcJar
+}
+
func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
d.Javadoc.addDeps(ctx)
diff --git a/java/java_test.go b/java/java_test.go
index 6d972be..84f8d9b 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1229,6 +1229,24 @@
}
}
+func TestJavaSdkLibrary_InvalidScopes(t *testing.T) {
+ testJavaError(t, `module "foo": enabled api scope "system" depends on disabled scope "public"`, `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java", "b.java"],
+ api_packages: ["foo"],
+ // Explicitly disable public to test the check that ensures the set of enabled
+ // scopes is consistent.
+ public: {
+ enabled: false,
+ },
+ system: {
+ enabled: true,
+ },
+ }
+ `)
+}
+
var compilerFlagsTestCases = []struct {
in string
out bool
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 1ad5132..fb51e10 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -70,6 +70,18 @@
// The api scope that this scope extends.
extends *apiScope
+ // The legacy enabled status for a specific scope can be dependent on other
+ // properties that have been specified on the library so it is provided by
+ // a function that can determine the status by examining those properties.
+ legacyEnabledStatus func(module *SdkLibrary) bool
+
+ // The default enabled status for non-legacy behavior, which is triggered by
+ // explicitly enabling at least one api scope.
+ defaultEnabledStatus bool
+
+ // Gets a pointer to the scope specific properties.
+ scopeSpecificProperties func(module *SdkLibrary) *ApiScopeProperties
+
// The name of the field in the dynamically created structure.
fieldName string
@@ -120,6 +132,10 @@
return baseName + sdkStubsSourceSuffix + scope.moduleSuffix
}
+func (scope *apiScope) String() string {
+ return scope.name
+}
+
type apiScopes []*apiScope
func (scopes apiScopes) Strings(accessor func(*apiScope) string) []string {
@@ -132,30 +148,68 @@
var (
apiScopePublic = initApiScope(&apiScope{
- name: "public",
+ name: "public",
+
+ // Public scope is enabled by default for both legacy and non-legacy modes.
+ legacyEnabledStatus: func(module *SdkLibrary) bool {
+ return true
+ },
+ defaultEnabledStatus: true,
+
+ scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
+ return &module.sdkLibraryProperties.Public
+ },
sdkVersion: "current",
})
apiScopeSystem = initApiScope(&apiScope{
- name: "system",
- extends: apiScopePublic,
+ name: "system",
+ extends: apiScopePublic,
+ legacyEnabledStatus: (*SdkLibrary).generateTestAndSystemScopesByDefault,
+ scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
+ return &module.sdkLibraryProperties.System
+ },
apiFilePrefix: "system-",
moduleSuffix: sdkSystemApiSuffix,
sdkVersion: "system_current",
droidstubsArgs: []string{"-showAnnotation android.annotation.SystemApi"},
})
apiScopeTest = initApiScope(&apiScope{
- name: "test",
- extends: apiScopePublic,
+ name: "test",
+ extends: apiScopePublic,
+ legacyEnabledStatus: (*SdkLibrary).generateTestAndSystemScopesByDefault,
+ scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
+ return &module.sdkLibraryProperties.Test
+ },
apiFilePrefix: "test-",
moduleSuffix: sdkTestApiSuffix,
sdkVersion: "test_current",
droidstubsArgs: []string{"-showAnnotation android.annotation.TestApi"},
unstable: true,
})
+ apiScopeModuleLib = initApiScope(&apiScope{
+ name: "module_lib",
+ extends: apiScopeSystem,
+ // Module_lib scope is disabled by default in legacy mode.
+ //
+ // Enabling this would break existing usages.
+ legacyEnabledStatus: func(module *SdkLibrary) bool {
+ return false
+ },
+ scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
+ return &module.sdkLibraryProperties.Module_lib
+ },
+ apiFilePrefix: "module-lib-",
+ moduleSuffix: ".module_lib",
+ sdkVersion: "module_current",
+ droidstubsArgs: []string{
+ "--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES\\)",
+ },
+ })
allApiScopes = apiScopes{
apiScopePublic,
apiScopeSystem,
apiScopeTest,
+ apiScopeModuleLib,
}
)
@@ -190,6 +244,18 @@
ctx.RegisterModuleType("java_sdk_library_import", sdkLibraryImportFactory)
}
+// Properties associated with each api scope.
+type ApiScopeProperties struct {
+ // Indicates whether the api surface is generated.
+ //
+ // If this is set for any scope then all scopes must explicitly specify if they
+ // are enabled. This is to prevent new usages from depending on legacy behavior.
+ //
+ // Otherwise, if this is not set for any scope then the default behavior is
+ // scope specific so please refer to the scope specific property documentation.
+ Enabled *bool
+}
+
type sdkLibraryProperties struct {
// List of Java libraries that will be in the classpath when building stubs
Stub_only_libs []string `android:"arch_variant"`
@@ -232,17 +298,47 @@
// don't create dist rules.
No_dist *bool `blueprint:"mutated"`
- // indicates whether system and test apis should be managed.
- Has_system_and_test_apis bool `blueprint:"mutated"`
+ // indicates whether system and test apis should be generated.
+ Generate_system_and_test_apis bool `blueprint:"mutated"`
+
+ // The properties specific to the public api scope
+ //
+ // Unless explicitly specified by using public.enabled the public api scope is
+ // enabled by default in both legacy and non-legacy mode.
+ Public ApiScopeProperties
+
+ // The properties specific to the system api scope
+ //
+ // In legacy mode the system api scope is enabled by default when sdk_version
+ // is set to something other than "none".
+ //
+ // In non-legacy mode the system api scope is disabled by default.
+ System ApiScopeProperties
+
+ // The properties specific to the test api scope
+ //
+ // In legacy mode the test api scope is enabled by default when sdk_version
+ // is set to something other than "none".
+ //
+ // In non-legacy mode the test api scope is disabled by default.
+ Test ApiScopeProperties
+
+ // The properties specific to the module_lib api scope
+ //
+ // Unless explicitly specified by using test.enabled the module_lib api scope is
+ // disabled by default.
+ Module_lib ApiScopeProperties
// TODO: determines whether to create HTML doc or not
//Html_doc *bool
}
type scopePaths struct {
- stubsHeaderPath android.Paths
- stubsImplPath android.Paths
- apiFilePath android.Path
+ stubsHeaderPath android.Paths
+ stubsImplPath android.Paths
+ currentApiFilePath android.Path
+ removedApiFilePath android.Path
+ stubsSrcJar android.Path
}
// Common code between sdk library and sdk library import
@@ -268,18 +364,65 @@
sdkLibraryProperties sdkLibraryProperties
+ // Map from api scope to the scope specific property structure.
+ scopeToProperties map[*apiScope]*ApiScopeProperties
+
commonToSdkLibraryAndImport
}
var _ Dependency = (*SdkLibrary)(nil)
var _ SdkLibraryDependency = (*SdkLibrary)(nil)
-func (module *SdkLibrary) getActiveApiScopes() apiScopes {
- if module.sdkLibraryProperties.Has_system_and_test_apis {
- return allApiScopes
- } else {
- return apiScopes{apiScopePublic}
+func (module *SdkLibrary) generateTestAndSystemScopesByDefault() bool {
+ return module.sdkLibraryProperties.Generate_system_and_test_apis
+}
+
+func (module *SdkLibrary) getGeneratedApiScopes(ctx android.EarlyModuleContext) apiScopes {
+ // Check to see if any scopes have been explicitly enabled. If any have then all
+ // must be.
+ anyScopesExplicitlyEnabled := false
+ for _, scope := range allApiScopes {
+ scopeProperties := module.scopeToProperties[scope]
+ if scopeProperties.Enabled != nil {
+ anyScopesExplicitlyEnabled = true
+ break
+ }
}
+
+ var generatedScopes apiScopes
+ enabledScopes := make(map[*apiScope]struct{})
+ for _, scope := range allApiScopes {
+ scopeProperties := module.scopeToProperties[scope]
+ // If any scopes are explicitly enabled then ignore the legacy enabled status.
+ // This is to ensure that any new usages of this module type do not rely on legacy
+ // behaviour.
+ defaultEnabledStatus := false
+ if anyScopesExplicitlyEnabled {
+ defaultEnabledStatus = scope.defaultEnabledStatus
+ } else {
+ defaultEnabledStatus = scope.legacyEnabledStatus(module)
+ }
+ enabled := proptools.BoolDefault(scopeProperties.Enabled, defaultEnabledStatus)
+ if enabled {
+ enabledScopes[scope] = struct{}{}
+ generatedScopes = append(generatedScopes, scope)
+ }
+ }
+
+ // Now check to make sure that any scope that is extended by an enabled scope is also
+ // enabled.
+ for _, scope := range allApiScopes {
+ if _, ok := enabledScopes[scope]; ok {
+ extends := scope.extends
+ if extends != nil {
+ if _, ok := enabledScopes[extends]; !ok {
+ ctx.ModuleErrorf("enabled api scope %q depends on disabled scope %q", scope, extends)
+ }
+ }
+ }
+ }
+
+ return generatedScopes
}
var xmlPermissionsFileTag = dependencyTag{name: "xml-permissions-file"}
@@ -292,7 +435,7 @@
}
func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
- for _, apiScope := range module.getActiveApiScopes() {
+ for _, apiScope := range module.getGeneratedApiScopes(ctx) {
// Add dependencies to the stubs library
ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsName(apiScope))
@@ -329,11 +472,13 @@
scopePaths.stubsImplPath = lib.ImplementationJars()
}
}
- if doc, ok := to.(ApiFilePath); ok {
+ if doc, ok := to.(ApiStubsProvider); ok {
if scopeTag, ok := tag.(scopeDependencyTag); ok {
apiScope := scopeTag.apiScope
scopePaths := module.getScopePaths(apiScope)
- scopePaths.apiFilePath = doc.ApiFilePath()
+ scopePaths.currentApiFilePath = doc.ApiFilePath()
+ scopePaths.removedApiFilePath = doc.RemovedApiFilePath()
+ scopePaths.stubsSrcJar = doc.StubsSrcJar()
} else {
ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
}
@@ -730,15 +875,15 @@
// also assume it does not contribute to the dist build.
sdkDep := decodeSdkDep(mctx, sdkContext(&module.Library))
hasSystemAndTestApis := sdkDep.hasStandardLibs()
- module.sdkLibraryProperties.Has_system_and_test_apis = hasSystemAndTestApis
+ module.sdkLibraryProperties.Generate_system_and_test_apis = hasSystemAndTestApis
module.sdkLibraryProperties.No_dist = proptools.BoolPtr(!hasSystemAndTestApis)
missing_current_api := false
- activeScopes := module.getActiveApiScopes()
+ generatedScopes := module.getGeneratedApiScopes(mctx)
apiDir := module.getApiDir()
- for _, scope := range activeScopes {
+ for _, scope := range generatedScopes {
for _, api := range []string{"current.txt", "removed.txt"} {
path := path.Join(mctx.ModuleDir(), apiDir, scope.apiFilePrefix+api)
p := android.ExistentPathForSource(mctx, path)
@@ -761,11 +906,11 @@
"You can update them by:\n"+
"%s %q %s && m update-api",
script, filepath.Join(mctx.ModuleDir(), apiDir),
- strings.Join(activeScopes.Strings(func(s *apiScope) string { return s.apiFilePrefix }), " "))
+ strings.Join(generatedScopes.Strings(func(s *apiScope) string { return s.apiFilePrefix }), " "))
return
}
- for _, scope := range activeScopes {
+ for _, scope := range generatedScopes {
module.createStubsLibrary(mctx, scope)
module.createStubsSources(mctx, scope)
}
@@ -805,6 +950,14 @@
module.InitSdkLibraryProperties()
android.InitApexModule(module)
InitJavaModule(module, android.HostAndDeviceSupported)
+
+ // Initialize the map from scope to scope specific properties.
+ scopeToProperties := make(map[*apiScope]*ApiScopeProperties)
+ for _, scope := range allApiScopes {
+ scopeToProperties[scope] = scope.scopeSpecificProperties(module)
+ }
+ module.scopeToProperties = scopeToProperties
+
module.SetDefaultableHook(func(ctx android.DefaultableHookContext) { module.CreateInternalModules(ctx) })
return module
}
@@ -821,6 +974,15 @@
// List of shared java libs that this module has dependencies to
Libs []string
+
+ // The stub sources.
+ Stub_srcs []string `android:"path"`
+
+ // The current.txt
+ Current_api string `android:"path"`
+
+ // The removed.txt
+ Removed_api string `android:"path"`
}
type sdkLibraryImportProperties struct {
@@ -922,6 +1084,8 @@
}
module.createJavaImportForStubs(mctx, apiScope, scopeProperties)
+
+ module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties)
}
javaSdkLibraries := javaSdkLibraries(mctx.Config())
@@ -966,6 +1130,16 @@
mctx.CreateModule(ImportFactory, &props)
}
+func (module *sdkLibraryImport) createPrebuiltStubsSources(mctx android.LoadHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
+ props := struct {
+ Name *string
+ Srcs []string
+ }{}
+ props.Name = proptools.StringPtr(apiScope.docsModuleName(module.BaseModuleName()))
+ props.Srcs = scopeProperties.Stub_srcs
+ mctx.CreateModule(PrebuiltStubsSourcesFactory, &props)
+}
+
func (module *sdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
for apiScope, scopeProperties := range module.scopeProperties {
if len(scopeProperties.Jars) == 0 {
@@ -1164,11 +1338,17 @@
// Additional libraries that the exported stubs libraries depend upon.
Libs []string
+
+ // The Java stubs source files.
+ Stub_srcs []string
}
type scopeProperties struct {
- Jars android.Paths
- SdkVersion string
+ Jars android.Paths
+ StubsSrcJar android.Path
+ CurrentApiFile android.Path
+ RemovedApiFile android.Path
+ SdkVersion string
}
func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
@@ -1182,6 +1362,9 @@
properties := scopeProperties{}
properties.Jars = jars
properties.SdkVersion = apiScope.sdkVersion
+ properties.StubsSrcJar = paths.stubsSrcJar
+ properties.CurrentApiFile = paths.currentApiFilePath
+ properties.RemovedApiFile = paths.removedApiFilePath
s.Scopes[apiScope] = properties
}
}
@@ -1194,14 +1377,34 @@
if properties, ok := s.Scopes[apiScope]; ok {
scopeSet := propertySet.AddPropertySet(apiScope.name)
+ scopeDir := filepath.Join("sdk_library", s.OsPrefix(), apiScope.name)
+
var jars []string
for _, p := range properties.Jars {
- dest := filepath.Join("sdk_library", s.OsPrefix(), apiScope.name, ctx.Name()+"-stubs.jar")
+ dest := filepath.Join(scopeDir, ctx.Name()+"-stubs.jar")
ctx.SnapshotBuilder().CopyToSnapshot(p, dest)
jars = append(jars, dest)
}
scopeSet.AddProperty("jars", jars)
+ // Merge the stubs source jar into the snapshot zip so that when it is unpacked
+ // the source files are also unpacked.
+ snapshotRelativeDir := filepath.Join(scopeDir, ctx.Name()+"_stub_sources")
+ ctx.SnapshotBuilder().UnzipToSnapshot(properties.StubsSrcJar, snapshotRelativeDir)
+ scopeSet.AddProperty("stub_srcs", []string{snapshotRelativeDir})
+
+ if properties.CurrentApiFile != nil {
+ currentApiSnapshotPath := filepath.Join(scopeDir, ctx.Name()+".txt")
+ ctx.SnapshotBuilder().CopyToSnapshot(properties.CurrentApiFile, currentApiSnapshotPath)
+ scopeSet.AddProperty("current_api", currentApiSnapshotPath)
+ }
+
+ if properties.RemovedApiFile != nil {
+ removedApiSnapshotPath := filepath.Join(scopeDir, ctx.Name()+"-removed.txt")
+ ctx.SnapshotBuilder().CopyToSnapshot(properties.CurrentApiFile, removedApiSnapshotPath)
+ scopeSet.AddProperty("removed_api", removedApiSnapshotPath)
+ }
+
if properties.SdkVersion != "" {
scopeSet.AddProperty("sdk_version", properties.SdkVersion)
}
diff --git a/java/testing.go b/java/testing.go
index 28c1a26..dd35653 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -114,6 +114,7 @@
"cert/new_cert.x509.pem": nil,
"cert/new_cert.pk8": nil,
+ "lineage.bin": nil,
"testdata/data": nil,
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index a844a53..6173510 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -32,6 +32,8 @@
"api/system-removed.txt": nil,
"api/test-current.txt": nil,
"api/test-removed.txt": nil,
+ "api/module-lib-current.txt": nil,
+ "api/module-lib-removed.txt": nil,
"build/soong/scripts/gen-java-current-api-files.sh": nil,
}
@@ -56,6 +58,9 @@
name: "android_test_stubs_current",
}
java_import {
+ name: "android_module_lib_stubs_current",
+}
+java_import {
name: "core-lambda-stubs",
sdk_version: "none",
}
@@ -624,7 +629,7 @@
`),
checkAllCopyRules(""),
- checkMergeZip(".intermediates/myexports/common_os/tmp/java/myjavaapistubs_stubs_sources.zip"),
+ checkMergeZips(".intermediates/myexports/common_os/tmp/java/myjavaapistubs_stubs_sources.zip"),
)
}
@@ -678,7 +683,7 @@
}
`),
checkAllCopyRules(""),
- checkMergeZip(".intermediates/myexports/common_os/tmp/java/myjavaapistubs_stubs_sources.zip"),
+ checkMergeZips(".intermediates/myexports/common_os/tmp/java/myjavaapistubs_stubs_sources.zip"),
)
}
@@ -997,14 +1002,23 @@
apex_available: ["//apex_available:anyapex"],
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
+ current_api: "sdk_library/public/myjavalib.txt",
+ removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
},
system: {
jars: ["sdk_library/system/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/system/myjavalib_stub_sources"],
+ current_api: "sdk_library/system/myjavalib.txt",
+ removed_api: "sdk_library/system/myjavalib-removed.txt",
sdk_version: "system_current",
},
test: {
jars: ["sdk_library/test/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/test/myjavalib_stub_sources"],
+ current_api: "sdk_library/test/myjavalib.txt",
+ removed_api: "sdk_library/test/myjavalib-removed.txt",
sdk_version: "test_current",
},
}
@@ -1015,14 +1029,23 @@
apex_available: ["//apex_available:anyapex"],
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
+ current_api: "sdk_library/public/myjavalib.txt",
+ removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
},
system: {
jars: ["sdk_library/system/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/system/myjavalib_stub_sources"],
+ current_api: "sdk_library/system/myjavalib.txt",
+ removed_api: "sdk_library/system/myjavalib-removed.txt",
sdk_version: "system_current",
},
test: {
jars: ["sdk_library/test/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/test/myjavalib_stub_sources"],
+ current_api: "sdk_library/test/myjavalib.txt",
+ removed_api: "sdk_library/test/myjavalib-removed.txt",
sdk_version: "test_current",
},
}
@@ -1034,8 +1057,209 @@
`),
checkAllCopyRules(`
.intermediates/myjavalib.stubs/android_common/javac/myjavalib.stubs.jar -> sdk_library/public/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib-removed.txt
.intermediates/myjavalib.stubs.system/android_common/javac/myjavalib.stubs.system.jar -> sdk_library/system/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib.txt
+.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib-removed.txt
.intermediates/myjavalib.stubs.test/android_common/javac/myjavalib.stubs.test.jar -> sdk_library/test/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source.test/android_common/myjavalib.stubs.source.test_api.txt -> sdk_library/test/myjavalib.txt
+.intermediates/myjavalib.stubs.source.test/android_common/myjavalib.stubs.source.test_api.txt -> sdk_library/test/myjavalib-removed.txt
`),
+ checkMergeZips(
+ ".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip",
+ ".intermediates/mysdk/common_os/tmp/sdk_library/system/myjavalib_stub_sources.zip",
+ ".intermediates/mysdk/common_os/tmp/sdk_library/test/myjavalib_stub_sources.zip"),
+ )
+}
+
+func TestSnapshotWithJavaSdkLibrary_ApiSurfaces(t *testing.T) {
+ result := testSdkWithJava(t, `
+ sdk {
+ name: "mysdk",
+ java_sdk_libs: ["myjavalib"],
+ }
+
+ java_sdk_library {
+ name: "myjavalib",
+ apex_available: ["//apex_available:anyapex"],
+ srcs: ["Test.java"],
+ sdk_version: "current",
+ public: {
+ enabled: true,
+ },
+ system: {
+ enabled: true,
+ },
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_sdk_library_import {
+ name: "mysdk_myjavalib@current",
+ sdk_member_name: "myjavalib",
+ apex_available: ["//apex_available:anyapex"],
+ public: {
+ jars: ["sdk_library/public/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
+ current_api: "sdk_library/public/myjavalib.txt",
+ removed_api: "sdk_library/public/myjavalib-removed.txt",
+ sdk_version: "current",
+ },
+ system: {
+ jars: ["sdk_library/system/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/system/myjavalib_stub_sources"],
+ current_api: "sdk_library/system/myjavalib.txt",
+ removed_api: "sdk_library/system/myjavalib-removed.txt",
+ sdk_version: "system_current",
+ },
+}
+
+java_sdk_library_import {
+ name: "myjavalib",
+ prefer: false,
+ apex_available: ["//apex_available:anyapex"],
+ public: {
+ jars: ["sdk_library/public/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
+ current_api: "sdk_library/public/myjavalib.txt",
+ removed_api: "sdk_library/public/myjavalib-removed.txt",
+ sdk_version: "current",
+ },
+ system: {
+ jars: ["sdk_library/system/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/system/myjavalib_stub_sources"],
+ current_api: "sdk_library/system/myjavalib.txt",
+ removed_api: "sdk_library/system/myjavalib-removed.txt",
+ sdk_version: "system_current",
+ },
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ java_sdk_libs: ["mysdk_myjavalib@current"],
+}
+`),
+ checkAllCopyRules(`
+.intermediates/myjavalib.stubs/android_common/javac/myjavalib.stubs.jar -> sdk_library/public/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.system/android_common/javac/myjavalib.stubs.system.jar -> sdk_library/system/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib.txt
+.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib-removed.txt
+`),
+ checkMergeZips(
+ ".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip",
+ ".intermediates/mysdk/common_os/tmp/sdk_library/system/myjavalib_stub_sources.zip",
+ ),
+ )
+}
+
+func TestSnapshotWithJavaSdkLibrary_ModuleLib(t *testing.T) {
+ result := testSdkWithJava(t, `
+ sdk {
+ name: "mysdk",
+ java_sdk_libs: ["myjavalib"],
+ }
+
+ java_sdk_library {
+ name: "myjavalib",
+ apex_available: ["//apex_available:anyapex"],
+ srcs: ["Test.java"],
+ sdk_version: "current",
+ public: {
+ enabled: true,
+ },
+ system: {
+ enabled: true,
+ },
+ module_lib: {
+ enabled: true,
+ },
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_sdk_library_import {
+ name: "mysdk_myjavalib@current",
+ sdk_member_name: "myjavalib",
+ apex_available: ["//apex_available:anyapex"],
+ public: {
+ jars: ["sdk_library/public/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
+ current_api: "sdk_library/public/myjavalib.txt",
+ removed_api: "sdk_library/public/myjavalib-removed.txt",
+ sdk_version: "current",
+ },
+ system: {
+ jars: ["sdk_library/system/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/system/myjavalib_stub_sources"],
+ current_api: "sdk_library/system/myjavalib.txt",
+ removed_api: "sdk_library/system/myjavalib-removed.txt",
+ sdk_version: "system_current",
+ },
+ module_lib: {
+ jars: ["sdk_library/module_lib/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/module_lib/myjavalib_stub_sources"],
+ current_api: "sdk_library/module_lib/myjavalib.txt",
+ removed_api: "sdk_library/module_lib/myjavalib-removed.txt",
+ sdk_version: "module_current",
+ },
+}
+
+java_sdk_library_import {
+ name: "myjavalib",
+ prefer: false,
+ apex_available: ["//apex_available:anyapex"],
+ public: {
+ jars: ["sdk_library/public/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
+ current_api: "sdk_library/public/myjavalib.txt",
+ removed_api: "sdk_library/public/myjavalib-removed.txt",
+ sdk_version: "current",
+ },
+ system: {
+ jars: ["sdk_library/system/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/system/myjavalib_stub_sources"],
+ current_api: "sdk_library/system/myjavalib.txt",
+ removed_api: "sdk_library/system/myjavalib-removed.txt",
+ sdk_version: "system_current",
+ },
+ module_lib: {
+ jars: ["sdk_library/module_lib/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/module_lib/myjavalib_stub_sources"],
+ current_api: "sdk_library/module_lib/myjavalib.txt",
+ removed_api: "sdk_library/module_lib/myjavalib-removed.txt",
+ sdk_version: "module_current",
+ },
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ java_sdk_libs: ["mysdk_myjavalib@current"],
+}
+`),
+ checkAllCopyRules(`
+.intermediates/myjavalib.stubs/android_common/javac/myjavalib.stubs.jar -> sdk_library/public/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.system/android_common/javac/myjavalib.stubs.system.jar -> sdk_library/system/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib.txt
+.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.module_lib/android_common/javac/myjavalib.stubs.module_lib.jar -> sdk_library/module_lib/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source.module_lib/android_common/myjavalib.stubs.source.module_lib_api.txt -> sdk_library/module_lib/myjavalib.txt
+.intermediates/myjavalib.stubs.source.module_lib/android_common/myjavalib.stubs.source.module_lib_api.txt -> sdk_library/module_lib/myjavalib-removed.txt
+`),
+ checkMergeZips(
+ ".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip",
+ ".intermediates/mysdk/common_os/tmp/sdk_library/system/myjavalib_stub_sources.zip",
+ ".intermediates/mysdk/common_os/tmp/sdk_library/module_lib/myjavalib_stub_sources.zip",
+ ),
)
}
diff --git a/sdk/testing.go b/sdk/testing.go
index 362a352..14a397c 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -348,14 +348,15 @@
}
}
-// Check that the specified path is in the list of zips to merge with the intermediate zip.
-func checkMergeZip(expected string) snapshotBuildInfoChecker {
+// Check that the specified paths match the list of zips to merge with the intermediate zip.
+func checkMergeZips(expected ...string) snapshotBuildInfoChecker {
return func(info *snapshotBuildInfo) {
info.r.t.Helper()
if info.intermediateZip == "" {
info.r.t.Errorf("No intermediate zip file was created")
}
- ensureListContains(info.r.t, info.mergeZips, expected)
+
+ info.r.AssertDeepEquals("mismatching merge zip files", expected, info.mergeZips)
}
}