Merge "Enable bp2build for cc modules relying on sysprop"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index cad9ec7..cfaa1d4 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -296,6 +296,8 @@
"system/tools/sysprop": Bp2BuildDefaultTrue,
"system/unwinding/libunwindstack": Bp2BuildDefaultTrueRecursively,
+ "frameworks/proto_logging/stats": Bp2BuildDefaultTrueRecursively,
+
"tools/apksig": Bp2BuildDefaultTrue,
"tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively,
"tools/tradefederation/prebuilts/filegroups": Bp2BuildDefaultTrueRecursively,
@@ -386,6 +388,7 @@
"libnativeloader-headers",
"libnativewindow_headers",
"libneuralnetworks_headers",
+ "libneuralnetworks_packageinfo",
"libopus",
"libpdx_headers",
"libprocpartition",
@@ -425,11 +428,14 @@
"neuralnetworks_types",
"neuralnetworks_utils_hal_aidl",
"neuralnetworks_utils_hal_common",
+ "neuralnetworks_utils_hal_service",
"neuralnetworks_utils_hal_1_0",
"neuralnetworks_utils_hal_1_1",
"neuralnetworks_utils_hal_1_2",
"neuralnetworks_utils_hal_1_3",
"libneuralnetworks_common",
+ // packagemanager_aidl_interface is created implicitly in packagemanager_aidl module
+ "packagemanager_aidl_interface",
"philox_random",
"philox_random_headers",
"server_configurable_flags",
@@ -502,6 +508,45 @@
//frameworks/native/cmds/cmd
"libcmd",
+
+ //system/core/fs_mgr/libdm
+ "libdm",
+
+ //system/core/fs_mgr/libfiemap
+ "libfiemap_headers",
+ "libfiemap_passthrough_srcs",
+ "libfiemap_srcs",
+
+ //system/gsid
+ "libgsi",
+ "libgsi_headers",
+
+ //system/core/libkeyutils
+ "libkeyutils",
+
+ //bootable/recovery/minadbd
+ "libminadbd_headers",
+
+ //bootable/recovery/otautil
+ "libotautil",
+
+ //system/vold
+ "libvold_headers",
+
+ //system/extras/libfscrypt
+ "libfscrypt",
+
+ //system/core/fs_mgr
+ "libfstab",
+
+ //bootable/recovery/fuse_sideload
+ "libfusesideload",
+
+ //system/core/fs_mgr/libfs_avb
+ "libfs_avb",
+
+ //system/core/fs_mgr
+ "libfs_mgr",
}
Bp2buildModuleTypeAlwaysConvertList = []string{
@@ -551,9 +596,6 @@
"prebuilt_platform-robolectric-4.4-prebuilt", // aosp/1999250, needs .aar support in Jars
"prebuilt_platform-robolectric-4.5.1-prebuilt", // aosp/1999250, needs .aar support in Jars
- // proto support
- "libstats_proto_host", // TODO(b/236055697): handle protos from other packages
-
// path property for filegroups
"conscrypt", // TODO(b/210751803), we don't handle path property for filegroups
"conscrypt-for-host", // TODO(b/210751803), we don't handle path property for filegroups
@@ -620,7 +662,6 @@
"pbtombstone", "crash_dump", // depends on libdebuggerd, libunwindstack
"robolectric-sqlite4java-0.282", // depends on unconverted modules: robolectric-sqlite4java-import, robolectric-sqlite4java-native
"static_crasher", // depends on unconverted modules: libdebuggerd_handler
- "stats-log-api-gen", // depends on unconverted modules: libstats_proto_host
"statslog.cpp", "statslog.h", "statslog.rs", // depends on unconverted modules: stats-log-api-gen
"statslog_art.cpp", "statslog_art.h", "statslog_header.rs", // depends on unconverted modules: stats-log-api-gen
"test_fips", // depends on unconverted modules: adb
@@ -1088,6 +1129,12 @@
"libtest_with_dependency_loop_b_tmp",
"libtest_with_dependency_loop_c",
"libtestshared",
+
+ // depends on unconverted libprotobuf-java-nano
+ "dnsresolverprotosnano",
+ "launcherprotosnano",
+ "datastallprotosnano",
+ "devicepolicyprotosnano",
}
Bp2buildCcLibraryStaticOnlyList = []string{}
@@ -1136,6 +1183,20 @@
"prebuilt_platform-robolectric-4.4-prebuilt",
"prebuilt_platform-robolectric-4.5.1-prebuilt",
"prebuilt_currysrc_org.eclipse",
+
+ // TODO(b/247782695 and/or b/242847534) Fix mixed build between unconverted gensrcs and converted filegroup
+ "libstats_atom_enum_protos",
+ "data_stall_event_proto",
+ "device_policy_proto",
+ "dns_resolver_proto",
+ "launcher_proto",
+ "network_stack_proto",
+ "srcs_bluetooth_protos",
+ "srcs_bluetooth_leaudio_protos",
+ "style_proto",
+ "tethering_proto",
+ "text_classifier_proto",
+ "libstats_atom_message_protos",
}
ProdMixedBuildsEnabledList = []string{
diff --git a/android/sdk.go b/android/sdk.go
index a477cba..a9cc547 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -74,6 +74,26 @@
sdkAwareWithoutModule
}
+// minApiLevelForSdkSnapshot provides access to the min_sdk_version for MinApiLevelForSdkSnapshot
+type minApiLevelForSdkSnapshot interface {
+ MinSdkVersion(ctx EarlyModuleContext) SdkSpec
+}
+
+// MinApiLevelForSdkSnapshot returns the ApiLevel of the min_sdk_version of the supplied module.
+//
+// If the module does not provide a min_sdk_version then it defaults to 1.
+func MinApiLevelForSdkSnapshot(ctx EarlyModuleContext, module Module) ApiLevel {
+ minApiLevel := NoneApiLevel
+ if m, ok := module.(minApiLevelForSdkSnapshot); ok {
+ minApiLevel = m.MinSdkVersion(ctx).ApiLevel
+ }
+ if minApiLevel == NoneApiLevel {
+ // The default min API level is 1.
+ minApiLevel = uncheckedFinalApiLevel(1)
+ }
+ return minApiLevel
+}
+
// SdkRef refers to a version of an SDK
type SdkRef struct {
Name string
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index c26ffa7..f633040 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -1367,26 +1367,6 @@
return []string{staticTarget, sharedTarget}
}
-func makeCcStubSuiteTargets(name string, attrs AttrNameToString) string {
- if _, hasStubs := attrs["stubs_symbol_file"]; !hasStubs {
- return ""
- }
- STUB_SUITE_ATTRS := map[string]string{
- "stubs_symbol_file": "symbol_file",
- "stubs_versions": "versions",
- "soname": "soname",
- "source_library": "source_library",
- }
-
- stubSuiteAttrs := AttrNameToString{}
- for key, _ := range attrs {
- if _, stubSuiteAttr := STUB_SUITE_ATTRS[key]; stubSuiteAttr {
- stubSuiteAttrs[STUB_SUITE_ATTRS[key]] = attrs[key]
- }
- }
- return MakeBazelTarget("cc_stub_suite", name+"_stub_libs", stubSuiteAttrs)
-}
-
func TestCCLibraryNoLibCrtFalse(t *testing.T) {
runCcLibraryTestCase(t, Bp2buildTestCase{
ModuleTypeUnderTest: "cc_library",
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index 6116aee..548bade 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -491,6 +491,16 @@
ExpectedBazelTargets: []string{MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
"has_stubs": `True`,
}),
+ makeCcStubSuiteTargets("a", AttrNameToString{
+ "soname": `"a.so"`,
+ "source_library": `":a"`,
+ "stubs_symbol_file": `"a.map.txt"`,
+ "stubs_versions": `[
+ "28",
+ "29",
+ "current",
+ ]`,
+ }),
},
},
)
diff --git a/bp2build/testing.go b/bp2build/testing.go
index edc5c4a..8ce8bb2 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -463,3 +463,23 @@
func (ebr ExpectedRuleTarget) String() string {
return makeBazelTargetHostOrDevice(ebr.Rule, ebr.Name, ebr.Attrs, ebr.Hod)
}
+
+func makeCcStubSuiteTargets(name string, attrs AttrNameToString) string {
+ if _, hasStubs := attrs["stubs_symbol_file"]; !hasStubs {
+ return ""
+ }
+ STUB_SUITE_ATTRS := map[string]string{
+ "stubs_symbol_file": "symbol_file",
+ "stubs_versions": "versions",
+ "soname": "soname",
+ "source_library": "source_library",
+ }
+
+ stubSuiteAttrs := AttrNameToString{}
+ for key, _ := range attrs {
+ if _, stubSuiteAttr := STUB_SUITE_ATTRS[key]; stubSuiteAttr {
+ stubSuiteAttrs[STUB_SUITE_ATTRS[key]] = attrs[key]
+ }
+ }
+ return MakeBazelTarget("cc_stub_suite", name+"_stub_libs", stubSuiteAttrs)
+}
diff --git a/cc/library.go b/cc/library.go
index a8653a0..83a2c68 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -441,6 +441,10 @@
android.CommonAttributes{Name: m.Name()},
sharedTargetAttrs, sharedAttrs.Enabled)
+ createStubsBazelTargetIfNeeded(ctx, m, compilerAttrs, exportedIncludes, baseAttributes)
+}
+
+func createStubsBazelTargetIfNeeded(ctx android.TopDownMutatorContext, m *Module, compilerAttrs compilerAttributes, exportedIncludes BazelIncludes, baseAttributes baseAttributes) {
if compilerAttrs.stubsSymbolFile != nil && len(compilerAttrs.stubsVersions.Value) > 0 {
stubSuitesProps := bazel.BazelTargetModuleProperties{
Rule_class: "cc_stub_suite",
@@ -2707,6 +2711,8 @@
}
ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
+
+ createStubsBazelTargetIfNeeded(ctx, module, compilerAttrs, exportedIncludes, baseAttributes)
}
// TODO(b/199902614): Can this be factored to share with the other Attributes?
diff --git a/java/app.go b/java/app.go
index bccd37f..7f37ff3 100755
--- a/java/app.go
+++ b/java/app.go
@@ -526,7 +526,8 @@
// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
-func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate, ctx android.ModuleContext) []Certificate {
+func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
+ ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
if android.SrcIsModule(certPropValue) == "" {
var mainCert Certificate
if certPropValue != "" {
@@ -558,7 +559,22 @@
}
}
- return certificates
+ if len(certificates) > 0 {
+ mainCertificate = certificates[0]
+ } else {
+ // This can be reached with an empty certificate list if AllowMissingDependencies is set
+ // and the certificate property for this module is a module reference to a missing module.
+ if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
+ panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
+ }
+ // Set a certificate to avoid panics later when accessing it.
+ mainCertificate = Certificate{
+ Key: android.PathForModuleOut(ctx, "missing.pk8"),
+ Pem: android.PathForModuleOut(ctx, "missing.pem"),
+ }
+ }
+
+ return mainCertificate, certificates
}
func (a *AndroidApp) InstallApkName() string {
@@ -632,29 +648,14 @@
dexJarFile := a.dexBuildActions(ctx)
- jniLibs, prebuiltJniPackages, certificateDeps := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
+ jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
if ctx.Failed() {
return
}
- certificates := processMainCert(a.ModuleBase, a.getCertString(ctx), certificateDeps, ctx)
-
- // This can be reached with an empty certificate list if AllowMissingDependencies is set
- // and the certificate property for this module is a module reference to a missing module.
- if len(certificates) > 0 {
- a.certificate = certificates[0]
- } else {
- if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
- panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
- }
- // Set a certificate to avoid panics later when accessing it.
- a.certificate = Certificate{
- Key: android.PathForModuleOut(ctx, "missing.pk8"),
- Pem: android.PathForModuleOut(ctx, "missing.pem"),
- }
- }
+ a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
// Build a final signed app package.
packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
diff --git a/java/app_import.go b/java/app_import.go
index d6dca38..6e603c9 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -318,19 +318,17 @@
if a.isPrebuiltFrameworkRes() {
a.outputFile = srcApk
- certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
+ a.certificate, certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
if len(certificates) != 1 {
ctx.ModuleErrorf("Unexpected number of certificates were extracted: %q", certificates)
}
- a.certificate = certificates[0]
} else if a.preprocessed {
a.outputFile = srcApk
a.certificate = PresignedCertificate
} else if !Bool(a.properties.Presigned) {
// If the certificate property is empty at this point, default_dev_cert must be set to true.
// Which makes processMainCert's behavior for the empty cert string WAI.
- certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
- a.certificate = certificates[0]
+ a.certificate, certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
signed := android.PathForModuleOut(ctx, "signed", apkFilename)
var lineageFile android.Path
if lineage := String(a.properties.Lineage); lineage != "" {
diff --git a/java/app_import_test.go b/java/app_import_test.go
index 41be092..ad27e3a 100644
--- a/java/app_import_test.go
+++ b/java/app_import_test.go
@@ -807,3 +807,23 @@
}
}
}
+
+func TestAppImportMissingCertificateAllowMissingDependencies(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithAllowMissingDependencies,
+ android.PrepareForTestWithAndroidMk,
+ ).RunTestWithBp(t, `
+ android_app_import {
+ name: "foo",
+ apk: "a.apk",
+ certificate: ":missing_certificate",
+ }`)
+
+ foo := result.ModuleForTests("foo", "android_common")
+ fooApk := foo.Output("signed/foo.apk")
+ if fooApk.Rule != android.ErrorRule {
+ t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String())
+ }
+ android.AssertStringDoesContain(t, "expected error rule message", fooApk.Args["error"], "missing dependencies: missing_certificate\n")
+}
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 42a11fb..f5b5f99 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -257,7 +257,7 @@
// Returns a *HiddenAPIOutput containing the paths for the generated files. Returns nil if the
// module cannot contribute to hidden API processing, e.g. because it is a prebuilt module in a
// versioned sdk.
- produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput
+ produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput
// produceBootImageFiles will attempt to produce rules to create the boot image files at the paths
// predefined in the bootImageConfig.
@@ -716,8 +716,6 @@
// This is an exception to support end-to-end test for SdkExtensions, until such support exists.
if android.InList("test_framework-sdkextensions", possibleUpdatableModules) {
jars = jars.Append("com.android.sdkext", "test_framework-sdkextensions")
- } else if android.InList("AddNewActivity", possibleUpdatableModules) {
- jars = jars.Append("test_com.android.cts.frameworkresapkplits", "AddNewActivity")
} else if android.InList("test_framework-apexd", possibleUpdatableModules) {
jars = jars.Append("com.android.apex.test_package", "test_framework-apexd")
} else if global.ApexBootJars.Len() != 0 && !android.IsModuleInVersionedSdk(ctx.Module()) {
@@ -761,7 +759,7 @@
// Delegate the production of the hidden API all-flags.csv file to a module type specific method.
common := ctx.Module().(commonBootclasspathFragment)
- output := common.produceHiddenAPIOutput(ctx, contents, input)
+ output := common.produceHiddenAPIOutput(ctx, contents, fragments, input)
// If the source or prebuilts module does not provide a signature patterns file then generate one
// from the flags.
@@ -769,7 +767,7 @@
// their own.
if output.SignaturePatternsPath == nil {
output.SignaturePatternsPath = buildRuleSignaturePatternsFile(
- ctx, output.AllFlagsPath, []string{"*"}, nil, nil)
+ ctx, output.AllFlagsPath, []string{"*"}, nil, nil, "")
}
// Initialize a HiddenAPIInfo structure.
@@ -843,12 +841,12 @@
return b.testFragment
}
-// produceHiddenAPIOutput produces the hidden API all-flags.csv file (and supporting files)
-// for the fragment as well as encoding the flags in the boot dex jars.
-func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
+// generateHiddenApiFlagRules generates rules to generate hidden API flags and compute the signature
+// patterns file.
+func (b *BootclasspathFragmentModule) generateHiddenApiFlagRules(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput, bootDexInfoByModule bootDexInfoByModule, suffix string) HiddenAPIFlagOutput {
// Generate the rules to create the hidden API flags and update the supplied hiddenAPIInfo with the
// paths to the created files.
- output := hiddenAPIRulesForBootclasspathFragment(ctx, contents, input)
+ flagOutput := hiddenAPIFlagRulesForBootclasspathFragment(ctx, bootDexInfoByModule, contents, input, suffix)
// If the module specifies split_packages or package_prefixes then use those to generate the
// signature patterns.
@@ -856,8 +854,8 @@
packagePrefixes := input.PackagePrefixes
singlePackages := input.SinglePackages
if splitPackages != nil || packagePrefixes != nil || singlePackages != nil {
- output.SignaturePatternsPath = buildRuleSignaturePatternsFile(
- ctx, output.AllFlagsPath, splitPackages, packagePrefixes, singlePackages)
+ flagOutput.SignaturePatternsPath = buildRuleSignaturePatternsFile(
+ ctx, flagOutput.AllFlagsPath, splitPackages, packagePrefixes, singlePackages, suffix)
} else if !b.isTestFragment() {
ctx.ModuleErrorf(`Must specify at least one of the split_packages, package_prefixes and single_packages properties
If this is a new bootclasspath_fragment or you are unsure what to do add the
@@ -869,6 +867,68 @@
should specify here. If you are happy with its suggestions then you can add
the --fix option and it will fix them for you.`, b.BaseModuleName())
}
+ return flagOutput
+}
+
+// produceHiddenAPIOutput produces the hidden API all-flags.csv file (and supporting files)
+// for the fragment as well as encoding the flags in the boot dex jars.
+func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
+ // Gather information about the boot dex files for the boot libraries provided by this fragment.
+ bootDexInfoByModule := extractBootDexInfoFromModules(ctx, contents)
+
+ // Generate the flag file needed to encode into the dex files.
+ flagOutput := b.generateHiddenApiFlagRules(ctx, contents, input, bootDexInfoByModule, "")
+
+ // Encode those flags into the dex files of the contents of this fragment.
+ encodedBootDexFilesByModule := hiddenAPIEncodeRulesForBootclasspathFragment(ctx, bootDexInfoByModule, flagOutput.AllFlagsPath)
+
+ // Store that information for return for use by other rules.
+ output := &HiddenAPIOutput{
+ HiddenAPIFlagOutput: flagOutput,
+ EncodedBootDexFilesByModule: encodedBootDexFilesByModule,
+ }
+
+ // Get the ApiLevel associated with SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE, defaulting to current
+ // if not set.
+ config := ctx.Config()
+ targetApiLevel := android.ApiLevelOrPanic(ctx,
+ config.GetenvWithDefault("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE", "current"))
+
+ // Filter the contents list to remove any modules that do not support the target build release.
+ // The current build release supports all the modules.
+ contentsForSdkSnapshot := []android.Module{}
+ for _, module := range contents {
+ // If the module has a min_sdk_version that is higher than the target build release then it will
+ // not work on the target build release and so must not be included in the sdk snapshot.
+ minApiLevel := android.MinApiLevelForSdkSnapshot(ctx, module)
+ if minApiLevel.GreaterThan(targetApiLevel) {
+ continue
+ }
+
+ contentsForSdkSnapshot = append(contentsForSdkSnapshot, module)
+ }
+
+ var flagFilesByCategory FlagFilesByCategory
+ if len(contentsForSdkSnapshot) != len(contents) {
+ // The sdk snapshot has different contents to the runtime fragment so it is not possible to
+ // reuse the hidden API information generated for the fragment. So, recompute that information
+ // for the sdk snapshot.
+ filteredInput := b.createHiddenAPIFlagInput(ctx, contentsForSdkSnapshot, fragments)
+
+ // Gather information about the boot dex files for the boot libraries provided by this fragment.
+ filteredBootDexInfoByModule := extractBootDexInfoFromModules(ctx, contentsForSdkSnapshot)
+ flagOutput = b.generateHiddenApiFlagRules(ctx, contentsForSdkSnapshot, filteredInput, filteredBootDexInfoByModule, "-for-sdk-snapshot")
+ flagFilesByCategory = filteredInput.FlagFilesByCategory
+ } else {
+ // The sdk snapshot has the same contents as the runtime fragment so reuse that information.
+ flagFilesByCategory = input.FlagFilesByCategory
+ }
+
+ // Make the information available for the sdk snapshot.
+ ctx.SetProvider(HiddenAPIInfoForSdkProvider, HiddenAPIInfoForSdk{
+ FlagFilesByCategory: flagFilesByCategory,
+ HiddenAPIFlagOutput: flagOutput,
+ })
return output
}
@@ -1034,7 +1094,7 @@
// Get the hidden API information from the module.
mctx := ctx.SdkModuleContext()
- hiddenAPIInfo := mctx.OtherModuleProvider(module, HiddenAPIInfoProvider).(HiddenAPIInfo)
+ hiddenAPIInfo := mctx.OtherModuleProvider(module, HiddenAPIInfoForSdkProvider).(HiddenAPIInfoForSdk)
b.Flag_files_by_category = hiddenAPIInfo.FlagFilesByCategory
// Copy all the generated file paths.
@@ -1176,7 +1236,7 @@
}
// produceHiddenAPIOutput returns a path to the prebuilt all-flags.csv or nil if none is specified.
-func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
+func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
pathForOptionalSrc := func(src *string, defaultPath android.Path) android.Path {
if src == nil {
return defaultPath
diff --git a/java/droiddoc.go b/java/droiddoc.go
index fc95184..15585f1 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -684,7 +684,7 @@
outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
cmd := rule.Command().
- BuiltTool("soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
+ BuiltTool("soong_javac_wrapper").Tool(android.PathForSource(ctx, "prebuilts/jdk/jdk11/linux-x86/bin/javadoc")).
Flag(config.JavacVmFlags).
FlagWithArg("-encoding ", "UTF-8").
FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "javadoc.rsp"), srcs).
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index 7b67803..5474ae1 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -594,6 +594,23 @@
var HiddenAPIInfoProvider = blueprint.NewProvider(HiddenAPIInfo{})
+// HiddenAPIInfoForSdk contains information provided by the hidden API processing for use
+// by the sdk snapshot.
+//
+// That includes paths resolved from HiddenAPIFlagFileProperties and also generated by hidden API
+// processing.
+type HiddenAPIInfoForSdk struct {
+ // FlagFilesByCategory maps from the flag file category to the paths containing information for
+ // that category.
+ FlagFilesByCategory FlagFilesByCategory
+
+ // The output from the hidden API processing needs to be made available to other modules.
+ HiddenAPIFlagOutput
+}
+
+// Provides hidden API info for the sdk snapshot.
+var HiddenAPIInfoForSdkProvider = blueprint.NewProvider(HiddenAPIInfoForSdk{})
+
// ModuleStubDexJars contains the stub dex jars provided by a single module.
//
// It maps a *HiddenAPIScope to the path to stub dex jars appropriate for that scope. See
@@ -1024,8 +1041,11 @@
// patterns that will select a subset of the monolithic flags.
func buildRuleSignaturePatternsFile(
ctx android.ModuleContext, flagsPath android.Path,
- splitPackages []string, packagePrefixes []string, singlePackages []string) android.Path {
- patternsFile := android.PathForModuleOut(ctx, "modular-hiddenapi", "signature-patterns.csv")
+ splitPackages []string, packagePrefixes []string, singlePackages []string,
+ suffix string) android.Path {
+ hiddenApiSubDir := "modular-hiddenapi" + suffix
+
+ patternsFile := android.PathForModuleOut(ctx, hiddenApiSubDir, "signature-patterns.csv")
// Create a rule to validate the output from the following rule.
rule := android.NewRuleBuilder(pctx, ctx)
@@ -1042,7 +1062,7 @@
FlagForEachArg("--package-prefix ", packagePrefixes).
FlagForEachArg("--single-package ", singlePackages).
FlagWithOutput("--output ", patternsFile)
- rule.Build("hiddenAPISignaturePatterns", "hidden API signature patterns")
+ rule.Build("hiddenAPISignaturePatterns"+suffix, "hidden API signature patterns"+suffix)
return patternsFile
}
@@ -1116,8 +1136,8 @@
return validFile
}
-// hiddenAPIRulesForBootclasspathFragment will generate all the flags for a fragment of the
-// bootclasspath and then encode the flags into the boot dex files.
+// hiddenAPIFlagRulesForBootclasspathFragment will generate all the flags for a fragment of the
+// bootclasspath.
//
// It takes:
// * Map from android.SdkKind to stub dex jar paths defining the API for that sdk kind.
@@ -1130,31 +1150,27 @@
// * metadata.csv
// * index.csv
// * all-flags.csv
-// * encoded boot dex files
-func hiddenAPIRulesForBootclasspathFragment(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
- hiddenApiSubDir := "modular-hiddenapi"
-
- // Gather information about the boot dex files for the boot libraries provided by this fragment.
- bootDexInfoByModule := extractBootDexInfoFromModules(ctx, contents)
+func hiddenAPIFlagRulesForBootclasspathFragment(ctx android.ModuleContext, bootDexInfoByModule bootDexInfoByModule, contents []android.Module, input HiddenAPIFlagInput, suffix string) HiddenAPIFlagOutput {
+ hiddenApiSubDir := "modular-hiddenapi" + suffix
// Generate the stub-flags.csv.
stubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "stub-flags.csv")
- buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "modularHiddenAPIStubFlagsFile", "modular hiddenapi stub flags", stubFlagsCSV, bootDexInfoByModule.bootDexJars(), input, nil)
+ buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "modularHiddenAPIStubFlagsFile"+suffix, "modular hiddenapi stub flags", stubFlagsCSV, bootDexInfoByModule.bootDexJars(), input, nil)
// Extract the classes jars from the contents.
classesJars := extractClassesJarsFromModules(contents)
// Generate the set of flags from the annotations in the source code.
annotationFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "annotation-flags.csv")
- buildRuleToGenerateAnnotationFlags(ctx, "modular hiddenapi annotation flags", classesJars, stubFlagsCSV, annotationFlagsCSV)
+ buildRuleToGenerateAnnotationFlags(ctx, "modular hiddenapi annotation flags"+suffix, classesJars, stubFlagsCSV, annotationFlagsCSV)
// Generate the metadata from the annotations in the source code.
metadataCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "metadata.csv")
- buildRuleToGenerateMetadata(ctx, "modular hiddenapi metadata", classesJars, stubFlagsCSV, metadataCSV)
+ buildRuleToGenerateMetadata(ctx, "modular hiddenapi metadata"+suffix, classesJars, stubFlagsCSV, metadataCSV)
// Generate the index file from the CSV files in the classes jars.
indexCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "index.csv")
- buildRuleToGenerateIndex(ctx, "modular hiddenapi index", classesJars, indexCSV)
+ buildRuleToGenerateIndex(ctx, "modular hiddenapi index"+suffix, classesJars, indexCSV)
// Removed APIs need to be marked and in order to do that the hiddenAPIInfo needs to specify files
// containing dex signatures of all the removed APIs. In the monolithic files that is done by
@@ -1162,15 +1178,44 @@
// signatures, see the combined-removed-dex module. This does that automatically by using the
// *removed.txt files retrieved from the java_sdk_library modules that are specified in the
// stub_libs and contents properties of a bootclasspath_fragment.
- removedDexSignatures := buildRuleToGenerateRemovedDexSignatures(ctx, input.RemovedTxtFiles)
+ removedDexSignatures := buildRuleToGenerateRemovedDexSignatures(ctx, suffix, input.RemovedTxtFiles)
// Generate the all-flags.csv which are the flags that will, in future, be encoded into the dex
// files.
allFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "all-flags.csv")
- buildRuleToGenerateHiddenApiFlags(ctx, "modularHiddenApiAllFlags", "modular hiddenapi all flags", allFlagsCSV, stubFlagsCSV, android.Paths{annotationFlagsCSV}, input.FlagFilesByCategory, nil, removedDexSignatures)
+ buildRuleToGenerateHiddenApiFlags(ctx, "modularHiddenApiAllFlags"+suffix, "modular hiddenapi all flags"+suffix, allFlagsCSV, stubFlagsCSV, android.Paths{annotationFlagsCSV}, input.FlagFilesByCategory, nil, removedDexSignatures)
+ // Generate the filtered-stub-flags.csv file which contains the filtered stub flags that will be
+ // compared against the monolithic stub flags.
+ filteredStubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "filtered-stub-flags.csv")
+ buildRuleRemoveSignaturesWithImplementationFlags(ctx, "modularHiddenApiFilteredStubFlags"+suffix,
+ "modular hiddenapi filtered stub flags"+suffix, stubFlagsCSV, filteredStubFlagsCSV,
+ HIDDENAPI_STUB_FLAGS_IMPL_FLAGS)
+
+ // Generate the filtered-flags.csv file which contains the filtered flags that will be compared
+ // against the monolithic flags.
+ filteredFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "filtered-flags.csv")
+ buildRuleRemoveSignaturesWithImplementationFlags(ctx, "modularHiddenApiFilteredFlags"+suffix,
+ "modular hiddenapi filtered flags"+suffix, allFlagsCSV, filteredFlagsCSV,
+ HIDDENAPI_FLAGS_CSV_IMPL_FLAGS)
+
+ // Store the paths in the info for use by other modules and sdk snapshot generation.
+ return HiddenAPIFlagOutput{
+ AnnotationFlagsPath: annotationFlagsCSV,
+ MetadataPath: metadataCSV,
+ IndexPath: indexCSV,
+ StubFlagsPath: stubFlagsCSV,
+ AllFlagsPath: allFlagsCSV,
+ FilteredStubFlagsPath: filteredStubFlagsCSV,
+ FilteredFlagsPath: filteredFlagsCSV,
+ }
+}
+
+// hiddenAPIEncodeRulesForBootclasspathFragment generates rules to encode hidden API flags into the
+// dex jars in bootDexInfoByModule.
+func hiddenAPIEncodeRulesForBootclasspathFragment(ctx android.ModuleContext, bootDexInfoByModule bootDexInfoByModule, allFlagsCSV android.Path) bootDexJarByModule {
// Encode the flags into the boot dex files.
- encodedBootDexJarsByModule := map[string]android.Path{}
+ encodedBootDexJarsByModule := bootDexJarByModule{}
outputDir := android.PathForModuleOut(ctx, "hiddenapi-modular/encoded").OutputPath
for _, name := range android.SortedStringKeys(bootDexInfoByModule) {
bootDexInfo := bootDexInfoByModule[name]
@@ -1178,43 +1223,15 @@
encodedDex := hiddenAPIEncodeDex(ctx, unencodedDex, allFlagsCSV, bootDexInfo.uncompressDex, bootDexInfo.minSdkVersion, outputDir)
encodedBootDexJarsByModule[name] = encodedDex
}
-
- // Generate the filtered-stub-flags.csv file which contains the filtered stub flags that will be
- // compared against the monolithic stub flags.
- filteredStubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "filtered-stub-flags.csv")
- buildRuleRemoveSignaturesWithImplementationFlags(ctx, "modularHiddenApiFilteredStubFlags",
- "modular hiddenapi filtered stub flags", stubFlagsCSV, filteredStubFlagsCSV,
- HIDDENAPI_STUB_FLAGS_IMPL_FLAGS)
-
- // Generate the filtered-flags.csv file which contains the filtered flags that will be compared
- // against the monolithic flags.
- filteredFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "filtered-flags.csv")
- buildRuleRemoveSignaturesWithImplementationFlags(ctx, "modularHiddenApiFilteredFlags",
- "modular hiddenapi filtered flags", allFlagsCSV, filteredFlagsCSV,
- HIDDENAPI_FLAGS_CSV_IMPL_FLAGS)
-
- // Store the paths in the info for use by other modules and sdk snapshot generation.
- output := HiddenAPIOutput{
- HiddenAPIFlagOutput: HiddenAPIFlagOutput{
- AnnotationFlagsPath: annotationFlagsCSV,
- MetadataPath: metadataCSV,
- IndexPath: indexCSV,
- StubFlagsPath: stubFlagsCSV,
- AllFlagsPath: allFlagsCSV,
- FilteredStubFlagsPath: filteredStubFlagsCSV,
- FilteredFlagsPath: filteredFlagsCSV,
- },
- EncodedBootDexFilesByModule: encodedBootDexJarsByModule,
- }
- return &output
+ return encodedBootDexJarsByModule
}
-func buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, removedTxtFiles android.Paths) android.OptionalPath {
+func buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, suffix string, removedTxtFiles android.Paths) android.OptionalPath {
if len(removedTxtFiles) == 0 {
return android.OptionalPath{}
}
- output := android.PathForModuleOut(ctx, "modular-hiddenapi/removed-dex-signatures.txt")
+ output := android.PathForModuleOut(ctx, "module-hiddenapi"+suffix, "removed-dex-signatures.txt")
rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().
@@ -1222,7 +1239,7 @@
Flag("--no-banner").
Inputs(removedTxtFiles).
FlagWithOutput("--dex-api ", output)
- rule.Build("modular-hiddenapi-removed-dex-signatures", "modular hiddenapi removed dex signatures")
+ rule.Build("modular-hiddenapi-removed-dex-signatures"+suffix, "modular hiddenapi removed dex signatures"+suffix)
return android.OptionalPathForPath(output)
}
diff --git a/java/rro.go b/java/rro.go
index c12e748..3a92b0c 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -146,7 +146,7 @@
// Sign the built package
_, _, certificates := collectAppDeps(ctx, r, false, false)
- certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx)
+ r.certificate, certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx)
signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk")
var lineageFile android.Path
if lineage := String(r.properties.Lineage); lineage != "" {
@@ -156,7 +156,6 @@
rotationMinSdkVersion := String(r.properties.RotationMinSdkVersion)
SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil, lineageFile, rotationMinSdkVersion)
- r.certificate = certificates[0]
r.outputFile = signed
partition := rroPartition(ctx)
diff --git a/licenses/Android.bp b/licenses/Android.bp
index 133f7f7..75154f9 100644
--- a/licenses/Android.bp
+++ b/licenses/Android.bp
@@ -762,7 +762,7 @@
license_kind {
name: "SPDX-license-identifier-GPL-2.0-with-classpath-exception",
- conditions: ["restricted"],
+ conditions: ["permissive"],
url: "https://spdx.org/licenses/GPL-2.0-with-classpath-exception.html",
}
@@ -810,7 +810,7 @@
license_kind {
name: "SPDX-license-identifier-GPL-with-classpath-exception",
- conditions: ["restricted"],
+ conditions: ["permissive"],
}
license_kind {
diff --git a/linkerconfig/proto/Android.bp b/linkerconfig/proto/Android.bp
index 3b1e4ab..754e7bf 100644
--- a/linkerconfig/proto/Android.bp
+++ b/linkerconfig/proto/Android.bp
@@ -19,14 +19,6 @@
python_library_host {
name: "linker_config_proto",
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- },
- },
srcs: [
"linker_config.proto",
],
diff --git a/python/python.go b/python/python.go
index 8364169..daf7c14 100644
--- a/python/python.go
+++ b/python/python.go
@@ -120,6 +120,15 @@
// whether the binary is required to be built with embedded launcher for this actual_version.
// this is set by the python version mutator based on version-specific properties
Embedded_launcher *bool `blueprint:"mutated"`
+
+ Proto struct {
+ // Whether generated python protos should include the pkg_path in
+ // their import statements. This is a temporary flag to help transition to
+ // the new behavior where this is always true. It will be removed after all
+ // usages of protos with pkg_path have been updated. The default is currently
+ // false.
+ Respect_pkg_path *bool
+ }
}
type baseAttributes struct {
@@ -672,8 +681,26 @@
protoFlags := android.GetProtoFlags(ctx, &p.protoProperties)
protoFlags.OutTypeFlag = "--python_out"
+ // TODO(b/247578564): Change the default to true, and then eventually remove respect_pkg_path
+ protosRespectPkgPath := proptools.BoolDefault(p.properties.Proto.Respect_pkg_path, false)
+ pkgPathForProtos := pkgPath
+ if pkgPathForProtos != "" && protosRespectPkgPath {
+ pkgPathStagingDir := android.PathForModuleGen(ctx, "protos_staged_for_pkg_path")
+ rule := android.NewRuleBuilder(pctx, ctx)
+ var stagedProtoSrcs android.Paths
+ for _, srcFile := range protoSrcs {
+ stagedProtoSrc := pkgPathStagingDir.Join(ctx, pkgPath, srcFile.Rel())
+ rule.Command().Text("mkdir -p").Flag(filepath.Base(stagedProtoSrc.String()))
+ rule.Command().Text("cp -f").Input(srcFile).Output(stagedProtoSrc)
+ stagedProtoSrcs = append(stagedProtoSrcs, stagedProtoSrc)
+ }
+ rule.Build("stage_protos_for_pkg_path", "Stage protos for pkg_path")
+ protoSrcs = stagedProtoSrcs
+ pkgPathForProtos = ""
+ }
+
for _, srcFile := range protoSrcs {
- zip := genProto(ctx, srcFile, protoFlags, pkgPath)
+ zip := genProto(ctx, srcFile, protoFlags, pkgPathForProtos)
zips = append(zips, zip)
}
}
diff --git a/python/tests/proto_pkg_path/Android.bp b/python/tests/proto_pkg_path/Android.bp
new file mode 100644
index 0000000..17afde2
--- /dev/null
+++ b/python/tests/proto_pkg_path/Android.bp
@@ -0,0 +1,13 @@
+python_test_host {
+ name: "py_proto_pkg_path_test",
+ main: "main.py",
+ srcs: [
+ "main.py",
+ "proto/*.proto",
+ ],
+ pkg_path: "mylib/subpackage",
+ proto: {
+ canonical_path_from_root: false,
+ respect_pkg_path: true,
+ },
+}
diff --git a/python/tests/proto_pkg_path/main.py b/python/tests/proto_pkg_path/main.py
new file mode 100644
index 0000000..c4acdde
--- /dev/null
+++ b/python/tests/proto_pkg_path/main.py
@@ -0,0 +1,18 @@
+import sys
+
+import unittest
+import mylib.subpackage.proto.test_pb2 as test_pb2
+import mylib.subpackage.proto.common_pb2 as common_pb2
+
+print(sys.path)
+
+class TestProtoWithPkgPath(unittest.TestCase):
+
+ def test_main(self):
+ x = test_pb2.MyMessage(name="foo",
+ common = common_pb2.MyCommonMessage(common="common"))
+ self.assertEqual(x.name, "foo")
+ self.assertEqual(x.common.common, "common")
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/python/tests/proto_pkg_path/proto/common.proto b/python/tests/proto_pkg_path/proto/common.proto
new file mode 100644
index 0000000..b24b8ea
--- /dev/null
+++ b/python/tests/proto_pkg_path/proto/common.proto
@@ -0,0 +1,5 @@
+syntax = "proto3";
+
+message MyCommonMessage {
+ string common = 1;
+}
diff --git a/python/tests/proto_pkg_path/proto/test.proto b/python/tests/proto_pkg_path/proto/test.proto
new file mode 100644
index 0000000..55f3b17
--- /dev/null
+++ b/python/tests/proto_pkg_path/proto/test.proto
@@ -0,0 +1,8 @@
+syntax = "proto3";
+
+import "mylib/subpackage/proto/common.proto";
+
+message MyMessage {
+ string name = 1;
+ MyCommonMessage common = 2;
+}
diff --git a/scripts/Android.bp b/scripts/Android.bp
index b5b588b..5dd45cd 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -199,6 +199,17 @@
],
}
+python_binary_host {
+ name: "build-apex-bundle",
+ main: "build-apex-bundle.py",
+ srcs: [
+ "build-apex-bundle.py",
+ ],
+ required: [
+ "bundletool",
+ ],
+}
+
sh_binary_host {
name: "list_image",
src: "list_image.sh",
diff --git a/scripts/build-apex-bundle.py b/scripts/build-apex-bundle.py
new file mode 100644
index 0000000..dcdd9ef
--- /dev/null
+++ b/scripts/build-apex-bundle.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2022 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.
+#
+"""A tool to create an APEX bundle out of Soong-built base.zip"""
+
+from __future__ import print_function
+
+import argparse
+import sys
+import tempfile
+import zipfile
+import os
+import json
+import subprocess
+
+
+def parse_args():
+ """Parse commandline arguments."""
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ '--overwrite',
+ action='store_true',
+ help='If set, any previous existing output will be overwritten')
+ parser.add_argument('--output', help='specify the output .aab file')
+ parser.add_argument(
+ 'input', help='specify the input <apex name>-base.zip file')
+ return parser.parse_args()
+
+
+def build_bundle(input, output, overwrite):
+ base_zip = zipfile.ZipFile(input)
+
+ tmpdir = tempfile.mkdtemp()
+ tmp_base_zip = os.path.join(tmpdir, 'base.zip')
+ tmp_bundle_config = os.path.join(tmpdir, 'bundle_config.json')
+
+ bundle_config = None
+ abi = []
+
+ # This block performs three tasks
+ # - extract/load bundle_config.json from input => bundle_config
+ # - get ABI from input => abi
+ # - discard bundle_config.json from input => tmp/base.zip
+ with zipfile.ZipFile(tmp_base_zip, 'a') as out:
+ for info in base_zip.infolist():
+
+ # discard bundle_config.json
+ if info.filename == 'bundle_config.json':
+ bundle_config = json.load(base_zip.open(info.filename))
+ continue
+
+ # get ABI from apex/{abi}.img
+ dir, basename = os.path.split(info.filename)
+ name, ext = os.path.splitext(basename)
+ if dir == 'apex' and ext == '.img':
+ abi.append(name)
+
+ # copy entries to tmp/base.zip
+ out.writestr(info, base_zip.open(info.filename).read())
+
+ base_zip.close()
+
+ if not bundle_config:
+ raise ValueError(f'bundle_config.json not found in {input}')
+ if len(abi) != 1:
+ raise ValueError(f'{input} should have only a single apex/*.img file')
+
+ # add ABI to tmp/bundle_config.json
+ apex_config = bundle_config['apex_config']
+ if 'supported_abi_set' not in apex_config:
+ apex_config['supported_abi_set'] = []
+ supported_abi_set = apex_config['supported_abi_set']
+ supported_abi_set.append({'abi': abi})
+
+ with open(tmp_bundle_config, 'w') as out:
+ json.dump(bundle_config, out)
+
+ # invoke bundletool
+ cmd = [
+ 'bundletool', 'build-bundle', '--config', tmp_bundle_config, '--modules',
+ tmp_base_zip, '--output', output
+ ]
+ if overwrite:
+ cmd.append('--overwrite')
+ subprocess.check_call(cmd)
+
+
+def main():
+ """Program entry point."""
+ try:
+ args = parse_args()
+ build_bundle(args.input, args.output, args.overwrite)
+
+ # pylint: disable=broad-except
+ except Exception as err:
+ print('error: ' + str(err), file=sys.stderr)
+ sys.exit(-1)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/hiddenapi/Android.bp b/scripts/hiddenapi/Android.bp
index 07878f9..1e89efe 100644
--- a/scripts/hiddenapi/Android.bp
+++ b/scripts/hiddenapi/Android.bp
@@ -18,29 +18,31 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
+python_defaults {
+ name: "hiddenapi_defaults",
+ version: {
+ py3: {
+ embedded_launcher: true,
+ },
+ },
+}
+
python_binary_host {
name: "analyze_bcpf",
main: "analyze_bcpf.py",
+ defaults: ["hiddenapi_defaults"],
srcs: ["analyze_bcpf.py"],
// Make sure that the bpmodify tool is built.
data: [":bpmodify"],
libs: [
"signature_trie",
],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- embedded_launcher: true,
- },
- },
}
python_test_host {
name: "analyze_bcpf_test",
main: "analyze_bcpf_test.py",
+ defaults: ["hiddenapi_defaults"],
srcs: [
"analyze_bcpf.py",
"analyze_bcpf_test.py",
@@ -50,15 +52,6 @@
libs: [
"signature_trie",
],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- embedded_launcher: true,
- },
- },
test_options: {
unit_test: true,
},
@@ -67,49 +60,25 @@
python_binary_host {
name: "merge_csv",
main: "merge_csv.py",
+ defaults: ["hiddenapi_defaults"],
srcs: ["merge_csv.py"],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- embedded_launcher: true,
- },
- },
}
python_binary_host {
name: "generate_hiddenapi_lists",
main: "generate_hiddenapi_lists.py",
+ defaults: ["hiddenapi_defaults"],
srcs: ["generate_hiddenapi_lists.py"],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- embedded_launcher: true,
- },
- },
}
python_test_host {
name: "generate_hiddenapi_lists_test",
main: "generate_hiddenapi_lists_test.py",
+ defaults: ["hiddenapi_defaults"],
srcs: [
"generate_hiddenapi_lists.py",
"generate_hiddenapi_lists_test.py",
],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- embedded_launcher: true,
- },
- },
test_options: {
unit_test: true,
},
@@ -123,17 +92,9 @@
python_test_host {
name: "signature_trie_test",
main: "signature_trie_test.py",
+ defaults: ["hiddenapi_defaults"],
srcs: ["signature_trie_test.py"],
libs: ["signature_trie"],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- embedded_launcher: true,
- },
- },
test_options: {
unit_test: true,
},
@@ -142,24 +103,17 @@
python_binary_host {
name: "verify_overlaps",
main: "verify_overlaps.py",
+ defaults: ["hiddenapi_defaults"],
srcs: ["verify_overlaps.py"],
libs: [
"signature_trie",
],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- embedded_launcher: true,
- },
- },
}
python_test_host {
name: "verify_overlaps_test",
main: "verify_overlaps_test.py",
+ defaults: ["hiddenapi_defaults"],
srcs: [
"verify_overlaps.py",
"verify_overlaps_test.py",
@@ -167,15 +121,6 @@
libs: [
"signature_trie",
],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- embedded_launcher: true,
- },
- },
test_options: {
unit_test: true,
},
@@ -184,34 +129,18 @@
python_binary_host {
name: "signature_patterns",
main: "signature_patterns.py",
+ defaults: ["hiddenapi_defaults"],
srcs: ["signature_patterns.py"],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- embedded_launcher: true,
- },
- },
}
python_test_host {
name: "signature_patterns_test",
main: "signature_patterns_test.py",
+ defaults: ["hiddenapi_defaults"],
srcs: [
"signature_patterns.py",
"signature_patterns_test.py",
],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- embedded_launcher: true,
- },
- },
test_options: {
unit_test: true,
},
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index c93055a..4be0ace 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -895,3 +895,222 @@
snapshotTestPreparer(checkSnapshotPreferredWithSource, preparerForSnapshot),
)
}
+
+func testSnapshotWithBootClasspathFragment_MinSdkVersion(t *testing.T, targetBuildRelease string,
+ expectedSdkSnapshot string,
+ expectedCopyRules string,
+ expectedStubFlagsInputs []string,
+ suffix string) {
+
+ result := android.GroupFixturePreparers(
+ prepareForSdkTestWithJava,
+ java.PrepareForTestWithJavaDefaultModules,
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureWithLastReleaseApis("mysdklibrary", "mynewsdklibrary"),
+ java.FixtureConfigureApexBootJars("myapex:mysdklibrary", "myapex:mynewsdklibrary"),
+ prepareForSdkTestWithApex,
+
+ // Add a platform_bootclasspath that depends on the fragment.
+ fixtureAddPlatformBootclasspathForBootclasspathFragment("myapex", "mybootclasspathfragment"),
+
+ android.FixtureMergeEnv(map[string]string{
+ "SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": targetBuildRelease,
+ }),
+
+ android.FixtureWithRootAndroidBp(`
+ sdk {
+ name: "mysdk",
+ apexes: ["myapex"],
+ }
+
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ min_sdk_version: "S",
+ bootclasspath_fragments: ["mybootclasspathfragment"],
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ apex_available: ["myapex"],
+ contents: [
+ "mysdklibrary",
+ "mynewsdklibrary",
+ ],
+
+ hidden_api: {
+ split_packages: [],
+ },
+ }
+
+ java_sdk_library {
+ name: "mysdklibrary",
+ apex_available: ["myapex"],
+ srcs: ["Test.java"],
+ shared_library: false,
+ public: {enabled: true},
+ min_sdk_version: "S",
+ }
+
+ java_sdk_library {
+ name: "mynewsdklibrary",
+ apex_available: ["myapex"],
+ srcs: ["Test.java"],
+ compile_dex: true,
+ public: {enabled: true},
+ min_sdk_version: "Tiramisu",
+ permitted_packages: ["mynewsdklibrary"],
+ }
+ `),
+ ).RunTest(t)
+
+ bcpf := result.ModuleForTests("mybootclasspathfragment", "android_common")
+ rule := bcpf.Output("out/soong/.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi" + suffix + "/stub-flags.csv")
+ android.AssertPathsRelativeToTopEquals(t, "stub flags inputs", expectedStubFlagsInputs, rule.Implicits)
+
+ CheckSnapshot(t, result, "mysdk", "",
+ checkAndroidBpContents(expectedSdkSnapshot),
+ checkAllCopyRules(expectedCopyRules),
+ )
+}
+
+func TestSnapshotWithBootClasspathFragment_MinSdkVersion(t *testing.T) {
+ t.Run("target S build", func(t *testing.T) {
+ expectedSnapshot := `
+// This is auto-generated. DO NOT EDIT.
+
+prebuilt_bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["myapex"],
+ contents: ["mysdklibrary"],
+ hidden_api: {
+ annotation_flags: "hiddenapi/annotation-flags.csv",
+ metadata: "hiddenapi/metadata.csv",
+ index: "hiddenapi/index.csv",
+ stub_flags: "hiddenapi/stub-flags.csv",
+ all_flags: "hiddenapi/all-flags.csv",
+ },
+}
+
+java_sdk_library_import {
+ name: "mysdklibrary",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["myapex"],
+ shared_library: false,
+ public: {
+ jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
+ stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
+ current_api: "sdk_library/public/mysdklibrary.txt",
+ removed_api: "sdk_library/public/mysdklibrary-removed.txt",
+ sdk_version: "current",
+ },
+}
+`
+ expectedCopyRules := `
+.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi-for-sdk-snapshot/annotation-flags.csv -> hiddenapi/annotation-flags.csv
+.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi-for-sdk-snapshot/metadata.csv -> hiddenapi/metadata.csv
+.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi-for-sdk-snapshot/index.csv -> hiddenapi/index.csv
+.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi-for-sdk-snapshot/stub-flags.csv -> hiddenapi/stub-flags.csv
+.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi-for-sdk-snapshot/all-flags.csv -> hiddenapi/all-flags.csv
+.intermediates/mysdklibrary.stubs/android_common/javac/mysdklibrary.stubs.jar -> sdk_library/public/mysdklibrary-stubs.jar
+.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt
+.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt
+`
+
+ // On S the stub flags should only be generated from mysdklibrary as mynewsdklibrary is not part
+ // of the snapshot.
+ expectedStubFlagsInputs := []string{
+ "out/soong/.intermediates/mysdklibrary.stubs/android_common/dex/mysdklibrary.stubs.jar",
+ "out/soong/.intermediates/mysdklibrary/android_common/aligned/mysdklibrary.jar",
+ }
+
+ testSnapshotWithBootClasspathFragment_MinSdkVersion(t, "S",
+ expectedSnapshot, expectedCopyRules, expectedStubFlagsInputs, "-for-sdk-snapshot")
+ })
+
+ t.Run("target-Tiramisu-build", func(t *testing.T) {
+ expectedSnapshot := `
+// This is auto-generated. DO NOT EDIT.
+
+prebuilt_bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["myapex"],
+ contents: [
+ "mysdklibrary",
+ "mynewsdklibrary",
+ ],
+ hidden_api: {
+ annotation_flags: "hiddenapi/annotation-flags.csv",
+ metadata: "hiddenapi/metadata.csv",
+ index: "hiddenapi/index.csv",
+ signature_patterns: "hiddenapi/signature-patterns.csv",
+ filtered_stub_flags: "hiddenapi/filtered-stub-flags.csv",
+ filtered_flags: "hiddenapi/filtered-flags.csv",
+ },
+}
+
+java_sdk_library_import {
+ name: "mysdklibrary",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["myapex"],
+ shared_library: false,
+ public: {
+ jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
+ stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
+ current_api: "sdk_library/public/mysdklibrary.txt",
+ removed_api: "sdk_library/public/mysdklibrary-removed.txt",
+ sdk_version: "current",
+ },
+}
+
+java_sdk_library_import {
+ name: "mynewsdklibrary",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["myapex"],
+ shared_library: true,
+ compile_dex: true,
+ permitted_packages: ["mynewsdklibrary"],
+ public: {
+ jars: ["sdk_library/public/mynewsdklibrary-stubs.jar"],
+ stub_srcs: ["sdk_library/public/mynewsdklibrary_stub_sources"],
+ current_api: "sdk_library/public/mynewsdklibrary.txt",
+ removed_api: "sdk_library/public/mynewsdklibrary-removed.txt",
+ sdk_version: "current",
+ },
+}
+`
+ expectedCopyRules := `
+.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv
+.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv
+.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/index.csv -> hiddenapi/index.csv
+.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv
+.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
+.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
+.intermediates/mysdklibrary.stubs/android_common/javac/mysdklibrary.stubs.jar -> sdk_library/public/mysdklibrary-stubs.jar
+.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt
+.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt
+.intermediates/mynewsdklibrary.stubs/android_common/javac/mynewsdklibrary.stubs.jar -> sdk_library/public/mynewsdklibrary-stubs.jar
+.intermediates/mynewsdklibrary.stubs.source/android_common/metalava/mynewsdklibrary.stubs.source_api.txt -> sdk_library/public/mynewsdklibrary.txt
+.intermediates/mynewsdklibrary.stubs.source/android_common/metalava/mynewsdklibrary.stubs.source_removed.txt -> sdk_library/public/mynewsdklibrary-removed.txt
+`
+
+ // On tiramisu the stub flags should be generated from both mynewsdklibrary and mysdklibrary as
+ // they are both part of the snapshot.
+ expectedStubFlagsInputs := []string{
+ "out/soong/.intermediates/mynewsdklibrary.stubs/android_common/dex/mynewsdklibrary.stubs.jar",
+ "out/soong/.intermediates/mynewsdklibrary/android_common/aligned/mynewsdklibrary.jar",
+ "out/soong/.intermediates/mysdklibrary.stubs/android_common/dex/mysdklibrary.stubs.jar",
+ "out/soong/.intermediates/mysdklibrary/android_common/aligned/mysdklibrary.jar",
+ }
+
+ testSnapshotWithBootClasspathFragment_MinSdkVersion(t, "Tiramisu",
+ expectedSnapshot, expectedCopyRules, expectedStubFlagsInputs, "")
+ })
+}
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 7ab5285..d598834 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -1004,7 +1004,7 @@
java_sdk_library {
name: "myjavalib",
srcs: ["Test.java"],
- sdk_version: "current",
+ sdk_version: "S",
shared_library: false,
annotations_enabled: true,
public: {
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index 1ec12c3..8b8e1d7 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -482,6 +482,7 @@
name: "mysdklibrary",
srcs: ["Test.java"],
compile_dex: true,
+ sdk_version: "S",
public: {enabled: true},
permitted_packages: ["mysdklibrary"],
}
diff --git a/sdk/update.go b/sdk/update.go
index 5c9376b..81f3672 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -211,11 +211,14 @@
container = parent.(android.SdkAware)
}
+ minApiLevel := android.MinApiLevelForSdkSnapshot(ctx, child)
+
export := memberTag.ExportMember()
s.memberVariantDeps = append(s.memberVariantDeps, sdkMemberVariantDep{
sdkVariant: s,
memberType: memberType,
variant: child.(android.SdkAware),
+ minApiLevel: minApiLevel,
container: container,
export: export,
exportedComponentsInfo: exportedComponentsInfo,
@@ -332,10 +335,28 @@
// <arch>/lib/
// libFoo.so : a stub library
+func (s sdk) targetBuildRelease(ctx android.ModuleContext) *buildRelease {
+ config := ctx.Config()
+ targetBuildReleaseEnv := config.GetenvWithDefault("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE", buildReleaseCurrent.name)
+ targetBuildRelease, err := nameToRelease(targetBuildReleaseEnv)
+ if err != nil {
+ ctx.ModuleErrorf("invalid SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE: %s", err)
+ targetBuildRelease = buildReleaseCurrent
+ }
+
+ return targetBuildRelease
+}
+
// buildSnapshot is the main function in this source file. It creates rules to copy
// the contents (header files, stub libraries, etc) into the zip file.
func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) {
+ targetBuildRelease := s.targetBuildRelease(ctx)
+ targetApiLevel, err := android.ApiLevelFromUser(ctx, targetBuildRelease.name)
+ if err != nil {
+ targetApiLevel = android.FutureApiLevel
+ }
+
// Aggregate all the sdkMemberVariantDep instances from all the sdk variants.
hasLicenses := false
var memberVariantDeps []sdkMemberVariantDep
@@ -346,12 +367,18 @@
// Filter out any sdkMemberVariantDep that is a component of another.
memberVariantDeps = filterOutComponents(ctx, memberVariantDeps)
- // Record the names of all the members, both explicitly specified and implicitly
- // included.
+ // Record the names of all the members, both explicitly specified and implicitly included. Also,
+ // record the names of any members that should be excluded from this snapshot.
allMembersByName := make(map[string]struct{})
exportedMembersByName := make(map[string]struct{})
+ excludedMembersByName := make(map[string]struct{})
- addMember := func(name string, export bool) {
+ addMember := func(name string, export bool, exclude bool) {
+ if exclude {
+ excludedMembersByName[name] = struct{}{}
+ return
+ }
+
allMembersByName[name] = struct{}{}
if export {
exportedMembersByName[name] = struct{}{}
@@ -362,11 +389,15 @@
name := memberVariantDep.variant.Name()
export := memberVariantDep.export
- addMember(name, export)
+ // If the minApiLevel of the member is greater than the target API level then exclude it from
+ // this snapshot.
+ exclude := memberVariantDep.minApiLevel.GreaterThan(targetApiLevel)
+
+ addMember(name, export, exclude)
// Add any components provided by the module.
for _, component := range memberVariantDep.exportedComponentsInfo.Components {
- addMember(component, export)
+ addMember(component, export, exclude)
}
if memberVariantDep.memberType == android.LicenseModuleSdkMemberType {
@@ -382,18 +413,9 @@
modules: make(map[string]*bpModule),
}
- config := ctx.Config()
-
// Always add -current to the end
snapshotFileSuffix := "-current"
- targetBuildReleaseEnv := config.GetenvWithDefault("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE", buildReleaseCurrent.name)
- targetBuildRelease, err := nameToRelease(targetBuildReleaseEnv)
- if err != nil {
- ctx.ModuleErrorf("invalid SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE: %s", err)
- targetBuildRelease = buildReleaseCurrent
- }
-
builder := &snapshotBuilder{
ctx: ctx,
sdk: s,
@@ -404,6 +426,7 @@
prebuiltModules: make(map[string]*bpModule),
allMembersByName: allMembersByName,
exportedMembersByName: exportedMembersByName,
+ excludedMembersByName: excludedMembersByName,
targetBuildRelease: targetBuildRelease,
}
s.builderForTests = builder
@@ -437,6 +460,10 @@
}
name := member.name
+ if _, ok := excludedMembersByName[name]; ok {
+ continue
+ }
+
requiredTraits := traits[name]
if requiredTraits == nil {
requiredTraits = android.EmptySdkMemberTraitSet()
@@ -1034,6 +1061,9 @@
// The set of exported members by name.
exportedMembersByName map[string]struct{}
+ // The set of members which have been excluded from this snapshot; by name.
+ excludedMembersByName map[string]struct{}
+
// The target build release for which the snapshot is to be generated.
targetBuildRelease *buildRelease
@@ -1218,6 +1248,9 @@
func (s *snapshotBuilder) snapshotSdkMemberNames(members []string, required bool) []string {
var references []string = nil
for _, m := range members {
+ if _, ok := s.excludedMembersByName[m]; ok {
+ continue
+ }
references = append(references, s.snapshotSdkMemberName(m, required))
}
return references
@@ -1260,6 +1293,9 @@
// The names of additional component modules provided by the variant.
exportedComponentsInfo android.ExportedComponentsInfo
+
+ // The minimum API level on which this module is supported.
+ minApiLevel android.ApiLevel
}
var _ android.SdkMember = (*sdkMember)(nil)