Merge "Fix toJsonClassLoaderContextRec size bug"
diff --git a/android/androidmk.go b/android/androidmk.go
index 618e4be..590eceb 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -550,7 +550,9 @@
if !amod.InRamdisk() && !amod.InVendorRamdisk() {
a.AddPaths("LOCAL_FULL_INIT_RC", amod.initRcPaths)
}
- a.AddStrings("LOCAL_VINTF_FRAGMENTS", amod.commonProperties.Vintf_fragments...)
+ if len(amod.vintfFragmentsPaths) > 0 {
+ a.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", amod.vintfFragmentsPaths)
+ }
a.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(amod.commonProperties.Proprietary))
if Bool(amod.commonProperties.Vendor) || Bool(amod.commonProperties.Soc_specific) {
a.SetString("LOCAL_VENDOR_MODULE", "true")
diff --git a/android/bazel.go b/android/bazel.go
index 6e87d57..6800c91 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -180,8 +180,6 @@
"libc_init_dynamic", // ruperts@, cc_library_static, 'private/bionic_defs.h' file not found
"libc_tzcode", // ruperts@, cc_library_static, error: expected expression
"libc_netbsd", // ruperts@, cc_library_static, 'engine.c' file not found
- "libc_openbsd_large_stack", // ruperts@, cc_library_static, 'android/log.h' file not found
- "libc_openbsd", // ruperts@, cc_library_static, 'android/log.h' file not found
"libc_fortify", // ruperts@, cc_library_static, 'private/bionic_fortify.h' file not found
"libc_bionic", // ruperts@, cc_library_static, 'private/bionic_asm.h' file not found
"libc_bionic_ndk", // ruperts@, cc_library_static, depends on //bionic/libc/system_properties
@@ -203,7 +201,7 @@
"liblinker_malloc", // ruperts@, cc_library_static, depends on //system/logging/liblog:liblog
"liblinker_debuggerd_stub", // ruperts@, cc_library_static, depends on //system/libbase
"libbionic_tests_headers_posix", // ruperts@, cc_library_static, 'complex.h' file not found
- "libc_dns", // ruperts@, cc_library_static, 'android/log.h' file not found
+ "libc_dns", // ruperts@, cc_library_static, 'private/android_filesystem_config.h' file not found
"libc_static_dispatch", // eakammer@, cc_library_static, 'private/bionic_asm.h' file not found
"libc_dynamic_dispatch", // eakammer@, cc_library_static, 'private/bionic_ifuncs.h' file not found
"note_memtag_heap_async", // jingwen@, cc_library_static, 'private/bionic_asm.h' file not found (arm64)
@@ -222,7 +220,8 @@
// Per-module denylist to opt modules out of mixed builds. Such modules will
// still be generated via bp2build.
mixedBuildsDisabledList = []string{
- "libc_gdtoa", // ruperts@, cc_library_static, OK for bp2build but undefined symbol: __strtorQ for mixed builds
+ "libc_gdtoa", // ruperts@, cc_library_static, OK for bp2build but undefined symbol: __strtorQ for mixed builds
+ "libc_openbsd", // ruperts@, cc_library_static, OK for bp2build but error: duplicate symbol: strcpy for mixed builds
}
// Used for quicker lookups
diff --git a/android/test_asserts.go b/android/test_asserts.go
index bfb88ab..edeb408 100644
--- a/android/test_asserts.go
+++ b/android/test_asserts.go
@@ -126,13 +126,44 @@
}
}
+// AssertStringContainsEquals checks if the string contains or does not contain the substring, given
+// the value of the expected bool. If the expectation does not hold it reports an error prefixed with
+// the supplied message and including a reason for why it failed.
+func AssertStringContainsEquals(t *testing.T, message string, s string, substring string, expected bool) {
+ if expected {
+ AssertStringDoesContain(t, message, s, substring)
+ } else {
+ AssertStringDoesNotContain(t, message, s, substring)
+ }
+}
+
// AssertStringListContains checks if the list of strings contains the expected string. If it does
// not then it reports an error prefixed with the supplied message and including a reason for why it
// failed.
-func AssertStringListContains(t *testing.T, message string, list []string, expected string) {
+func AssertStringListContains(t *testing.T, message string, list []string, s string) {
t.Helper()
- if !InList(expected, list) {
- t.Errorf("%s: could not find %q within %q", message, expected, list)
+ if !InList(s, list) {
+ t.Errorf("%s: could not find %q within %q", message, s, list)
+ }
+}
+
+// AssertStringListDoesNotContain checks if the list of strings contains the expected string. If it does
+// then it reports an error prefixed with the supplied message and including a reason for why it failed.
+func AssertStringListDoesNotContain(t *testing.T, message string, list []string, s string) {
+ t.Helper()
+ if InList(s, list) {
+ t.Errorf("%s: unexpectedly found %q within %q", message, s, list)
+ }
+}
+
+// AssertStringContainsEquals checks if the string contains or does not contain the substring, given
+// the value of the expected bool. If the expectation does not hold it reports an error prefixed with
+// the supplied message and including a reason for why it failed.
+func AssertStringListContainsEquals(t *testing.T, message string, list []string, s string, expected bool) {
+ if expected {
+ AssertStringListContains(t, message, list, s)
+ } else {
+ AssertStringListDoesNotContain(t, message, list, s)
}
}
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 9fc701d..06d3b54 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -284,7 +284,7 @@
// To install companion files (init_rc, vintf_fragments)
// Copy some common properties of apexBundle to apex_manifest
commonProperties := []string{
- "LOCAL_FULL_INIT_RC", "LOCAL_VINTF_FRAGMENTS",
+ "LOCAL_FULL_INIT_RC", "LOCAL_FULL_VINTF_FRAGMENTS",
}
for _, name := range commonProperties {
if value, ok := apexAndroidMkData.Entries.EntryMap[name]; ok {
@@ -394,7 +394,7 @@
// Because apex writes .mk with Custom(), we need to write manually some common properties
// which are available via data.Entries
commonProperties := []string{
- "LOCAL_FULL_INIT_RC", "LOCAL_VINTF_FRAGMENTS",
+ "LOCAL_FULL_INIT_RC", "LOCAL_FULL_VINTF_FRAGMENTS",
"LOCAL_PROPRIETARY_MODULE", "LOCAL_VENDOR_MODULE", "LOCAL_ODM_MODULE", "LOCAL_PRODUCT_MODULE", "LOCAL_SYSTEM_EXT_MODULE",
"LOCAL_MODULE_OWNER",
}
diff --git a/apex/apex.go b/apex/apex.go
index 6f02c47..088a462 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -110,16 +110,6 @@
// List of filesystem images that are embedded inside this APEX bundle.
Filesystems []string
- // Name of the apex_key module that provides the private key to sign this APEX bundle.
- Key *string
-
- // Specifies the certificate and the private key to sign the zip container of this APEX. If
- // this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
- // as the certificate and the private key, respectively. If this is ":module", then the
- // certificate and the private key are provided from the android_app_certificate module
- // named "module".
- Certificate *string
-
// The minimum SDK version that this APEX must support at minimum. This is usually set to
// the SDK version that the APEX was first introduced.
Min_sdk_version *string
@@ -299,6 +289,16 @@
// A txt file containing list of files that are allowed to be included in this APEX.
Allowed_files *string `android:"path"`
+
+ // Name of the apex_key module that provides the private key to sign this APEX bundle.
+ Key *string
+
+ // Specifies the certificate and the private key to sign the zip container of this APEX. If
+ // this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
+ // as the certificate and the private key, respectively. If this is ":module", then the
+ // certificate and the private key are provided from the android_app_certificate module
+ // named "module".
+ Certificate *string
}
type apexBundle struct {
@@ -760,20 +760,6 @@
}
}
- // Dependencies for signing
- if String(a.properties.Key) == "" {
- ctx.PropertyErrorf("key", "missing")
- return
- }
- ctx.AddDependency(ctx.Module(), keyTag, String(a.properties.Key))
-
- cert := android.SrcIsModule(a.getCertString(ctx))
- if cert != "" {
- ctx.AddDependency(ctx.Module(), certificateTag, cert)
- // empty cert is not an error. Cert and private keys will be directly found under
- // PRODUCT_DEFAULT_DEV_CERTIFICATE
- }
-
// Marks that this APEX (in fact all the modules in it) has to be built with the given SDKs.
// This field currently isn't used.
// TODO(jiyong): consider dropping this feature
@@ -797,6 +783,20 @@
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
+
+ // Dependencies for signing
+ if String(a.overridableProperties.Key) == "" {
+ ctx.PropertyErrorf("key", "missing")
+ return
+ }
+ ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))
+
+ cert := android.SrcIsModule(a.getCertString(ctx))
+ if cert != "" {
+ ctx.AddDependency(ctx.Module(), certificateTag, cert)
+ // empty cert is not an error. Cert and private keys will be directly found under
+ // PRODUCT_DEFAULT_DEV_CERTIFICATE
+ }
}
type ApexBundleInfo struct {
@@ -1292,7 +1292,7 @@
if overridden {
return ":" + certificate
}
- return String(a.properties.Certificate)
+ return String(a.overridableProperties.Certificate)
}
// See the installable property
@@ -1924,7 +1924,7 @@
// Rlib is statically linked, but it might have shared lib
// dependencies. Track them.
return true
- } else if java.IsbootImageContentDepTag(depTag) {
+ } else if java.IsBootclasspathFragmentContentDepTag(depTag) {
// Add the contents of the bootclasspath fragment to the apex.
switch child.(type) {
case *java.Library, *java.SdkLibrary:
@@ -1949,7 +1949,7 @@
return false
})
if a.privateKeyFile == nil {
- ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.properties.Key))
+ ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
return
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 977a954..c2378fc 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2755,7 +2755,7 @@
var builder strings.Builder
data.Custom(&builder, name, prefix, "", data)
androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_VINTF_FRAGMENTS := fragment.xml\n")
+ ensureContains(t, androidMk, "LOCAL_FULL_VINTF_FRAGMENTS := fragment.xml\n")
ensureContains(t, androidMk, "LOCAL_FULL_INIT_RC := init.rc\n")
}
@@ -5599,6 +5599,8 @@
overrides: ["unknownapex"],
logging_parent: "com.foo.bar",
package_name: "test.overridden.package",
+ key: "mynewapex.key",
+ certificate: ":myapex.certificate",
}
apex_key {
@@ -5607,6 +5609,17 @@
private_key: "testkey.pem",
}
+ apex_key {
+ name: "mynewapex.key",
+ public_key: "testkey2.avbpubkey",
+ private_key: "testkey2.pem",
+ }
+
+ android_app_certificate {
+ name: "myapex.certificate",
+ certificate: "testkey",
+ }
+
android_app {
name: "app",
srcs: ["foo/bar/MyClass.java"],
@@ -5651,6 +5664,10 @@
optFlags := apexRule.Args["opt_flags"]
ensureContains(t, optFlags, "--override_apk_package_name test.overridden.package")
+ ensureContains(t, optFlags, "--pubkey testkey2.avbpubkey")
+
+ signApkRule := module.Rule("signapk")
+ ensureEquals(t, signApkRule.Args["certificates"], "testkey.x509.pem testkey.pk8")
data := android.AndroidMkDataForTest(t, ctx, apexBundle)
var builder strings.Builder
diff --git a/apex/boot_image_test.go b/apex/boot_image_test.go
index e18c2ea..dab72f7 100644
--- a/apex/boot_image_test.go
+++ b/apex/boot_image_test.go
@@ -216,6 +216,22 @@
],
}
+ java_import {
+ name: "foo",
+ jars: ["foo.jar"],
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ java_import {
+ name: "bar",
+ jars: ["bar.jar"],
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
// Make sure that a preferred prebuilt doesn't affect the apex.
prebuilt_boot_image {
name: "mybootclasspathfragment",
diff --git a/apex/builder.go b/apex/builder.go
index b382a53..da8841c 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -871,7 +871,7 @@
return a.containerCertificateFile, a.containerPrivateKeyFile
}
- cert := String(a.properties.Certificate)
+ cert := String(a.overridableProperties.Certificate)
if cert == "" {
return ctx.Config().DefaultAppCertificate(ctx)
}
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index 74830d3..52b1689 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -137,9 +137,12 @@
)
java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{
+ // The configured contents of BootJars.
"com.android.art:baz",
"com.android.art:quuz",
"platform:foo",
+
+ // The configured contents of UpdatableBootJars.
"myapex:bar",
})
@@ -149,11 +152,24 @@
// Make sure that the myplatform-bootclasspath has the correct dependencies.
CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
+ // The following are stubs.
+ `platform:android_stubs_current`,
+ `platform:android_system_stubs_current`,
+ `platform:android_test_stubs_current`,
+ `platform:legacy.core.platform.api.stubs`,
+
+ // Needed for generating the boot image.
`platform:dex2oatd`,
+
+ // The configured contents of BootJars.
`com.android.art:baz`,
`com.android.art:quuz`,
`platform:foo`,
+
+ // The configured contents of UpdatableBootJars.
`myapex:bar`,
+
+ // The fragments.
`com.android.art:art-bootclasspath-fragment`,
})
}
diff --git a/apex/testing.go b/apex/testing.go
index 926125f..69bd73e 100644
--- a/apex/testing.go
+++ b/apex/testing.go
@@ -25,5 +25,7 @@
// Needed by apex.
"system/core/rootdir/etc/public.libraries.android.txt": nil,
"build/soong/scripts/gen_ndk_backedby_apex.sh": nil,
+ // Needed by prebuilt_apex.
+ "build/soong/scripts/unpack-prebuilt-apex.sh": nil,
}.AddToFixture(),
)
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 114b668..d67ab3d 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -49,7 +49,7 @@
func createBuildFiles(buildToTargets map[string]BazelTargets, mode CodegenMode) []BazelFile {
files := make([]BazelFile, 0, len(buildToTargets))
for _, dir := range android.SortedStringKeys(buildToTargets) {
- if !android.ShouldWriteBuildFileForDir(dir) {
+ if mode == Bp2Build && !android.ShouldWriteBuildFileForDir(dir) {
fmt.Printf("[bp2build] Not writing generated BUILD file for dir: '%s'\n", dir)
continue
}
diff --git a/cc/cc.go b/cc/cc.go
index 9eebbae..98df545 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1145,12 +1145,7 @@
func (c *Module) isImplementationForLLNDKPublic() bool {
library, _ := c.library.(*libraryDecorator)
return library != nil && library.hasLLNDKStubs() &&
- (!Bool(library.Properties.Llndk.Private) ||
- // TODO(b/170784825): until the LLNDK properties are moved into the cc_library,
- // the non-Vendor variants of the cc_library don't know if the corresponding
- // llndk_library set private: true. Since libft2 is the only private LLNDK
- // library, hardcode it during the transition.
- c.BaseModuleName() != "libft2")
+ !Bool(library.Properties.Llndk.Private)
}
// Returns true for LLNDK-private, VNDK-SP-private, and VNDK-core-private.
diff --git a/cc/cc_test.go b/cc/cc_test.go
index db696ef..c56643b 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -2824,6 +2824,100 @@
checkEquals(t, "override apiLevel for versioned stubs", "1", params.Args["apiLevel"])
}
+func TestEmbeddedLlndkLibrary(t *testing.T) {
+ result := prepareForCcTest.RunTestWithBp(t, `
+ cc_library {
+ name: "libllndk",
+ stubs: { versions: ["1", "2"] },
+ llndk: {
+ symbol_file: "libllndk.map.txt",
+ },
+ export_include_dirs: ["include"],
+ }
+
+ cc_prebuilt_library_shared {
+ name: "libllndkprebuilt",
+ stubs: { versions: ["1", "2"] },
+ llndk: {
+ symbol_file: "libllndkprebuilt.map.txt",
+ },
+ }
+
+ cc_library {
+ name: "libllndk_with_external_headers",
+ stubs: { versions: ["1", "2"] },
+ llndk: {
+ symbol_file: "libllndk.map.txt",
+ export_llndk_headers: ["libexternal_llndk_headers"],
+ },
+ header_libs: ["libexternal_headers"],
+ export_header_lib_headers: ["libexternal_headers"],
+ }
+ cc_library_headers {
+ name: "libexternal_headers",
+ export_include_dirs: ["include"],
+ vendor_available: true,
+ }
+ cc_library_headers {
+ name: "libexternal_llndk_headers",
+ export_include_dirs: ["include_llndk"],
+ llndk: {
+ symbol_file: "libllndk.map.txt",
+ },
+ vendor_available: true,
+ }
+
+ cc_library {
+ name: "libllndk_with_override_headers",
+ stubs: { versions: ["1", "2"] },
+ llndk: {
+ symbol_file: "libllndk.map.txt",
+ override_export_include_dirs: ["include_llndk"],
+ },
+ export_include_dirs: ["include"],
+ }
+ `)
+ actual := result.ModuleVariantsForTests("libllndk")
+ for i := 0; i < len(actual); i++ {
+ if !strings.HasPrefix(actual[i], "android_vendor.29_") {
+ actual = append(actual[:i], actual[i+1:]...)
+ i--
+ }
+ }
+ expected := []string{
+ "android_vendor.29_arm64_armv8-a_shared_1",
+ "android_vendor.29_arm64_armv8-a_shared_2",
+ "android_vendor.29_arm64_armv8-a_shared_current",
+ "android_vendor.29_arm64_armv8-a_shared",
+ "android_vendor.29_arm_armv7-a-neon_shared_1",
+ "android_vendor.29_arm_armv7-a-neon_shared_2",
+ "android_vendor.29_arm_armv7-a-neon_shared_current",
+ "android_vendor.29_arm_armv7-a-neon_shared",
+ }
+ android.AssertArrayString(t, "variants for llndk stubs", expected, actual)
+
+ params := result.ModuleForTests("libllndk", "android_vendor.29_arm_armv7-a-neon_shared").Description("generate stub")
+ android.AssertSame(t, "use VNDK version for default stubs", "current", params.Args["apiLevel"])
+
+ params = result.ModuleForTests("libllndk", "android_vendor.29_arm_armv7-a-neon_shared_1").Description("generate stub")
+ android.AssertSame(t, "override apiLevel for versioned stubs", "1", params.Args["apiLevel"])
+
+ checkExportedIncludeDirs := func(module, variant string, expectedDirs ...string) {
+ t.Helper()
+ m := result.ModuleForTests(module, variant).Module()
+ f := result.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
+ android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
+ expectedDirs, f.IncludeDirs)
+ }
+
+ checkExportedIncludeDirs("libllndk", "android_arm64_armv8-a_shared", "include")
+ checkExportedIncludeDirs("libllndk", "android_vendor.29_arm64_armv8-a_shared", "include")
+ checkExportedIncludeDirs("libllndk_with_external_headers", "android_arm64_armv8-a_shared", "include")
+ checkExportedIncludeDirs("libllndk_with_external_headers", "android_vendor.29_arm64_armv8-a_shared", "include_llndk")
+ checkExportedIncludeDirs("libllndk_with_override_headers", "android_arm64_armv8-a_shared", "include")
+ checkExportedIncludeDirs("libllndk_with_override_headers", "android_vendor.29_arm64_armv8-a_shared", "include_llndk")
+}
+
func TestLlndkHeaders(t *testing.T) {
ctx := testCc(t, `
llndk_headers {
diff --git a/cc/library.go b/cc/library.go
index 9a2b02e..8acd7c7 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -403,8 +403,8 @@
func (f *flagExporter) setProvider(ctx android.ModuleContext) {
ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{
- IncludeDirs: f.dirs,
- SystemIncludeDirs: f.systemDirs,
+ IncludeDirs: android.FirstUniquePaths(f.dirs),
+ SystemIncludeDirs: android.FirstUniquePaths(f.systemDirs),
Flags: f.flags,
Deps: f.deps,
GeneratedHeaders: f.headers,
@@ -959,9 +959,8 @@
if ctx.IsLlndk() {
// LLNDK libraries ignore most of the properties on the cc_library and use the
// LLNDK-specific properties instead.
- deps.HeaderLibs = append(deps.HeaderLibs, library.Properties.Llndk.Export_llndk_headers...)
- deps.ReexportHeaderLibHeaders = append(deps.ReexportHeaderLibHeaders,
- library.Properties.Llndk.Export_llndk_headers...)
+ deps.HeaderLibs = append([]string(nil), library.Properties.Llndk.Export_llndk_headers...)
+ deps.ReexportHeaderLibHeaders = append([]string(nil), library.Properties.Llndk.Export_llndk_headers...)
return deps
}
@@ -1406,6 +1405,12 @@
library.reexportDeps(timestampFiles...)
}
+ // override the module's export_include_dirs with llndk.override_export_include_dirs
+ // if it is set.
+ if override := library.Properties.Llndk.Override_export_include_dirs; override != nil {
+ library.flagExporter.Properties.Export_include_dirs = override
+ }
+
if Bool(library.Properties.Llndk.Export_headers_as_system) {
library.flagExporter.Properties.Export_system_include_dirs = append(
library.flagExporter.Properties.Export_system_include_dirs,
@@ -1667,6 +1672,13 @@
// hasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs.
func (library *libraryDecorator) hasLLNDKStubs() bool {
+ return library.hasVestigialLLNDKLibrary() || String(library.Properties.Llndk.Symbol_file) != ""
+}
+
+// hasVestigialLLNDKLibrary returns true if this cc_library module has a corresponding llndk_library
+// module containing properties describing the LLNDK variant.
+// TODO(b/170784825): remove this once there are no more llndk_library modules.
+func (library *libraryDecorator) hasVestigialLLNDKLibrary() bool {
return String(library.Properties.Llndk_stubs) != ""
}
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index a46b31c..d05dbce 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -56,7 +56,12 @@
Unversioned *bool
// list of llndk headers to re-export include directories from.
- Export_llndk_headers []string `android:"arch_variant"`
+ Export_llndk_headers []string
+
+ // list of directories relative to the Blueprints file that willbe added to the include path
+ // (using -I) for any module that links against the LLNDK variant of this module, replacing
+ // any that were listed outside the llndk clause.
+ Override_export_include_dirs []string
// whether this module can be directly depended upon by libs that are installed
// to /vendor and /product.
diff --git a/cc/vndk.go b/cc/vndk.go
index 41f9fd3..e224e66 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -233,7 +233,7 @@
type moduleListerFunc func(ctx android.SingletonContext) (moduleNames, fileNames []string)
var (
- llndkLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsLLNDK && !isVestigialLLNDKModule(m) })
+ llndkLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsLLNDK && !isVestigialLLNDKModule(m) && !m.Header() })
llndkLibrariesWithoutHWASAN = vndkModuleListRemover(llndkLibraries, "libclang_rt.hwasan-")
vndkSPLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKSP })
vndkCoreLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKCore })
@@ -423,15 +423,24 @@
lib, isLib := m.linker.(*libraryDecorator)
prebuiltLib, isPrebuiltLib := m.linker.(*prebuiltLibraryLinker)
- if m.UseVndk() && isLib && lib.hasLLNDKStubs() {
+ if m.UseVndk() && isLib && lib.hasVestigialLLNDKLibrary() {
llndk := mctx.AddVariationDependencies(nil, llndkStubDepTag, String(lib.Properties.Llndk_stubs))
mergeLLNDKToLib(llndk[0].(*Module), &lib.Properties.Llndk, &lib.flagExporter)
}
- if m.UseVndk() && isPrebuiltLib && prebuiltLib.hasLLNDKStubs() {
+ if m.UseVndk() && isPrebuiltLib && prebuiltLib.hasVestigialLLNDKLibrary() {
llndk := mctx.AddVariationDependencies(nil, llndkStubDepTag, String(prebuiltLib.Properties.Llndk_stubs))
mergeLLNDKToLib(llndk[0].(*Module), &prebuiltLib.Properties.Llndk, &prebuiltLib.flagExporter)
}
+ if m.UseVndk() && isLib && lib.hasLLNDKStubs() && !lib.hasVestigialLLNDKLibrary() {
+ m.VendorProperties.IsLLNDK = true
+ m.VendorProperties.IsVNDKPrivate = Bool(lib.Properties.Llndk.Private)
+ }
+ if m.UseVndk() && isPrebuiltLib && prebuiltLib.hasLLNDKStubs() && !prebuiltLib.hasVestigialLLNDKLibrary() {
+ m.VendorProperties.IsLLNDK = true
+ m.VendorProperties.IsVNDKPrivate = Bool(prebuiltLib.Properties.Llndk.Private)
+ }
+
if (isLib && lib.buildShared()) || (isPrebuiltLib && prebuiltLib.buildShared()) {
if m.vndkdep != nil && m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
processVndkLibrary(mctx, m)
diff --git a/java/Android.bp b/java/Android.bp
index 888b01b..8e3e10d 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -83,6 +83,7 @@
"java_test.go",
"jdeps_test.go",
"kotlin_test.go",
+ "lint_test.go",
"platform_bootclasspath_test.go",
"platform_compat_config_test.go",
"plugin_test.go",
diff --git a/java/boot_image.go b/java/boot_image.go
index 78215f0..d0862a9 100644
--- a/java/boot_image.go
+++ b/java/boot_image.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "path/filepath"
"strings"
"android/soong/android"
@@ -53,7 +54,7 @@
ctx.RegisterModuleType("prebuilt_bootclasspath_fragment", prebuiltBootImageFactory)
}
-type bootImageContentDependencyTag struct {
+type bootclasspathFragmentContentDependencyTag struct {
blueprint.BaseDependencyTag
}
@@ -62,16 +63,22 @@
// This is a temporary workaround to make it easier to migrate to boot image modules with proper
// dependencies.
// TODO(b/177892522): Remove this and add needed visibility.
-func (b bootImageContentDependencyTag) ExcludeFromVisibilityEnforcement() {
+func (b bootclasspathFragmentContentDependencyTag) ExcludeFromVisibilityEnforcement() {
+}
+
+// The bootclasspath_fragment contents must never depend on prebuilts.
+func (b bootclasspathFragmentContentDependencyTag) ReplaceSourceWithPrebuilt() bool {
+ return false
}
// The tag used for the dependency between the boot image module and its contents.
-var bootImageContentDepTag = bootImageContentDependencyTag{}
+var bootclasspathFragmentContentDepTag = bootclasspathFragmentContentDependencyTag{}
-var _ android.ExcludeFromVisibilityEnforcementTag = bootImageContentDepTag
+var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathFragmentContentDepTag
+var _ android.ReplaceSourceWithPrebuilt = bootclasspathFragmentContentDepTag
-func IsbootImageContentDepTag(tag blueprint.DependencyTag) bool {
- return tag == bootImageContentDepTag
+func IsBootclasspathFragmentContentDepTag(tag blueprint.DependencyTag) bool {
+ return tag == bootclasspathFragmentContentDepTag
}
type bootImageProperties struct {
@@ -187,7 +194,7 @@
func (b *BootImageModule) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
tag := ctx.OtherModuleDependencyTag(dep)
- if tag == bootImageContentDepTag {
+ if IsBootclasspathFragmentContentDepTag(tag) {
// Boot image contents are automatically added to apex.
return true
}
@@ -202,8 +209,28 @@
return nil
}
+// ComponentDepsMutator adds dependencies onto modules before any prebuilt modules without a
+// corresponding source module are renamed. This means that adding a dependency using a name without
+// a prebuilt_ prefix will always resolve to a source module and when using a name with that prefix
+// it will always resolve to a prebuilt module.
+func (b *BootImageModule) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
+ module := ctx.Module()
+ _, isSourceModule := module.(*BootImageModule)
+
+ for _, name := range b.properties.Contents {
+ // A bootclasspath_fragment must depend only on other source modules, while the
+ // prebuilt_bootclasspath_fragment must only depend on other prebuilt modules.
+ //
+ // TODO(b/177892522) - avoid special handling of jacocoagent.
+ if !isSourceModule && name != "jacocoagent" {
+ name = android.PrebuiltNameFromSource(name)
+ }
+ ctx.AddDependency(module, bootclasspathFragmentContentDepTag, name)
+ }
+
+}
+
func (b *BootImageModule) DepsMutator(ctx android.BottomUpMutatorContext) {
- ctx.AddDependency(ctx.Module(), bootImageContentDepTag, b.properties.Contents...)
if SkipDexpreoptBootJars(ctx) {
return
@@ -295,19 +322,58 @@
type bootImageSdkMemberProperties struct {
android.SdkMemberPropertiesBase
+ // The image name
Image_name *string
+
+ // Contents of the bootclasspath fragment
+ Contents []string
+
+ // Flag files by *hiddenAPIFlagFileCategory
+ Flag_files_by_category map[*hiddenAPIFlagFileCategory]android.Paths
}
func (b *bootImageSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
module := variant.(*BootImageModule)
b.Image_name = module.properties.Image_name
+ if b.Image_name == nil {
+ // Only one of image_name or contents can be specified. However, if image_name is set then the
+ // contents property is updated to match the configuration used to create the corresponding
+ // boot image. Therefore, contents property is only copied if the image name is not specified.
+ b.Contents = module.properties.Contents
+ }
+
+ // Get the flag file information from the module.
+ mctx := ctx.SdkModuleContext()
+ flagFileInfo := mctx.OtherModuleProvider(module, hiddenAPIFlagFileInfoProvider).(hiddenAPIFlagFileInfo)
+ b.Flag_files_by_category = flagFileInfo.categoryToPaths
}
func (b *bootImageSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
if b.Image_name != nil {
propertySet.AddProperty("image_name", *b.Image_name)
}
+
+ if len(b.Contents) > 0 {
+ propertySet.AddPropertyWithTag("contents", b.Contents, ctx.SnapshotBuilder().SdkMemberReferencePropertyTag(true))
+ }
+
+ builder := ctx.SnapshotBuilder()
+ if b.Flag_files_by_category != nil {
+ hiddenAPISet := propertySet.AddPropertySet("hidden_api")
+ for _, category := range hiddenAPIFlagFileCategories {
+ paths := b.Flag_files_by_category[category]
+ if len(paths) > 0 {
+ dests := []string{}
+ for _, p := range paths {
+ dest := filepath.Join("hiddenapi", p.Base())
+ builder.CopyToSnapshot(p, dest)
+ dests = append(dests, dest)
+ }
+ hiddenAPISet.AddProperty(category.propertyName, dests)
+ }
+ }
+ }
}
var _ android.SdkMemberType = (*bootImageMemberType)(nil)
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index 747b292..8cc6f8f 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -21,6 +21,158 @@
// Contains support for processing hiddenAPI in a modular fashion.
+type hiddenAPIStubsDependencyTag struct {
+ blueprint.BaseDependencyTag
+ sdkKind android.SdkKind
+}
+
+func (b hiddenAPIStubsDependencyTag) ExcludeFromApexContents() {
+}
+
+func (b hiddenAPIStubsDependencyTag) ReplaceSourceWithPrebuilt() bool {
+ return false
+}
+
+// Avoid having to make stubs content explicitly visible to dependent modules.
+//
+// This is a temporary workaround to make it easier to migrate to bootclasspath_fragment modules
+// with proper dependencies.
+// TODO(b/177892522): Remove this and add needed visibility.
+func (b hiddenAPIStubsDependencyTag) ExcludeFromVisibilityEnforcement() {
+}
+
+var _ android.ExcludeFromVisibilityEnforcementTag = hiddenAPIStubsDependencyTag{}
+var _ android.ReplaceSourceWithPrebuilt = hiddenAPIStubsDependencyTag{}
+var _ android.ExcludeFromApexContentsTag = hiddenAPIStubsDependencyTag{}
+
+// hiddenAPIRelevantSdkKinds lists all the android.SdkKind instances that are needed by the hidden
+// API processing.
+var hiddenAPIRelevantSdkKinds = []android.SdkKind{
+ android.SdkPublic,
+ android.SdkSystem,
+ android.SdkTest,
+ android.SdkCorePlatform,
+}
+
+// hiddenAPIComputeMonolithicStubLibModules computes the set of module names that provide stubs
+// needed to produce the hidden API monolithic stub flags file.
+func hiddenAPIComputeMonolithicStubLibModules(config android.Config) map[android.SdkKind][]string {
+ var publicStubModules []string
+ var systemStubModules []string
+ var testStubModules []string
+ var corePlatformStubModules []string
+
+ if config.AlwaysUsePrebuiltSdks() {
+ // Build configuration mandates using prebuilt stub modules
+ publicStubModules = append(publicStubModules, "sdk_public_current_android")
+ systemStubModules = append(systemStubModules, "sdk_system_current_android")
+ testStubModules = append(testStubModules, "sdk_test_current_android")
+ } else {
+ // Use stub modules built from source
+ publicStubModules = append(publicStubModules, "android_stubs_current")
+ systemStubModules = append(systemStubModules, "android_system_stubs_current")
+ testStubModules = append(testStubModules, "android_test_stubs_current")
+ }
+ // We do not have prebuilts of the core platform api yet
+ corePlatformStubModules = append(corePlatformStubModules, "legacy.core.platform.api.stubs")
+
+ // Allow products to define their own stubs for custom product jars that apps can use.
+ publicStubModules = append(publicStubModules, config.ProductHiddenAPIStubs()...)
+ systemStubModules = append(systemStubModules, config.ProductHiddenAPIStubsSystem()...)
+ testStubModules = append(testStubModules, config.ProductHiddenAPIStubsTest()...)
+ if config.IsEnvTrue("EMMA_INSTRUMENT") {
+ publicStubModules = append(publicStubModules, "jacoco-stubs")
+ }
+
+ m := map[android.SdkKind][]string{}
+ m[android.SdkPublic] = publicStubModules
+ m[android.SdkSystem] = systemStubModules
+ m[android.SdkTest] = testStubModules
+ m[android.SdkCorePlatform] = corePlatformStubModules
+ return m
+}
+
+// hiddenAPIAddStubLibDependencies adds dependencies onto the modules specified in
+// sdkKindToStubLibModules. It adds them in a well known order and uses an SdkKind specific tag to
+// identify the source of the dependency.
+func hiddenAPIAddStubLibDependencies(ctx android.BottomUpMutatorContext, sdkKindToStubLibModules map[android.SdkKind][]string) {
+ module := ctx.Module()
+ for _, sdkKind := range hiddenAPIRelevantSdkKinds {
+ modules := sdkKindToStubLibModules[sdkKind]
+ ctx.AddDependency(module, hiddenAPIStubsDependencyTag{sdkKind: sdkKind}, modules...)
+ }
+}
+
+// hiddenAPIGatherStubLibDexJarPaths gathers the paths to the dex jars from the dependencies added
+// in hiddenAPIAddStubLibDependencies.
+func hiddenAPIGatherStubLibDexJarPaths(ctx android.ModuleContext) map[android.SdkKind]android.Paths {
+ m := map[android.SdkKind]android.Paths{}
+ ctx.VisitDirectDepsIf(isActiveModule, func(module android.Module) {
+ tag := ctx.OtherModuleDependencyTag(module)
+ if hiddenAPIStubsTag, ok := tag.(hiddenAPIStubsDependencyTag); ok {
+ kind := hiddenAPIStubsTag.sdkKind
+ dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module)
+ if dexJar != nil {
+ m[kind] = append(m[kind], dexJar)
+ }
+ }
+ })
+ return m
+}
+
+// hiddenAPIRetrieveDexJarBuildPath retrieves the DexJarBuildPath from the specified module, if
+// available, or reports an error.
+func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module) android.Path {
+ if j, ok := module.(UsesLibraryDependency); ok {
+ dexJar := j.DexJarBuildPath()
+ if dexJar != nil {
+ return dexJar
+ }
+ ctx.ModuleErrorf("dependency %s does not provide a dex jar, consider setting compile_dex: true", module)
+ } else {
+ ctx.ModuleErrorf("dependency %s of module type %s does not support providing a dex jar", module, ctx.OtherModuleType(module))
+ }
+ return nil
+}
+
+var sdkKindToHiddenapiListOption = map[android.SdkKind]string{
+ android.SdkPublic: "public-stub-classpath",
+ android.SdkSystem: "system-stub-classpath",
+ android.SdkTest: "test-stub-classpath",
+ android.SdkCorePlatform: "core-platform-stub-classpath",
+}
+
+// ruleToGenerateHiddenAPIStubFlagsFile creates a rule to create a hidden API stub flags file.
+//
+// The rule is initialized but not built so that the caller can modify it and select an appropriate
+// name.
+func ruleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, outputPath android.OutputPath, bootDexJars android.Paths, sdkKindToPathList map[android.SdkKind]android.Paths) *android.RuleBuilder {
+ // Singleton rule which applies hiddenapi on all boot class path dex files.
+ rule := android.NewRuleBuilder(pctx, ctx)
+
+ tempPath := tempPathForRestat(ctx, outputPath)
+
+ command := rule.Command().
+ Tool(ctx.Config().HostToolPath(ctx, "hiddenapi")).
+ Text("list").
+ FlagForEachInput("--boot-dex=", bootDexJars)
+
+ // Iterate over the sdk kinds in a fixed order.
+ for _, sdkKind := range hiddenAPIRelevantSdkKinds {
+ paths := sdkKindToPathList[sdkKind]
+ if len(paths) > 0 {
+ option := sdkKindToHiddenapiListOption[sdkKind]
+ command.FlagWithInputList("--"+option+"=", paths, ":")
+ }
+ }
+
+ // Add the output path.
+ command.FlagWithOutput("--out-api-flags=", tempPath)
+
+ commitChangeForRestat(rule, tempPath, outputPath)
+ return rule
+}
+
// HiddenAPIFlagFileProperties contains paths to the flag files that can be used to augment the
// information obtained from annotations within the source code in order to create the complete set
// of flags that should be applied to the dex implementation jars on the bootclasspath.
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 0149609..3cc88e6 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -127,8 +127,6 @@
return
}
- stubFlagsRule(ctx)
-
// If there is a prebuilt hiddenapi dir, generate rules to use the
// files within. Generally, we build the hiddenapi files from source
// during the build, ensuring consistency. It's possible, in a split
@@ -160,109 +158,6 @@
ctx.Strict("INTERNAL_PLATFORM_HIDDENAPI_FLAGS", h.flags.String())
}
-// stubFlagsRule creates the rule to build hiddenapi-stub-flags.txt out of dex jars from stub modules and boot image
-// modules.
-func stubFlagsRule(ctx android.SingletonContext) {
- var publicStubModules []string
- var systemStubModules []string
- var testStubModules []string
- var corePlatformStubModules []string
-
- if ctx.Config().AlwaysUsePrebuiltSdks() {
- // Build configuration mandates using prebuilt stub modules
- publicStubModules = append(publicStubModules, "sdk_public_current_android")
- systemStubModules = append(systemStubModules, "sdk_system_current_android")
- testStubModules = append(testStubModules, "sdk_test_current_android")
- } else {
- // Use stub modules built from source
- publicStubModules = append(publicStubModules, "android_stubs_current")
- systemStubModules = append(systemStubModules, "android_system_stubs_current")
- testStubModules = append(testStubModules, "android_test_stubs_current")
- }
- // We do not have prebuilts of the core platform api yet
- corePlatformStubModules = append(corePlatformStubModules, "legacy.core.platform.api.stubs")
-
- // Allow products to define their own stubs for custom product jars that apps can use.
- publicStubModules = append(publicStubModules, ctx.Config().ProductHiddenAPIStubs()...)
- systemStubModules = append(systemStubModules, ctx.Config().ProductHiddenAPIStubsSystem()...)
- testStubModules = append(testStubModules, ctx.Config().ProductHiddenAPIStubsTest()...)
- if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") {
- publicStubModules = append(publicStubModules, "jacoco-stubs")
- }
-
- publicStubPaths := make(android.Paths, len(publicStubModules))
- systemStubPaths := make(android.Paths, len(systemStubModules))
- testStubPaths := make(android.Paths, len(testStubModules))
- corePlatformStubPaths := make(android.Paths, len(corePlatformStubModules))
-
- moduleListToPathList := map[*[]string]android.Paths{
- &publicStubModules: publicStubPaths,
- &systemStubModules: systemStubPaths,
- &testStubModules: testStubPaths,
- &corePlatformStubModules: corePlatformStubPaths,
- }
-
- var bootDexJars android.Paths
-
- ctx.VisitAllModules(func(module android.Module) {
- // Collect dex jar paths for the modules listed above.
- if j, ok := module.(UsesLibraryDependency); ok {
- name := ctx.ModuleName(module)
- for moduleList, pathList := range moduleListToPathList {
- if i := android.IndexList(name, *moduleList); i != -1 {
- pathList[i] = j.DexJarBuildPath()
- }
- }
- }
-
- // Collect dex jar paths for modules that had hiddenapi encode called on them.
- if h, ok := module.(hiddenAPIIntf); ok {
- if jar := h.bootDexJar(); jar != nil {
- bootDexJars = append(bootDexJars, jar)
- }
- }
- })
-
- var missingDeps []string
- // Ensure all modules were converted to paths
- for moduleList, pathList := range moduleListToPathList {
- for i := range pathList {
- if pathList[i] == nil {
- moduleName := (*moduleList)[i]
- pathList[i] = android.PathForOutput(ctx, "missing/module", moduleName)
- if ctx.Config().AllowMissingDependencies() {
- missingDeps = append(missingDeps, moduleName)
- } else {
- ctx.Errorf("failed to find dex jar path for module %q",
- moduleName)
- }
- }
- }
- }
-
- // Singleton rule which applies hiddenapi on all boot class path dex files.
- rule := android.NewRuleBuilder(pctx, ctx)
-
- outputPath := hiddenAPISingletonPaths(ctx).stubFlags
- tempPath := tempPathForRestat(ctx, outputPath)
-
- rule.MissingDeps(missingDeps)
-
- rule.Command().
- Tool(ctx.Config().HostToolPath(ctx, "hiddenapi")).
- Text("list").
- FlagForEachInput("--boot-dex=", bootDexJars).
- FlagWithInputList("--public-stub-classpath=", publicStubPaths, ":").
- FlagWithInputList("--system-stub-classpath=", systemStubPaths, ":").
- FlagWithInputList("--test-stub-classpath=", testStubPaths, ":").
- FlagWithInputList("--core-platform-stub-classpath=", corePlatformStubPaths, ":").
- FlagWithOutput("--out-api-flags=", tempPath)
-
- commitChangeForRestat(rule, tempPath, outputPath)
-
- rule.Build("hiddenAPIStubFlagsFile", "hiddenapi stub flags")
-}
-
// Checks to see whether the supplied module variant is in the list of boot jars.
//
// This is similar to logic in getBootImageJar() so any changes needed here are likely to be needed
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index 5ea9a5b..3ab2277 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -23,12 +23,20 @@
"github.com/google/blueprint/proptools"
)
+// TODO(b/177892522): Move these tests into a more appropriate place.
+
func fixtureSetPrebuiltHiddenApiDirProductVariable(prebuiltHiddenApiDir *string) android.FixturePreparer {
return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.PrebuiltHiddenApiDir = prebuiltHiddenApiDir
})
}
+var prepareForTestWithDefaultPlatformBootclasspath = android.FixtureAddTextFile("frameworks/base/boot/Android.bp", `
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ }
+`)
+
var hiddenApiFixtureFactory = android.GroupFixturePreparers(
prepareForJavaTest, PrepareForTestWithHiddenApiBuildComponents)
@@ -36,6 +44,7 @@
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
FixtureConfigureBootJars("platform:foo"),
+ prepareForTestWithDefaultPlatformBootclasspath,
).RunTestWithBp(t, `
java_library {
name: "foo",
@@ -44,8 +53,8 @@
}
`)
- hiddenAPI := result.SingletonForTests("hiddenapi")
- hiddenapiRule := hiddenAPI.Rule("hiddenapi")
+ hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
want := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want)
}
@@ -59,6 +68,7 @@
android.GroupFixturePreparers(
hiddenApiFixtureFactory,
FixtureConfigureBootJars("platform:foo"),
+ prepareForTestWithDefaultPlatformBootclasspath,
).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(expectedErrorMessage)).
RunTestWithBp(t, `
java_library {
@@ -79,6 +89,7 @@
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
FixtureConfigureBootJars("platform:foo"),
+ prepareForTestWithDefaultPlatformBootclasspath,
).RunTestWithBp(t, `
java_import {
name: "foo",
@@ -87,8 +98,8 @@
}
`)
- hiddenAPI := result.SingletonForTests("hiddenapi")
- hiddenapiRule := hiddenAPI.Rule("hiddenapi")
+ hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
want := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want)
}
@@ -97,6 +108,7 @@
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
FixtureConfigureBootJars("platform:foo"),
+ prepareForTestWithDefaultPlatformBootclasspath,
).RunTestWithBp(t, `
java_library {
name: "foo",
@@ -112,8 +124,8 @@
}
`)
- hiddenAPI := result.SingletonForTests("hiddenapi")
- hiddenapiRule := hiddenAPI.Rule("hiddenapi")
+ hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
fromSourceJarArg := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, fromSourceJarArg)
@@ -125,6 +137,7 @@
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
FixtureConfigureBootJars("platform:foo"),
+ prepareForTestWithDefaultPlatformBootclasspath,
).RunTestWithBp(t, `
java_library {
name: "foo",
@@ -140,8 +153,8 @@
}
`)
- hiddenAPI := result.SingletonForTests("hiddenapi")
- hiddenapiRule := hiddenAPI.Rule("hiddenapi")
+ hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
prebuiltJarArg := "--boot-dex=out/soong/.intermediates/prebuilt_foo/android_common/dex/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, prebuiltJarArg)
@@ -184,13 +197,14 @@
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
tc.preparer,
+ prepareForTestWithDefaultPlatformBootclasspath,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.Always_use_prebuilt_sdks = proptools.BoolPtr(tc.unbundledBuild)
}),
).RunTest(t)
- hiddenAPI := result.SingletonForTests("hiddenapi")
- hiddenapiRule := hiddenAPI.Rule("hiddenapi")
+ hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
wantPublicStubs := "--public-stub-classpath=" + generateSdkDexPath(tc.publicStub, tc.unbundledBuild)
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantPublicStubs)
diff --git a/java/java_test.go b/java/java_test.go
index e7ea4ef..1b8aec2 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1203,107 +1203,6 @@
}
}
-func TestJavaLint(t *testing.T) {
- ctx, _ := testJavaWithFS(t, `
- java_library {
- name: "foo",
- srcs: [
- "a.java",
- "b.java",
- "c.java",
- ],
- min_sdk_version: "29",
- sdk_version: "system_current",
- }
- `, map[string][]byte{
- "lint-baseline.xml": nil,
- })
-
- foo := ctx.ModuleForTests("foo", "android_common")
-
- sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
- if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml") {
- t.Error("did not pass --baseline flag")
- }
-}
-
-func TestJavaLintWithoutBaseline(t *testing.T) {
- ctx, _ := testJavaWithFS(t, `
- java_library {
- name: "foo",
- srcs: [
- "a.java",
- "b.java",
- "c.java",
- ],
- min_sdk_version: "29",
- sdk_version: "system_current",
- }
- `, map[string][]byte{})
-
- foo := ctx.ModuleForTests("foo", "android_common")
-
- sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
- if strings.Contains(*sboxProto.Commands[0].Command, "--baseline") {
- t.Error("passed --baseline flag for non existent file")
- }
-}
-
-func TestJavaLintRequiresCustomLintFileToExist(t *testing.T) {
- android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestDisallowNonExistentPaths,
- ).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern([]string{`source path "mybaseline.xml" does not exist`})).
- RunTestWithBp(t, `
- java_library {
- name: "foo",
- srcs: [
- ],
- min_sdk_version: "29",
- sdk_version: "system_current",
- lint: {
- baseline_filename: "mybaseline.xml",
- },
- }
- `)
-}
-
-func TestJavaLintUsesCorrectBpConfig(t *testing.T) {
- ctx, _ := testJavaWithFS(t, `
- java_library {
- name: "foo",
- srcs: [
- "a.java",
- "b.java",
- "c.java",
- ],
- min_sdk_version: "29",
- sdk_version: "system_current",
- lint: {
- error_checks: ["SomeCheck"],
- baseline_filename: "mybaseline.xml",
- },
- }
- `, map[string][]byte{
- "mybaseline.xml": nil,
- })
-
- foo := ctx.ModuleForTests("foo", "android_common")
-
- sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
- if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline mybaseline.xml") {
- t.Error("did not use the correct file for baseline")
- }
-
- if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check NewApi") {
- t.Error("should check NewApi errors")
- }
-
- if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check SomeCheck") {
- t.Error("should combine NewApi errors with SomeCheck errors")
- }
-}
-
func TestGeneratedSources(t *testing.T) {
ctx, _ := testJavaWithFS(t, `
java_library {
@@ -1647,31 +1546,51 @@
java_sdk_library {
name: "sdklib",
srcs: ["a.java"],
- impl_only_libs: ["foo"],
- stub_only_libs: ["bar"],
+ libs: ["lib"],
+ static_libs: ["static-lib"],
+ impl_only_libs: ["impl-only-lib"],
+ stub_only_libs: ["stub-only-lib"],
+ stub_only_static_libs: ["stub-only-static-lib"],
}
- java_library {
- name: "foo",
+ java_defaults {
+ name: "defaults",
srcs: ["a.java"],
sdk_version: "current",
}
- java_library {
- name: "bar",
- srcs: ["a.java"],
- sdk_version: "current",
- }
+ java_library { name: "lib", defaults: ["defaults"] }
+ java_library { name: "static-lib", defaults: ["defaults"] }
+ java_library { name: "impl-only-lib", defaults: ["defaults"] }
+ java_library { name: "stub-only-lib", defaults: ["defaults"] }
+ java_library { name: "stub-only-static-lib", defaults: ["defaults"] }
`)
-
- for _, implName := range []string{"sdklib", "sdklib.impl"} {
- implJavacCp := result.ModuleForTests(implName, "android_common").Rule("javac").Args["classpath"]
- if !strings.Contains(implJavacCp, "/foo.jar") || strings.Contains(implJavacCp, "/bar.jar") {
- t.Errorf("%v javac classpath %v does not contain foo and not bar", implName, implJavacCp)
- }
+ var expectations = []struct {
+ lib string
+ on_impl_classpath bool
+ on_stub_classpath bool
+ in_impl_combined bool
+ in_stub_combined bool
+ }{
+ {lib: "lib", on_impl_classpath: true},
+ {lib: "static-lib", in_impl_combined: true},
+ {lib: "impl-only-lib", on_impl_classpath: true},
+ {lib: "stub-only-lib", on_stub_classpath: true},
+ {lib: "stub-only-static-lib", in_stub_combined: true},
}
- stubName := apiScopePublic.stubsLibraryModuleName("sdklib")
- stubsJavacCp := result.ModuleForTests(stubName, "android_common").Rule("javac").Args["classpath"]
- if strings.Contains(stubsJavacCp, "/foo.jar") || !strings.Contains(stubsJavacCp, "/bar.jar") {
- t.Errorf("stubs javac classpath %v does not contain bar and not foo", stubsJavacCp)
+ verify := func(sdklib, dep string, cp, combined bool) {
+ sdklibCp := result.ModuleForTests(sdklib, "android_common").Rule("javac").Args["classpath"]
+ expected := cp || combined // Every combined jar is also on the classpath.
+ android.AssertStringContainsEquals(t, "bad classpath for "+sdklib, sdklibCp, "/"+dep+".jar", expected)
+
+ combineJarInputs := result.ModuleForTests(sdklib, "android_common").Rule("combineJar").Inputs.Strings()
+ depPath := filepath.Join("out", "soong", ".intermediates", dep, "android_common", "turbine-combined", dep+".jar")
+ android.AssertStringListContainsEquals(t, "bad combined inputs for "+sdklib, combineJarInputs, depPath, combined)
+ }
+ for _, expectation := range expectations {
+ verify("sdklib", expectation.lib, expectation.on_impl_classpath, expectation.in_impl_combined)
+ verify("sdklib.impl", expectation.lib, expectation.on_impl_classpath, expectation.in_impl_combined)
+
+ stubName := apiScopePublic.stubsLibraryModuleName("sdklib")
+ verify(stubName, expectation.lib, expectation.on_stub_classpath, expectation.in_stub_combined)
}
}
diff --git a/java/lint.go b/java/lint.go
index a77daa8..862c9b4 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -26,6 +26,10 @@
"android/soong/remoteexec"
)
+// lint checks automatically enforced for modules that have different min_sdk_version than
+// sdk_version
+var updatabilityChecks = []string{"NewApi"}
+
type LintProperties struct {
// Controls for running Android Lint on the module.
Lint struct {
@@ -53,6 +57,9 @@
// Name of the file that lint uses as the baseline. Defaults to "lint-baseline.xml".
Baseline_filename *string
+
+ // If true, baselining updatability lint checks (e.g. NewApi) is prohibited. Defaults to false.
+ Strict_updatability_linting *bool
}
}
@@ -253,6 +260,13 @@
cmd.FlagForEachArg("--error_check ", l.properties.Lint.Error_checks)
cmd.FlagForEachArg("--fatal_check ", l.properties.Lint.Fatal_checks)
+ if BoolDefault(l.properties.Lint.Strict_updatability_linting, false) {
+ if baselinePath := l.getBaselineFilepath(ctx); baselinePath.Valid() {
+ cmd.FlagWithInput("--baseline ", baselinePath.Path())
+ cmd.FlagForEachArg("--disallowed_issues ", updatabilityChecks)
+ }
+ }
+
return lintPaths{
projectXML: projectXMLPath,
configXML: configXMLPath,
@@ -298,7 +312,17 @@
}
if l.minSdkVersion != l.compileSdkVersion {
- l.extraMainlineLintErrors = append(l.extraMainlineLintErrors, "NewApi")
+ l.extraMainlineLintErrors = append(l.extraMainlineLintErrors, updatabilityChecks...)
+ _, filtered := android.FilterList(l.properties.Lint.Warning_checks, updatabilityChecks)
+ if len(filtered) != 0 {
+ ctx.PropertyErrorf("lint.warning_checks",
+ "Can't treat %v checks as warnings if min_sdk_version is different from sdk_version.", filtered)
+ }
+ _, filtered = android.FilterList(l.properties.Lint.Disabled_checks, updatabilityChecks)
+ if len(filtered) != 0 {
+ ctx.PropertyErrorf("lint.disabled_checks",
+ "Can't disable %v checks if min_sdk_version is different from sdk_version.", filtered)
+ }
}
extraLintCheckModules := ctx.GetDirectDepsWithTag(extraLintCheckTag)
diff --git a/java/lint_test.go b/java/lint_test.go
new file mode 100644
index 0000000..a253df9
--- /dev/null
+++ b/java/lint_test.go
@@ -0,0 +1,204 @@
+// Copyright 2021 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+ "strings"
+ "testing"
+
+ "android/soong/android"
+)
+
+func TestJavaLint(t *testing.T) {
+ ctx, _ := testJavaWithFS(t, `
+ java_library {
+ name: "foo",
+ srcs: [
+ "a.java",
+ "b.java",
+ "c.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "system_current",
+ }
+ `, map[string][]byte{
+ "lint-baseline.xml": nil,
+ })
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+
+ sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
+ if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml") {
+ t.Error("did not pass --baseline flag")
+ }
+}
+
+func TestJavaLintWithoutBaseline(t *testing.T) {
+ ctx, _ := testJavaWithFS(t, `
+ java_library {
+ name: "foo",
+ srcs: [
+ "a.java",
+ "b.java",
+ "c.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "system_current",
+ }
+ `, map[string][]byte{})
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+
+ sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
+ if strings.Contains(*sboxProto.Commands[0].Command, "--baseline") {
+ t.Error("passed --baseline flag for non existent file")
+ }
+}
+
+func TestJavaLintRequiresCustomLintFileToExist(t *testing.T) {
+ android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestDisallowNonExistentPaths,
+ ).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern([]string{`source path "mybaseline.xml" does not exist`})).
+ RunTestWithBp(t, `
+ java_library {
+ name: "foo",
+ srcs: [
+ ],
+ min_sdk_version: "29",
+ sdk_version: "system_current",
+ lint: {
+ baseline_filename: "mybaseline.xml",
+ },
+ }
+ `)
+}
+
+func TestJavaLintUsesCorrectBpConfig(t *testing.T) {
+ ctx, _ := testJavaWithFS(t, `
+ java_library {
+ name: "foo",
+ srcs: [
+ "a.java",
+ "b.java",
+ "c.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "system_current",
+ lint: {
+ error_checks: ["SomeCheck"],
+ baseline_filename: "mybaseline.xml",
+ },
+ }
+ `, map[string][]byte{
+ "mybaseline.xml": nil,
+ })
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+
+ sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
+ if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline mybaseline.xml") {
+ t.Error("did not use the correct file for baseline")
+ }
+
+ if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check NewApi") {
+ t.Error("should check NewApi errors")
+ }
+
+ if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check SomeCheck") {
+ t.Error("should combine NewApi errors with SomeCheck errors")
+ }
+}
+
+func TestJavaLintBypassUpdatableChecks(t *testing.T) {
+ testCases := []struct {
+ name string
+ bp string
+ error string
+ }{
+ {
+ name: "warning_checks",
+ bp: `
+ java_library {
+ name: "foo",
+ srcs: [
+ "a.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "current",
+ lint: {
+ warning_checks: ["NewApi"],
+ },
+ }
+ `,
+ error: "lint.warning_checks: Can't treat \\[NewApi\\] checks as warnings if min_sdk_version is different from sdk_version.",
+ },
+ {
+ name: "disable_checks",
+ bp: `
+ java_library {
+ name: "foo",
+ srcs: [
+ "a.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "current",
+ lint: {
+ disabled_checks: ["NewApi"],
+ },
+ }
+ `,
+ error: "lint.disabled_checks: Can't disable \\[NewApi\\] checks if min_sdk_version is different from sdk_version.",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ errorHandler := android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.error)
+ android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules).
+ ExtendWithErrorHandler(errorHandler).
+ RunTestWithBp(t, testCase.bp)
+ })
+ }
+}
+
+func TestJavaLintStrictUpdatabilityLinting(t *testing.T) {
+ bp := `
+ java_library {
+ name: "foo",
+ srcs: [
+ "a.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "current",
+ lint: {
+ strict_updatability_linting: true,
+ },
+ }
+ `
+ fs := android.MockFS{
+ "lint-baseline.xml": nil,
+ }
+
+ result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, fs.AddToFixture()).
+ RunTestWithBp(t, bp)
+
+ foo := result.ModuleForTests("foo", "android_common")
+ sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
+ if !strings.Contains(*sboxProto.Commands[0].Command,
+ "--baseline lint-baseline.xml --disallowed_issues NewApi") {
+ t.Error("did not restrict baselining NewApi")
+ }
+}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index ba758dd..568f5e4 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -140,6 +140,8 @@
}
func (b *platformBootclasspathModule) DepsMutator(ctx android.BottomUpMutatorContext) {
+ b.hiddenAPIDepsMutator(ctx)
+
if SkipDexpreoptBootJars(ctx) {
return
}
@@ -149,6 +151,16 @@
dexpreopt.RegisterToolDeps(ctx)
}
+func (b *platformBootclasspathModule) hiddenAPIDepsMutator(ctx android.BottomUpMutatorContext) {
+ if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
+ return
+ }
+
+ // Add dependencies onto the stub lib modules.
+ sdkKindToStubLibModules := hiddenAPIComputeMonolithicStubLibModules(ctx.Config())
+ hiddenAPIAddStubLibDependencies(ctx, sdkKindToStubLibModules)
+}
+
func platformBootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
m := ctx.Module()
if p, ok := m.(*platformBootclasspathModule); ok {
@@ -353,10 +365,24 @@
baseFlagsPath := hiddenAPISingletonPaths(ctx).stubFlags
ruleToGenerateHiddenApiFlags(ctx, outputPath, baseFlagsPath, moduleSpecificFlagsPaths, flagFileInfo)
+ b.generateHiddenAPIStubFlagsRules(ctx, hiddenAPISupportingModules)
b.generateHiddenAPIIndexRules(ctx, hiddenAPISupportingModules)
b.generatedHiddenAPIMetadataRules(ctx, hiddenAPISupportingModules)
}
+func (b *platformBootclasspathModule) generateHiddenAPIStubFlagsRules(ctx android.ModuleContext, modules []hiddenAPISupportingModule) {
+ bootDexJars := android.Paths{}
+ for _, module := range modules {
+ bootDexJars = append(bootDexJars, module.bootDexJar())
+ }
+
+ sdkKindToStubPaths := hiddenAPIGatherStubLibDexJarPaths(ctx)
+
+ outputPath := hiddenAPISingletonPaths(ctx).stubFlags
+ rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, outputPath, bootDexJars, sdkKindToStubPaths)
+ rule.Build("platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags")
+}
+
func (b *platformBootclasspathModule) generateHiddenAPIIndexRules(ctx android.ModuleContext, modules []hiddenAPISupportingModule) {
indexes := android.Paths{}
for _, module := range modules {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 223be5c..05ce97a 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -399,6 +399,9 @@
// List of Java libraries that will be in the classpath when building stubs
Stub_only_libs []string `android:"arch_variant"`
+ // List of Java libraries that will included in stub libraries
+ Stub_only_static_libs []string `android:"arch_variant"`
+
// list of package names that will be documented and publicized as API.
// This allows the API to be restricted to a subset of the source files provided.
// If this is unspecified then all the source files will be treated as being part
@@ -1275,6 +1278,7 @@
System_modules *string
Patch_module *string
Libs []string
+ Static_libs []string
Compile_dex *bool
Java_version *string
Openjdk9 struct {
@@ -1299,6 +1303,7 @@
props.Patch_module = module.properties.Patch_module
props.Installable = proptools.BoolPtr(false)
props.Libs = module.sdkLibraryProperties.Stub_only_libs
+ props.Static_libs = module.sdkLibraryProperties.Stub_only_static_libs
// The stub-annotations library contains special versions of the annotations
// with CLASS retention policy, so that they're kept.
if proptools.Bool(module.sdkLibraryProperties.Annotations_enabled) {
diff --git a/java/testing.go b/java/testing.go
index aee0710..08a71b8 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -200,6 +200,9 @@
}),
dexpreopt.FixtureSetBootJars(bootJars...),
dexpreopt.FixtureSetArtBootJars(artBootJars...),
+
+ // Add a fake dex2oatd module.
+ dexpreopt.PrepareForTestWithFakeDex2oatd,
)
}
@@ -212,6 +215,9 @@
variables.UpdatableBootJars = android.CreateTestConfiguredJarList(bootJars)
}),
dexpreopt.FixtureSetUpdatableBootJars(bootJars...),
+
+ // Add a fake dex2oatd module.
+ dexpreopt.PrepareForTestWithFakeDex2oatd,
)
}
diff --git a/scripts/hiddenapi/generate_hiddenapi_lists.py b/scripts/hiddenapi/generate_hiddenapi_lists.py
index 6816475..5ab93d1 100755
--- a/scripts/hiddenapi/generate_hiddenapi_lists.py
+++ b/scripts/hiddenapi/generate_hiddenapi_lists.py
@@ -332,7 +332,7 @@
def main(argv):
# Parse arguments.
args = vars(get_args())
- flagfiles = parse_ordered_flags(args['ordered_flags'])
+ flagfiles = parse_ordered_flags(args['ordered_flags'] or [])
# Initialize API->flags dictionary.
flags = FlagsDict()
diff --git a/sdk/Android.bp b/sdk/Android.bp
index 7b034e6..09a7286 100644
--- a/sdk/Android.bp
+++ b/sdk/Android.bp
@@ -20,7 +20,7 @@
"update.go",
],
testSrcs: [
- "boot_image_sdk_test.go",
+ "bootclasspath_fragment_sdk_test.go",
"bp_test.go",
"cc_sdk_test.go",
"compat_config_sdk_test.go",
diff --git a/sdk/boot_image_sdk_test.go b/sdk/boot_image_sdk_test.go
deleted file mode 100644
index 5a03e34..0000000
--- a/sdk/boot_image_sdk_test.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (C) 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package sdk
-
-import (
- "testing"
-
- "android/soong/android"
-)
-
-func TestSnapshotWithBootImage(t *testing.T) {
- result := android.GroupFixturePreparers(
- prepareForSdkTestWithJava,
- android.FixtureWithRootAndroidBp(`
- sdk {
- name: "mysdk",
- boot_images: ["mybootimage"],
- }
-
- boot_image {
- name: "mybootimage",
- image_name: "art",
- }
- `),
- ).RunTest(t)
-
- CheckSnapshot(t, result, "mysdk", "",
- checkUnversionedAndroidBpContents(`
-// This is auto-generated. DO NOT EDIT.
-
-prebuilt_boot_image {
- name: "mybootimage",
- prefer: false,
- visibility: ["//visibility:public"],
- apex_available: ["//apex_available:platform"],
- image_name: "art",
-}
-`),
- checkVersionedAndroidBpContents(`
-// This is auto-generated. DO NOT EDIT.
-
-prebuilt_boot_image {
- name: "mysdk_mybootimage@current",
- sdk_member_name: "mybootimage",
- visibility: ["//visibility:public"],
- apex_available: ["//apex_available:platform"],
- image_name: "art",
-}
-
-sdk_snapshot {
- name: "mysdk@current",
- visibility: ["//visibility:public"],
- boot_images: ["mysdk_mybootimage@current"],
-}
-`),
- checkAllCopyRules(""))
-}
-
-// Test that boot_image works with sdk.
-func TestBasicSdkWithBootImage(t *testing.T) {
- android.GroupFixturePreparers(
- prepareForSdkTestWithApex,
- prepareForSdkTestWithJava,
- android.FixtureWithRootAndroidBp(`
- sdk {
- name: "mysdk",
- boot_images: ["mybootimage"],
- }
-
- boot_image {
- name: "mybootimage",
- image_name: "art",
- apex_available: ["myapex"],
- }
-
- sdk_snapshot {
- name: "mysdk@1",
- boot_images: ["mybootimage_mysdk_1"],
- }
-
- prebuilt_boot_image {
- name: "mybootimage_mysdk_1",
- sdk_member_name: "mybootimage",
- prefer: false,
- visibility: ["//visibility:public"],
- apex_available: [
- "myapex",
- ],
- image_name: "art",
- }
- `),
- ).RunTest(t)
-}
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
new file mode 100644
index 0000000..0ce4351
--- /dev/null
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -0,0 +1,355 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package sdk
+
+import (
+ "testing"
+
+ "android/soong/android"
+ "android/soong/java"
+)
+
+func TestSnapshotWithBootclasspathFragment_ImageName(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForSdkTestWithJava,
+ prepareForSdkTestWithApex,
+
+ // Some additional files needed for the art apex.
+ android.FixtureMergeMockFs(android.MockFS{
+ "com.android.art.avbpubkey": nil,
+ "com.android.art.pem": nil,
+ "system/sepolicy/apex/com.android.art-file_contexts": nil,
+ }),
+ java.FixtureConfigureBootJars("com.android.art:mybootlib"),
+ android.FixtureWithRootAndroidBp(`
+ sdk {
+ name: "mysdk",
+ bootclasspath_fragments: ["mybootclasspathfragment"],
+ java_boot_libs: ["mybootlib"],
+ }
+
+ apex {
+ name: "com.android.art",
+ key: "com.android.art.key",
+ bootclasspath_fragments: [
+ "mybootclasspathfragment",
+ ],
+ updatable: false,
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ image_name: "art",
+ apex_available: ["com.android.art"],
+ }
+
+ apex_key {
+ name: "com.android.art.key",
+ public_key: "com.android.art.avbpubkey",
+ private_key: "com.android.art.pem",
+ }
+
+ java_library {
+ name: "mybootlib",
+ srcs: ["Test.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ compile_dex: true,
+ apex_available: ["com.android.art"],
+ }
+ `),
+ ).RunTest(t)
+
+ CheckSnapshot(t, result, "mysdk", "",
+ checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+prebuilt_bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["com.android.art"],
+ image_name: "art",
+}
+
+java_import {
+ name: "mybootlib",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["com.android.art"],
+ jars: ["java/mybootlib.jar"],
+}
+`),
+ checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+prebuilt_bootclasspath_fragment {
+ name: "mysdk_mybootclasspathfragment@current",
+ sdk_member_name: "mybootclasspathfragment",
+ visibility: ["//visibility:public"],
+ apex_available: ["com.android.art"],
+ image_name: "art",
+}
+
+java_import {
+ name: "mysdk_mybootlib@current",
+ sdk_member_name: "mybootlib",
+ visibility: ["//visibility:public"],
+ apex_available: ["com.android.art"],
+ jars: ["java/mybootlib.jar"],
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ visibility: ["//visibility:public"],
+ bootclasspath_fragments: ["mysdk_mybootclasspathfragment@current"],
+ java_boot_libs: ["mysdk_mybootlib@current"],
+}
+`),
+ checkAllCopyRules(`
+.intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar
+`),
+ snapshotTestPreparer(checkSnapshotPreferredWithSource, android.GroupFixturePreparers(
+ android.FixtureAddTextFile("prebuilts/apex/Android.bp", `
+ prebuilt_apex {
+ name: "com.android.art",
+ src: "art.apex",
+ exported_java_libs: [
+ "mybootlib",
+ ],
+ }
+ `),
+ android.FixtureAddFile("prebuilts/apex/art.apex", nil),
+ ),
+ ),
+ )
+}
+
+func TestSnapshotWithBootClasspathFragment_Contents(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForSdkTestWithJava,
+ android.FixtureWithRootAndroidBp(`
+ sdk {
+ name: "mysdk",
+ bootclasspath_fragments: ["mybootclasspathfragment"],
+ java_boot_libs: ["mybootlib"],
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ contents: ["mybootlib"],
+ }
+
+ java_library {
+ name: "mybootlib",
+ srcs: ["Test.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ compile_dex: true,
+ }
+ `),
+ ).RunTest(t)
+
+ CheckSnapshot(t, result, "mysdk", "",
+ checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+prebuilt_bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ contents: ["mybootlib"],
+}
+
+java_import {
+ name: "mybootlib",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ jars: ["java/mybootlib.jar"],
+}
+`),
+ checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+prebuilt_bootclasspath_fragment {
+ name: "mysdk_mybootclasspathfragment@current",
+ sdk_member_name: "mybootclasspathfragment",
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ contents: ["mysdk_mybootlib@current"],
+}
+
+java_import {
+ name: "mysdk_mybootlib@current",
+ sdk_member_name: "mybootlib",
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ jars: ["java/mybootlib.jar"],
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ visibility: ["//visibility:public"],
+ bootclasspath_fragments: ["mysdk_mybootclasspathfragment@current"],
+ java_boot_libs: ["mysdk_mybootlib@current"],
+}
+`),
+ checkAllCopyRules(`
+.intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar
+`))
+}
+
+// Test that bootclasspath_fragment works with sdk.
+func TestBasicSdkWithBootclasspathFragment(t *testing.T) {
+ android.GroupFixturePreparers(
+ prepareForSdkTestWithApex,
+ prepareForSdkTestWithJava,
+ android.FixtureWithRootAndroidBp(`
+ sdk {
+ name: "mysdk",
+ bootclasspath_fragments: ["mybootclasspathfragment"],
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ image_name: "art",
+ apex_available: ["myapex"],
+ }
+
+ sdk_snapshot {
+ name: "mysdk@1",
+ bootclasspath_fragments: ["mybootclasspathfragment_mysdk_1"],
+ }
+
+ prebuilt_bootclasspath_fragment {
+ name: "mybootclasspathfragment_mysdk_1",
+ sdk_member_name: "mybootclasspathfragment",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: [
+ "myapex",
+ ],
+ image_name: "art",
+ }
+ `),
+ ).RunTest(t)
+}
+
+func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForSdkTestWithJava,
+ android.MockFS{
+ "my-blocked.txt": nil,
+ "my-max-target-o-low-priority.txt": nil,
+ "my-max-target-p.txt": nil,
+ "my-max-target-q.txt": nil,
+ "my-max-target-r-low-priority.txt": nil,
+ "my-removed.txt": nil,
+ "my-unsupported-packages.txt": nil,
+ "my-unsupported.txt": nil,
+ }.AddToFixture(),
+ android.FixtureWithRootAndroidBp(`
+ sdk {
+ name: "mysdk",
+ bootclasspath_fragments: ["mybootclasspathfragment"],
+ java_boot_libs: ["mybootlib"],
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ contents: ["mybootlib"],
+ hidden_api: {
+ unsupported: [
+ "my-unsupported.txt",
+ ],
+ removed: [
+ "my-removed.txt",
+ ],
+ max_target_r_low_priority: [
+ "my-max-target-r-low-priority.txt",
+ ],
+ max_target_q: [
+ "my-max-target-q.txt",
+ ],
+ max_target_p: [
+ "my-max-target-p.txt",
+ ],
+ max_target_o_low_priority: [
+ "my-max-target-o-low-priority.txt",
+ ],
+ blocked: [
+ "my-blocked.txt",
+ ],
+ unsupported_packages: [
+ "my-unsupported-packages.txt",
+ ],
+ },
+ }
+
+ java_library {
+ name: "mybootlib",
+ srcs: ["Test.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ compile_dex: true,
+ }
+ `),
+ ).RunTest(t)
+
+ CheckSnapshot(t, result, "mysdk", "",
+ checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+prebuilt_bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ contents: ["mybootlib"],
+ hidden_api: {
+ unsupported: ["hiddenapi/my-unsupported.txt"],
+ removed: ["hiddenapi/my-removed.txt"],
+ max_target_r_low_priority: ["hiddenapi/my-max-target-r-low-priority.txt"],
+ max_target_q: ["hiddenapi/my-max-target-q.txt"],
+ max_target_p: ["hiddenapi/my-max-target-p.txt"],
+ max_target_o_low_priority: ["hiddenapi/my-max-target-o-low-priority.txt"],
+ blocked: ["hiddenapi/my-blocked.txt"],
+ unsupported_packages: ["hiddenapi/my-unsupported-packages.txt"],
+ },
+}
+
+java_import {
+ name: "mybootlib",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ jars: ["java/mybootlib.jar"],
+}
+`),
+ checkAllCopyRules(`
+my-unsupported.txt -> hiddenapi/my-unsupported.txt
+my-removed.txt -> hiddenapi/my-removed.txt
+my-max-target-r-low-priority.txt -> hiddenapi/my-max-target-r-low-priority.txt
+my-max-target-q.txt -> hiddenapi/my-max-target-q.txt
+my-max-target-p.txt -> hiddenapi/my-max-target-p.txt
+my-max-target-o-low-priority.txt -> hiddenapi/my-max-target-o-low-priority.txt
+my-blocked.txt -> hiddenapi/my-blocked.txt
+my-unsupported-packages.txt -> hiddenapi/my-unsupported-packages.txt
+.intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar
+`),
+ )
+}
diff --git a/sdk/testing.go b/sdk/testing.go
index 9465e13..bf59aed 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -255,13 +255,14 @@
var runSnapshotTestWithCheckers = func(t *testing.T, testConfig snapshotTest, extraPreparer android.FixturePreparer) {
customization := snapshotBuildInfo.snapshotTestCustomization(testConfig)
+ customizedPreparers := android.GroupFixturePreparers(customization.preparers...)
// TODO(b/183184375): Set Config.TestAllowNonExistentPaths = false to verify that all the
// files the snapshot needs are actually copied into the snapshot.
// Run the snapshot with the snapshot preparer and the extra preparer, which must come after as
// it may need to modify parts of the MockFS populated by the snapshot preparer.
- result := android.GroupFixturePreparers(snapshotPreparer, extraPreparer).
+ result := android.GroupFixturePreparers(snapshotPreparer, extraPreparer, customizedPreparers).
ExtendWithErrorHandler(customization.errorHandler).
RunTest(t)
@@ -369,6 +370,15 @@
type resultChecker func(t *testing.T, result *android.TestResult)
+// snapshotTestPreparer registers a preparer that will be used to customize the specified
+// snapshotTest.
+func snapshotTestPreparer(snapshotTest snapshotTest, preparer android.FixturePreparer) snapshotBuildInfoChecker {
+ return func(info *snapshotBuildInfo) {
+ customization := info.snapshotTestCustomization(snapshotTest)
+ customization.preparers = append(customization.preparers, preparer)
+ }
+}
+
// snapshotTestChecker registers a checker that will be run against the result of processing the
// generated snapshot for the specified snapshotTest.
func snapshotTestChecker(snapshotTest snapshotTest, checker resultChecker) snapshotBuildInfoChecker {
@@ -395,6 +405,9 @@
// Encapsulates information provided by each test to customize a specific snapshotTest.
type snapshotTestCustomization struct {
+ // Preparers that are used to customize the test fixture before running the test.
+ preparers []android.FixturePreparer
+
// Checkers that are run on the result of processing the preferred snapshot in a specific test
// case.
checkers []resultChecker