Merge "Define __ANDROID_VENDOR_API__ for product variants" into main
diff --git a/Android.bp b/Android.bp
index 535246e..ab8e4a0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -3,6 +3,7 @@
default_visibility: [
"//build/soong:__subpackages__",
],
+ default_team: "trendy_team_build",
}
subdirs = [
@@ -116,6 +117,11 @@
visibility: ["//visibility:public"],
}
+art_boot_images {
+ name: "art_boot_images",
+ visibility: ["//art:__subpackages__"],
+}
+
// Pseudo-test that's run on checkbuilds to ensure that get_clang_version can
// parse cc/config/global.go.
genrule {
@@ -136,9 +142,13 @@
visibility: ["//visibility:public"],
}
+// TODO(b/365670526): remove the cuttlefish visibility once it is fully removed
product_config {
name: "product_config",
- visibility: ["//device/google/cuttlefish/system_image"],
+ visibility: [
+ "//build/make/target/product/generic",
+ "//device/google/cuttlefish/system_image",
+ ],
}
build_prop {
@@ -147,6 +157,7 @@
product_config: ":product_config",
// Currently, only microdroid and cf system image can refer to system-build.prop
visibility: [
+ "//build/make/target/product/generic",
"//device/google/cuttlefish/system_image",
"//packages/modules/Virtualization/build/microdroid",
],
diff --git a/aconfig/codegen/cc_aconfig_library.go b/aconfig/codegen/cc_aconfig_library.go
index b5cf687..8c4bfe6 100644
--- a/aconfig/codegen/cc_aconfig_library.go
+++ b/aconfig/codegen/cc_aconfig_library.go
@@ -63,7 +63,7 @@
callbacks := &CcAconfigLibraryCallbacks{
properties: &CcAconfigLibraryProperties{},
}
- return cc.GeneratedCcLibraryModuleFactory("cc_aconfig_library", callbacks)
+ return cc.GeneratedCcLibraryModuleFactory(callbacks)
}
func (this *CcAconfigLibraryCallbacks) GeneratorInit(ctx cc.BaseModuleContext) {
diff --git a/aconfig/codegen/init.go b/aconfig/codegen/init.go
index 98d288f..ed0b3ed 100644
--- a/aconfig/codegen/init.go
+++ b/aconfig/codegen/init.go
@@ -32,6 +32,7 @@
` --mode ${mode}` +
` --cache ${in}` +
` --out ${out}.tmp` +
+ ` --allow-instrumentation ${debug}` +
` && $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` +
` && rm -rf ${out}.tmp`,
CommandDeps: []string{
@@ -39,7 +40,7 @@
"$soong_zip",
},
Restat: true,
- }, "mode")
+ }, "mode", "debug")
// For cc_aconfig_library: Generate C++ library
cppRule = pctx.AndroidStaticRule("cc_aconfig_library",
diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go
index 673ac2a..ebca413 100644
--- a/aconfig/codegen/java_aconfig_library.go
+++ b/aconfig/codegen/java_aconfig_library.go
@@ -20,6 +20,7 @@
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
+ "strconv"
)
type declarationsTagType struct {
@@ -71,6 +72,7 @@
module.AddSharedLibrary("aconfig-annotations-lib")
// TODO(b/303773055): Remove the annotation after access issue is resolved.
module.AddSharedLibrary("unsupportedappusage")
+ module.AddSharedLibrary("aconfig_storage_reader_java")
}
}
@@ -102,7 +104,8 @@
Output: srcJarPath,
Description: "aconfig.srcjar",
Args: map[string]string{
- "mode": mode,
+ "mode": mode,
+ "debug": strconv.FormatBool(ctx.Config().ReleaseReadFromNewStorage()),
},
})
diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go
index d2a9622..b902f8b 100644
--- a/android/aconfig_providers.go
+++ b/android/aconfig_providers.go
@@ -107,7 +107,7 @@
mergedAconfigFiles := make(map[string]Paths)
mergedModeInfos := make(map[string]ModeInfo)
- ctx.VisitDirectDepsIgnoreBlueprint(func(module Module) {
+ ctx.VisitDirectDeps(func(module Module) {
if aconfig_dep, ok := OtherModuleProvider(ctx, module, CodegenInfoProvider); ok && len(aconfig_dep.ModeInfos) > 0 {
maps.Copy(mergedModeInfos, aconfig_dep.ModeInfos)
}
diff --git a/android/apex.go b/android/apex.go
index 114fe29..79ab13c 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -989,8 +989,8 @@
// Function called while walking an APEX's payload dependencies.
//
// Return true if the `to` module should be visited, false otherwise.
-type PayloadDepsCallback func(ctx ModuleContext, from blueprint.Module, to ApexModule, externalDep bool) bool
-type WalkPayloadDepsFunc func(ctx ModuleContext, do PayloadDepsCallback)
+type PayloadDepsCallback func(ctx BaseModuleContext, from blueprint.Module, to ApexModule, externalDep bool) bool
+type WalkPayloadDepsFunc func(ctx BaseModuleContext, do PayloadDepsCallback)
// ModuleWithMinSdkVersionCheck represents a module that implements min_sdk_version checks
type ModuleWithMinSdkVersionCheck interface {
@@ -1017,7 +1017,7 @@
return
}
- walk(ctx, func(ctx ModuleContext, from blueprint.Module, to ApexModule, externalDep bool) bool {
+ walk(ctx, func(ctx BaseModuleContext, from blueprint.Module, to ApexModule, externalDep bool) bool {
if externalDep {
// external deps are outside the payload boundary, which is "stable"
// interface. We don't have to check min_sdk_version for external
diff --git a/android/arch.go b/android/arch.go
index 942727a..1ec971d 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -138,6 +138,16 @@
return a.Name
}
+func (a ArchType) Bitness() string {
+ if a.Multilib == "lib32" {
+ return "32"
+ }
+ if a.Multilib == "lib64" {
+ return "64"
+ }
+ panic("Bitness is not defined for the common variant")
+}
+
const COMMON_VARIANT = "common"
var (
diff --git a/android/arch_list.go b/android/arch_list.go
index 9501c87..389f194 100644
--- a/android/arch_list.go
+++ b/android/arch_list.go
@@ -29,6 +29,7 @@
"armv9-2a",
},
X86: {
+ "alderlake",
"amberlake",
"atom",
"broadwell",
@@ -53,6 +54,7 @@
"x86_64",
},
X86_64: {
+ "alderlake",
"amberlake",
"broadwell",
"goldmont",
@@ -110,9 +112,6 @@
}
var archFeatures = map[ArchType][]string{
- Arm: {
- "neon",
- },
Arm64: {
"dotprod",
},
@@ -142,17 +141,6 @@
}
var androidArchFeatureMap = map[ArchType]map[string][]string{
- Arm: {
- "armv7-a-neon": {
- "neon",
- },
- "armv8-a": {
- "neon",
- },
- "armv8-2a": {
- "neon",
- },
- },
Arm64: {
"armv8-2a-dotprod": {
"dotprod",
@@ -165,6 +153,16 @@
},
},
X86: {
+ "alderlake": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "aes_ni",
+ "popcnt",
+ },
"amberlake": {
"ssse3",
"sse4",
@@ -341,6 +339,16 @@
"sse4_2",
"popcnt",
},
+ "alderlake": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "aes_ni",
+ "popcnt",
+ },
"amberlake": {
"ssse3",
"sse4",
diff --git a/android/base_module_context.go b/android/base_module_context.go
index bb81377..c7d7573 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -113,31 +113,22 @@
// the first DependencyTag.
GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
- // VisitDirectDepsBlueprint calls visit for each direct dependency. If there are multiple
+ // VisitDirectDeps calls visit for each direct dependency. If there are multiple
+ // direct dependencies on the same module visit will be called multiple times on that module
+ // and OtherModuleDependencyTag will return a different tag for each. It raises an error if any of the
+ // dependencies are disabled.
+ //
+ // The Module passed to the visit function should not be retained outside of the visit
+ // function, it may be invalidated by future mutators.
+ VisitDirectDeps(visit func(Module))
+
+ // VisitDirectDeps calls visit for each direct dependency. If there are multiple
// direct dependencies on the same module visit will be called multiple times on that module
// and OtherModuleDependencyTag will return a different tag for each.
//
// The Module passed to the visit function should not be retained outside of the visit
// function, it may be invalidated by future mutators.
- VisitDirectDepsBlueprint(visit func(blueprint.Module))
-
- // VisitDirectDepsIgnoreBlueprint calls visit for each direct dependency. If there are multiple
- // direct dependencies on the same module visit will be called multiple times on that module
- // and OtherModuleDependencyTag will return a different tag for each. It silently ignores any
- // dependencies that are not an android.Module.
- //
- // The Module passed to the visit function should not be retained outside of the visit
- // function, it may be invalidated by future mutators.
- VisitDirectDepsIgnoreBlueprint(visit func(Module))
-
- // VisitDirectDeps calls visit for each direct dependency. If there are multiple
- // direct dependencies on the same module visit will be called multiple times on that module
- // and OtherModuleDependencyTag will return a different tag for each. It raises an error if any of the
- // dependencies are not an android.Module.
- //
- // The Module passed to the visit function should not be retained outside of the visit
- // function, it may be invalidated by future mutators.
- VisitDirectDeps(visit func(Module))
+ VisitDirectDepsAllowDisabled(visit func(Module))
VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
@@ -164,17 +155,6 @@
// invalidated by future mutators.
WalkDeps(visit func(child, parent Module) bool)
- // WalkDepsBlueprint calls visit for each transitive dependency, traversing the dependency
- // tree in top down order. visit may be called multiple times for the same (child, parent)
- // pair if there are multiple direct dependencies between the child and parent with different
- // tags. OtherModuleDependencyTag will return the tag for the currently visited
- // (child, parent) pair. If visit returns false WalkDeps will not continue recursing down
- // to child.
- //
- // The Modules passed to the visit function should not be retained outside of the visit function, they may be
- // invalidated by future mutators.
- WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool)
-
// GetWalkPath is supposed to be called in visit function passed in WalkDeps()
// and returns a top-down dependency path from a start module to current child module.
GetWalkPath() []Module
@@ -220,10 +200,6 @@
// EvaluateConfiguration makes ModuleContext a valid proptools.ConfigurableEvaluator, so this context
// can be used to evaluate the final value of Configurable properties.
EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue
-
- // HasMutatorFinished returns true if the given mutator has finished running.
- // It will panic if given an invalid mutator name.
- HasMutatorFinished(mutatorName string) bool
}
type baseModuleContext struct {
@@ -274,10 +250,6 @@
b.bp.SetProvider(provider, value)
}
-func (b *baseModuleContext) HasMutatorFinished(mutatorName string) bool {
- return b.bp.HasMutatorFinished(mutatorName)
-}
-
func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
return b.bp.GetDirectDepWithTag(name, tag)
}
@@ -319,7 +291,7 @@
return true
}
-func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag blueprint.DependencyTag, strict bool, ignoreBlueprint bool) Module {
+func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag blueprint.DependencyTag, strict bool) Module {
aModule, _ := module.(Module)
if !strict {
@@ -327,10 +299,7 @@
}
if aModule == nil {
- if !ignoreBlueprint {
- b.ModuleErrorf("module %q (%#v) not an android module", b.OtherModuleName(module), tag)
- }
- return nil
+ panic(fmt.Errorf("module %q (%#v) not an android module", b.OtherModuleName(module), tag))
}
if !aModule.Enabled(b) {
@@ -353,15 +322,8 @@
func (b *baseModuleContext) getDirectDepsInternal(name string, tag blueprint.DependencyTag) []dep {
var deps []dep
- b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
- if aModule, _ := module.(Module); aModule != nil {
- if aModule.base().BaseModuleName() == name {
- returnedTag := b.bp.OtherModuleDependencyTag(aModule)
- if tag == nil || returnedTag == tag {
- deps = append(deps, dep{aModule, returnedTag})
- }
- }
- } else if b.bp.OtherModuleName(module) == name {
+ b.VisitDirectDeps(func(module Module) {
+ if module.base().BaseModuleName() == name {
returnedTag := b.bp.OtherModuleDependencyTag(module)
if tag == nil || returnedTag == tag {
deps = append(deps, dep{module, returnedTag})
@@ -404,11 +366,9 @@
func (b *baseModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module {
var deps []Module
- b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
- if aModule, _ := module.(Module); aModule != nil {
- if b.bp.OtherModuleDependencyTag(aModule) == tag {
- deps = append(deps, aModule)
- }
+ b.VisitDirectDeps(func(module Module) {
+ if b.bp.OtherModuleDependencyTag(module) == tag {
+ deps = append(deps, module)
}
})
return deps
@@ -421,30 +381,24 @@
return b.getDirectDepFirstTag(name)
}
-func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
- b.bp.VisitDirectDeps(visit)
-}
-
func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) {
- b.visitDirectDeps(visit, false)
-}
-
-func (b *baseModuleContext) VisitDirectDepsIgnoreBlueprint(visit func(Module)) {
- b.visitDirectDeps(visit, true)
-}
-
-func (b *baseModuleContext) visitDirectDeps(visit func(Module), ignoreBlueprint bool) {
b.bp.VisitDirectDeps(func(module blueprint.Module) {
- if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, ignoreBlueprint); aModule != nil {
+ if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
visit(aModule)
}
})
}
+func (b *baseModuleContext) VisitDirectDepsAllowDisabled(visit func(Module)) {
+ b.bp.VisitDirectDeps(func(module blueprint.Module) {
+ visit(module.(Module))
+ })
+}
+
func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
b.bp.VisitDirectDeps(func(module blueprint.Module) {
if b.bp.OtherModuleDependencyTag(module) == tag {
- if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, false); aModule != nil {
+ if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
visit(aModule)
}
}
@@ -455,7 +409,7 @@
b.bp.VisitDirectDepsIf(
// pred
func(module blueprint.Module) bool {
- if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, false); aModule != nil {
+ if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
return pred(aModule)
} else {
return false
@@ -469,7 +423,7 @@
func (b *baseModuleContext) VisitDepsDepthFirst(visit func(Module)) {
b.bp.VisitDepsDepthFirst(func(module blueprint.Module) {
- if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, false); aModule != nil {
+ if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
visit(aModule)
}
})
@@ -479,7 +433,7 @@
b.bp.VisitDepsDepthFirstIf(
// pred
func(module blueprint.Module) bool {
- if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, false); aModule != nil {
+ if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
return pred(aModule)
} else {
return false
@@ -491,10 +445,6 @@
})
}
-func (b *baseModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) {
- b.bp.WalkDeps(visit)
-}
-
func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) {
b.walkPath = []Module{b.Module()}
b.tagPath = []blueprint.DependencyTag{}
diff --git a/android/config.go b/android/config.go
index 00fc823..9f92fff 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1252,7 +1252,7 @@
}
func (c *config) LibartImgHostBaseAddress() string {
- return "0x60000000"
+ return "0x70000000"
}
func (c *config) LibartImgDeviceBaseAddress() string {
@@ -1278,6 +1278,7 @@
}
return false
}
+
func (c *config) EnforceRROExcludedOverlay(path string) bool {
excluded := c.productVariables.EnforceRROExcludedOverlays
if len(excluded) > 0 {
@@ -1286,6 +1287,11 @@
return false
}
+func (c *config) EnforceRROGlobally() bool {
+ enforceList := c.productVariables.EnforceRROTargets
+ return InList("*", enforceList)
+}
+
func (c *config) ExportedNamespaces() []string {
return append([]string(nil), c.productVariables.NamespacesToExport...)
}
@@ -1691,14 +1697,6 @@
return Bool(c.productVariables.EnforceProductPartitionInterface)
}
-func (c *config) EnforceInterPartitionJavaSdkLibrary() bool {
- return Bool(c.productVariables.EnforceInterPartitionJavaSdkLibrary)
-}
-
-func (c *config) InterPartitionJavaLibraryAllowList() []string {
- return c.productVariables.InterPartitionJavaLibraryAllowList
-}
-
func (c *config) ProductHiddenAPIStubs() []string {
return c.productVariables.ProductHiddenAPIStubs
}
diff --git a/android/container.go b/android/container.go
index c048d6c..2a3777b 100644
--- a/android/container.go
+++ b/android/container.go
@@ -479,7 +479,7 @@
func checkContainerViolations(ctx ModuleContext) {
if _, ok := ctx.Module().(InstallableModule); ok {
containersInfo, _ := getContainerModuleInfo(ctx, ctx.Module())
- ctx.VisitDirectDepsIgnoreBlueprint(func(dep Module) {
+ ctx.VisitDirectDeps(func(dep Module) {
if !dep.Enabled(ctx) {
return
}
diff --git a/android/early_module_context.go b/android/early_module_context.go
index 23f4c90..11de771 100644
--- a/android/early_module_context.go
+++ b/android/early_module_context.go
@@ -93,6 +93,10 @@
// Namespace returns the Namespace object provided by the NameInterface set by Context.SetNameInterface, or the
// default SimpleNameInterface if Context.SetNameInterface was not called.
Namespace() *Namespace
+
+ // HasMutatorFinished returns true if the given mutator has finished running.
+ // It will panic if given an invalid mutator name.
+ HasMutatorFinished(mutatorName string) bool
}
// Deprecated: use EarlyModuleContext instead
@@ -175,3 +179,7 @@
func (e *earlyModuleContext) OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{}) {
e.EarlyModuleContext.OtherModulePropertyErrorf(module, property, fmt, args...)
}
+
+func (e *earlyModuleContext) HasMutatorFinished(mutatorName string) bool {
+ return e.EarlyModuleContext.HasMutatorFinished(mutatorName)
+}
diff --git a/android/hooks.go b/android/hooks.go
index 2ad3b5f..bd2fa5e 100644
--- a/android/hooks.go
+++ b/android/hooks.go
@@ -95,10 +95,17 @@
type createModuleContext interface {
Module() Module
+ HasMutatorFinished(mutatorName string) bool
createModule(blueprint.ModuleFactory, string, ...interface{}) blueprint.Module
}
func createModule(ctx createModuleContext, factory ModuleFactory, ext string, props ...interface{}) Module {
+ if ctx.HasMutatorFinished("defaults") {
+ // Creating modules late is oftentimes problematic, because they don't have earlier
+ // mutators run on them. Prevent making modules after the defaults mutator has run.
+ panic("Cannot create a module after the defaults mutator has finished")
+ }
+
inherited := []interface{}{&ctx.Module().base().commonProperties}
var typeName string
diff --git a/android/license_metadata.go b/android/license_metadata.go
index 0ac975f..f925638 100644
--- a/android/license_metadata.go
+++ b/android/license_metadata.go
@@ -63,11 +63,7 @@
var allDepOutputFiles Paths
var allDepMetadataDepSets []*DepSet[Path]
- ctx.VisitDirectDepsBlueprint(func(bpdep blueprint.Module) {
- dep, _ := bpdep.(Module)
- if dep == nil {
- return
- }
+ ctx.VisitDirectDeps(func(dep Module) {
if !dep.Enabled(ctx) {
return
}
diff --git a/android/module.go b/android/module.go
index e2b7e11..20caae2 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1005,6 +1005,14 @@
return
}
+ // Do not create a dependency from common variant to arch variant for `common_first` modules
+ if multilib, _ := decodeMultilib(ctx, ctx.Module().base()); multilib == string(MultilibCommonFirst) {
+ commonVariant := ctx.Arch().ArchType.Multilib == ""
+ if bothInAndroid && commonVariant && InList(target.Arch.ArchType.Multilib, []string{"lib32", "lib64"}) {
+ return
+ }
+ }
+
variation := target.Variations()
if ctx.OtherModuleFarDependencyVariantExists(variation, depName) {
ctx.AddFarVariationDependencies(variation, RequiredDepTag, depName)
@@ -1057,8 +1065,29 @@
}{}
func addVintfFragmentDeps(ctx BottomUpMutatorContext) {
+ // Vintf manifests in the recovery partition will be ignored.
+ if !ctx.Device() || ctx.Module().InstallInRecovery() {
+ return
+ }
+
+ deviceConfig := ctx.DeviceConfig()
+
mod := ctx.Module()
- ctx.AddDependency(mod, vintfDepTag, mod.VintfFragmentModuleNames(ctx)...)
+ vintfModules := ctx.AddDependency(mod, vintfDepTag, mod.VintfFragmentModuleNames(ctx)...)
+
+ modPartition := mod.PartitionTag(deviceConfig)
+ for _, vintf := range vintfModules {
+ if vintfModule, ok := vintf.(*vintfFragmentModule); ok {
+ vintfPartition := vintfModule.PartitionTag(deviceConfig)
+ if modPartition != vintfPartition {
+ ctx.ModuleErrorf("Module %q(%q) and Vintf_fragment %q(%q) are installed to different partitions.",
+ mod.Name(), modPartition,
+ vintfModule.Name(), vintfPartition)
+ }
+ } else {
+ ctx.ModuleErrorf("Only vintf_fragment type module should be listed in vintf_fragment_modules : %q", vintf.Name())
+ }
+ }
}
// AddProperties "registers" the provided props
@@ -1840,10 +1869,8 @@
if m.Enabled(ctx) {
// ensure all direct android.Module deps are enabled
- ctx.VisitDirectDepsBlueprint(func(bm blueprint.Module) {
- if m, ok := bm.(Module); ok {
- ctx.validateAndroidModule(bm, ctx.OtherModuleDependencyTag(m), ctx.baseModuleContext.strictVisitDeps, false)
- }
+ ctx.VisitDirectDeps(func(m Module) {
+ ctx.validateAndroidModule(m, ctx.OtherModuleDependencyTag(m), ctx.baseModuleContext.strictVisitDeps)
})
if m.Device() {
@@ -2269,6 +2296,8 @@
}
variable := condition.Arg(0)
switch variable {
+ case "build_from_text_stub":
+ return proptools.ConfigurableValueBool(ctx.Config().BuildFromTextStub())
case "debuggable":
return proptools.ConfigurableValueBool(ctx.Config().Debuggable())
case "use_debug_art":
diff --git a/android/module_test.go b/android/module_test.go
index d64e3a5..d76d9b3 100644
--- a/android/module_test.go
+++ b/android/module_test.go
@@ -1080,3 +1080,29 @@
})
}
}
+
+func TestVintfFragmentModulesChecksPartition(t *testing.T) {
+ bp := `
+ vintf_fragment {
+ name: "vintfModA",
+ src: "test_vintf_file",
+ vendor: true,
+ }
+ deps {
+ name: "modA",
+ vintf_fragment_modules: [
+ "vintfModA",
+ ]
+ }
+ `
+
+ testPreparer := GroupFixturePreparers(
+ PrepareForTestWithAndroidBuildComponents,
+ prepareForModuleTests,
+ )
+
+ testPreparer.
+ ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(
+ "Module .+ and Vintf_fragment .+ are installed to different partitions.")).
+ RunTestWithBp(t, bp)
+}
diff --git a/android/mutator.go b/android/mutator.go
index 9404945..a8b5c7d 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -26,7 +26,7 @@
// run Pre-deps mutators
// run depsMutator
// run PostDeps mutators
-// run FinalDeps mutators (CreateVariations disallowed in this phase)
+// run FinalDeps mutators (TransitionMutators disallowed in this phase)
// continue on to GenerateAndroidBuildActions
// collateGloballyRegisteredMutators constructs the list of mutators that have been registered
@@ -231,36 +231,6 @@
// module's dependency list.
AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string)
- // CreateVariations splits a module into multiple variants, one for each name in the variationNames
- // parameter. It returns a list of new modules in the same order as the variationNames
- // list.
- //
- // If any of the dependencies of the module being operated on were already split
- // by calling CreateVariations with the same name, the dependency will automatically
- // be updated to point the matching variant.
- //
- // If a module is split, and then a module depending on the first module is not split
- // when the Mutator is later called on it, the dependency of the depending module will
- // automatically be updated to point to the first variant.
- CreateVariations(...string) []Module
-
- // CreateLocationVariations splits a module into multiple variants, one for each name in the variantNames
- // parameter. It returns a list of new modules in the same order as the variantNames
- // list.
- //
- // Local variations do not affect automatic dependency resolution - dependencies added
- // to the split module via deps or DynamicDependerModule must exactly match a variant
- // that contains all the non-local variations.
- CreateLocalVariations(...string) []Module
-
- // SetDependencyVariation sets all dangling dependencies on the current module to point to the variation
- // with given name. This function ignores the default variation set by SetDefaultDependencyVariation.
- SetDependencyVariation(string)
-
- // SetDefaultDependencyVariation sets the default variation when a dangling reference is detected
- // during the subsequent calls on Create*Variations* functions. To reset, set it to nil.
- SetDefaultDependencyVariation(*string)
-
// AddVariationDependencies adds deps as dependencies of the current module, but uses the variations
// argument to select which variant of the dependency to use. It returns a slice of modules for
// each dependency (some entries may be nil). A variant of the dependency must exist that matches
@@ -272,6 +242,16 @@
// be ordered correctly for all future mutator passes.
AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, names ...string) []blueprint.Module
+ // AddReverseVariationDependencies adds a dependency from the named module to the current
+ // module. The given variations will be added to the current module's varations, and then the
+ // result will be used to find the correct variation of the depending module, which must exist.
+ //
+ // Does not affect the ordering of the current mutator pass, but will be ordered
+ // correctly for all future mutator passes. All reverse dependencies for a destination module are
+ // collected until the end of the mutator pass, sorted by name, and then appended to the destination
+ // module's dependency list.
+ AddReverseVariationDependency([]blueprint.Variation, blueprint.DependencyTag, string)
+
// AddFarVariationDependencies adds deps as dependencies of the current module, but uses the
// variations argument to select which variant of the dependency to use. It returns a slice of
// modules for each dependency (some entries may be nil). A variant of the dependency must
@@ -287,12 +267,6 @@
// be ordered correctly for all future mutator passes.
AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) []blueprint.Module
- // AddInterVariantDependency adds a dependency between two variants of the same module. Variants are always
- // ordered in the same orderas they were listed in CreateVariations, and AddInterVariantDependency does not change
- // that ordering, but it associates a DependencyTag with the dependency and makes it visible to VisitDirectDeps,
- // WalkDeps, etc.
- AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module)
-
// ReplaceDependencies finds all the variants of the module with the specified name, then
// replaces all dependencies onto those variants with the current variant of this module.
// Replacements don't take effect until after the mutator pass is finished.
@@ -303,30 +277,6 @@
// as long as the supplied predicate returns true.
// Replacements don't take effect until after the mutator pass is finished.
ReplaceDependenciesIf(string, blueprint.ReplaceDependencyPredicate)
-
- // AliasVariation takes a variationName that was passed to CreateVariations for this module,
- // and creates an alias from the current variant (before the mutator has run) to the new
- // variant. The alias will be valid until the next time a mutator calls CreateVariations or
- // CreateLocalVariations on this module without also calling AliasVariation. The alias can
- // be used to add dependencies on the newly created variant using the variant map from
- // before CreateVariations was run.
- AliasVariation(variationName string)
-
- // CreateAliasVariation takes a toVariationName that was passed to CreateVariations for this
- // module, and creates an alias from a new fromVariationName variant the toVariationName
- // variant. The alias will be valid until the next time a mutator calls CreateVariations or
- // CreateLocalVariations on this module without also calling AliasVariation. The alias can
- // be used to add dependencies on the toVariationName variant using the fromVariationName
- // variant.
- CreateAliasVariation(fromVariationName, toVariationName string)
-
- // SetVariationProvider sets the value for a provider for the given newly created variant of
- // the current module, i.e. one of the Modules returned by CreateVariations.. It panics if
- // not called during the appropriate mutator or GenerateBuildActions pass for the provider,
- // if the value is not of the appropriate type, or if the module is not a newly created
- // variant of the current module. The value should not be modified after being passed to
- // SetVariationProvider.
- SetVariationProvider(module blueprint.Module, provider blueprint.AnyProviderKey, value interface{})
}
// An outgoingTransitionContextImpl and incomingTransitionContextImpl is created for every dependency of every module
@@ -764,48 +714,11 @@
b.bp.AddReverseDependency(module, tag, name)
}
-func (b *bottomUpMutatorContext) CreateVariations(variations ...string) []Module {
- if b.finalPhase {
- panic("CreateVariations not allowed in FinalDepsMutators")
+func (b *bottomUpMutatorContext) AddReverseVariationDependency(variations []blueprint.Variation, tag blueprint.DependencyTag, name string) {
+ if b.baseModuleContext.checkedMissingDeps() {
+ panic("Adding deps not allowed after checking for missing deps")
}
-
- modules := b.bp.CreateVariations(variations...)
-
- aModules := make([]Module, len(modules))
- for i := range variations {
- aModules[i] = modules[i].(Module)
- base := aModules[i].base()
- base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName())
- base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i])
- }
-
- return aModules
-}
-
-func (b *bottomUpMutatorContext) CreateLocalVariations(variations ...string) []Module {
- if b.finalPhase {
- panic("CreateLocalVariations not allowed in FinalDepsMutators")
- }
-
- modules := b.bp.CreateLocalVariations(variations...)
-
- aModules := make([]Module, len(modules))
- for i := range variations {
- aModules[i] = modules[i].(Module)
- base := aModules[i].base()
- base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName())
- base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i])
- }
-
- return aModules
-}
-
-func (b *bottomUpMutatorContext) SetDependencyVariation(variation string) {
- b.bp.SetDependencyVariation(variation)
-}
-
-func (b *bottomUpMutatorContext) SetDefaultDependencyVariation(variation *string) {
- b.bp.SetDefaultDependencyVariation(variation)
+ b.bp.AddReverseVariationDependency(variations, tag, name)
}
func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag,
@@ -825,10 +738,6 @@
return b.bp.AddFarVariationDependencies(variations, tag, names...)
}
-func (b *bottomUpMutatorContext) AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) {
- b.bp.AddInterVariantDependency(tag, from, to)
-}
-
func (b *bottomUpMutatorContext) ReplaceDependencies(name string) {
if b.baseModuleContext.checkedMissingDeps() {
panic("Adding deps not allowed after checking for missing deps")
@@ -842,15 +751,3 @@
}
b.bp.ReplaceDependenciesIf(name, predicate)
}
-
-func (b *bottomUpMutatorContext) AliasVariation(variationName string) {
- b.bp.AliasVariation(variationName)
-}
-
-func (b *bottomUpMutatorContext) CreateAliasVariation(fromVariationName, toVariationName string) {
- b.bp.CreateAliasVariation(fromVariationName, toVariationName)
-}
-
-func (b *bottomUpMutatorContext) SetVariationProvider(module blueprint.Module, provider blueprint.AnyProviderKey, value interface{}) {
- b.bp.SetVariationProvider(module, provider, value)
-}
diff --git a/android/mutator_test.go b/android/mutator_test.go
index b3ef00f..5d4074a 100644
--- a/android/mutator_test.go
+++ b/android/mutator_test.go
@@ -287,7 +287,7 @@
AssertDeepEquals(t, "final", finalWant, finalGot)
}
-func TestNoCreateVariationsInFinalDeps(t *testing.T) {
+func TestTransitionMutatorInFinalDeps(t *testing.T) {
GroupFixturePreparers(
FixtureRegisterWithContext(func(ctx RegistrationContext) {
ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
diff --git a/android/paths.go b/android/paths.go
index 0d94f03..1c8258e 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -92,7 +92,7 @@
type ModuleWithDepsPathContext interface {
EarlyModulePathContext
OtherModuleProviderContext
- VisitDirectDepsBlueprint(visit func(blueprint.Module))
+ VisitDirectDeps(visit func(Module))
OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
HasMutatorFinished(mutatorName string) bool
}
@@ -598,7 +598,7 @@
// create the tag here as was supplied to create the tag when the dependency was added so that
// this finds the matching dependency module.
expectedTag := sourceOrOutputDepTag(moduleName, tag)
- ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
+ ctx.VisitDirectDeps(func(module Module) {
depTag := ctx.OtherModuleDependencyTag(module)
if depTag == expectedTag {
found = module
diff --git a/android/prebuilt.go b/android/prebuilt.go
index fd5a6ea..4f04d05 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -359,8 +359,8 @@
//
// This function is for use on dependencies after PrebuiltPostDepsMutator has
// run - any dependency that is registered before that will already reference
-// the right module. This function is only safe to call after all mutators that
-// may call CreateVariations, e.g. in GenerateAndroidBuildActions.
+// the right module. This function is only safe to call after all TransitionMutators
+// have run, e.g. in GenerateAndroidBuildActions.
func PrebuiltGetPreferred(ctx BaseModuleContext, module Module) Module {
if !module.IsReplacedByPrebuilt() {
return module
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 18bbcab..56de9cd 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -38,6 +38,9 @@
const sboxToolsSubDir = "tools"
const sboxOutDir = sboxSandboxBaseDir + "/" + sboxOutSubDir
+const nsjailToolsSubDir = "tools"
+const nsjailOutDir = "out"
+
// RuleBuilder provides an alternative to ModuleContext.Rule and ModuleContext.Build to add a command line to the build
// graph.
type RuleBuilder struct {
@@ -59,6 +62,9 @@
sboxManifestPath WritablePath
missingDeps []string
args map[string]string
+ nsjail bool
+ nsjailBasePath WritablePath
+ nsjailImplicits Paths
}
// NewRuleBuilder returns a newly created RuleBuilder.
@@ -165,12 +171,43 @@
if len(r.commands) > 0 {
panic("Sbox() may not be called after Command()")
}
+ if r.nsjail {
+ panic("Sbox() may not be called after Nsjail()")
+ }
r.sbox = true
r.outDir = outputDir
r.sboxManifestPath = manifestPath
return r
}
+// Nsjail marks the rule as needing to be wrapped by nsjail. The outputDir should point to the
+// output directory that nsjail will mount to out/. It should not be written to by any other rule.
+// baseDir should point to a location where nsjail will mount to /nsjail_build_sandbox, which will
+// be the working directory of the command.
+func (r *RuleBuilder) Nsjail(outputDir WritablePath, baseDir WritablePath) *RuleBuilder {
+ if len(r.commands) > 0 {
+ panic("Nsjail() may not be called after Command()")
+ }
+ if r.sbox {
+ panic("Nsjail() may not be called after Sbox()")
+ }
+ r.nsjail = true
+ r.outDir = outputDir
+ r.nsjailBasePath = baseDir
+ return r
+}
+
+// NsjailImplicits adds implicit inputs that are not directly mounted. This is useful when
+// the rule mounts directories, as files within those directories can be globbed and
+// tracked as dependencies with NsjailImplicits().
+func (r *RuleBuilder) NsjailImplicits(inputs Paths) *RuleBuilder {
+ if !r.nsjail {
+ panic("NsjailImplicits() must be called after Nsjail()")
+ }
+ r.nsjailImplicits = append(r.nsjailImplicits, inputs...)
+ return r
+}
+
// SandboxTools enables tool sandboxing for the rule by copying any referenced tools into the
// sandbox.
func (r *RuleBuilder) SandboxTools() *RuleBuilder {
@@ -514,7 +551,73 @@
commandString := strings.Join(commands, " && ")
- if r.sbox {
+ if !r.sbox {
+ // If not using sbox the rule will run the command directly, put the hash of the
+ // list of input files in a comment at the end of the command line to ensure ninja
+ // reruns the rule when the list of input files changes.
+ commandString += " # hash of input list: " + hashSrcFiles(inputs)
+ }
+
+ if r.nsjail {
+ var nsjailCmd strings.Builder
+ nsjailPath := r.ctx.Config().PrebuiltBuildTool(r.ctx, "nsjail")
+ nsjailCmd.WriteString("mkdir -p ")
+ nsjailCmd.WriteString(r.nsjailBasePath.String())
+ nsjailCmd.WriteString(" && ")
+ nsjailCmd.WriteString(nsjailPath.String())
+ nsjailCmd.WriteRune(' ')
+ nsjailCmd.WriteString("-B $PWD/")
+ nsjailCmd.WriteString(r.nsjailBasePath.String())
+ nsjailCmd.WriteString(":nsjail_build_sandbox")
+
+ // out is mounted to $(genDir).
+ nsjailCmd.WriteString(" -B $PWD/")
+ nsjailCmd.WriteString(r.outDir.String())
+ nsjailCmd.WriteString(":nsjail_build_sandbox/out")
+
+ for _, input := range inputs {
+ nsjailCmd.WriteString(" -R $PWD/")
+ nsjailCmd.WriteString(input.String())
+ nsjailCmd.WriteString(":nsjail_build_sandbox/")
+ nsjailCmd.WriteString(r.nsjailPathForInputRel(input))
+ }
+ for _, tool := range tools {
+ nsjailCmd.WriteString(" -R $PWD/")
+ nsjailCmd.WriteString(tool.String())
+ nsjailCmd.WriteString(":nsjail_build_sandbox/")
+ nsjailCmd.WriteString(nsjailPathForToolRel(r.ctx, tool))
+ }
+ inputs = append(inputs, tools...)
+ for _, c := range r.commands {
+ for _, tool := range c.packagedTools {
+ nsjailCmd.WriteString(" -R $PWD/")
+ nsjailCmd.WriteString(tool.srcPath.String())
+ nsjailCmd.WriteString(":nsjail_build_sandbox/")
+ nsjailCmd.WriteString(nsjailPathForPackagedToolRel(tool))
+ inputs = append(inputs, tool.srcPath)
+ }
+ }
+
+ // These five directories are necessary to run native host tools like /bin/bash and py3-cmd.
+ nsjailCmd.WriteString(" -R /bin")
+ nsjailCmd.WriteString(" -R /lib")
+ nsjailCmd.WriteString(" -R /lib64")
+ nsjailCmd.WriteString(" -R /dev")
+ nsjailCmd.WriteString(" -R /usr")
+
+ nsjailCmd.WriteString(" -m none:/tmp:tmpfs:size=1073741824") // 1GB, should be enough
+ nsjailCmd.WriteString(" -D nsjail_build_sandbox")
+ nsjailCmd.WriteString(" --disable_rlimits")
+ nsjailCmd.WriteString(" -q")
+ nsjailCmd.WriteString(" -- ")
+ nsjailCmd.WriteString("/bin/bash -c ")
+ nsjailCmd.WriteString(proptools.ShellEscape(commandString))
+
+ commandString = nsjailCmd.String()
+
+ inputs = append(inputs, nsjailPath)
+ inputs = append(inputs, r.nsjailImplicits...)
+ } else if r.sbox {
// If running the command inside sbox, write the rule data out to an sbox
// manifest.textproto.
manifest := sbox_proto.Manifest{}
@@ -734,11 +837,6 @@
rewrapperCommand := r.rbeParams.NoVarTemplate(r.ctx.Config().RBEWrapper())
commandString = rewrapperCommand + " bash -c '" + strings.ReplaceAll(commandString, `'`, `'\''`) + "'"
}
- } else {
- // If not using sbox the rule will run the command directly, put the hash of the
- // list of input files in a comment at the end of the command line to ensure ninja
- // reruns the rule when the list of input files changes.
- commandString += " # hash of input list: " + hashSrcFiles(inputs)
}
// Ninja doesn't like multiple outputs when depfiles are enabled, move all but the first output to
@@ -869,6 +967,8 @@
rel = filepath.Join(sboxSandboxBaseDir, rel)
}
return rel
+ } else if c.rule.nsjail {
+ return c.rule.nsjailPathForInputRel(path)
}
return path.String()
}
@@ -894,6 +994,10 @@
// Errors will be handled in RuleBuilder.Build where we have a context to report them
rel, _, _ := maybeRelErr(c.rule.outDir.String(), path.String())
return filepath.Join(sboxOutDir, rel)
+ } else if c.rule.nsjail {
+ // Errors will be handled in RuleBuilder.Build where we have a context to report them
+ rel, _, _ := maybeRelErr(c.rule.outDir.String(), path.String())
+ return filepath.Join(nsjailOutDir, rel)
}
return path.String()
}
@@ -945,15 +1049,49 @@
return filepath.Join(sboxToolsSubDir, "out", spec.relPathInPackage)
}
+func nsjailPathForToolRel(ctx BuilderContext, path Path) string {
+ // Errors will be handled in RuleBuilder.Build where we have a context to report them
+ toolDir := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "")
+ relOutSoong, isRelOutSoong, _ := maybeRelErr(toolDir.String(), path.String())
+ if isRelOutSoong {
+ // The tool is in the Soong output directory, it will be copied to __SBOX_OUT_DIR__/tools/out
+ return filepath.Join(nsjailToolsSubDir, "out", relOutSoong)
+ }
+ // The tool is in the source directory, it will be copied to __SBOX_OUT_DIR__/tools/src
+ return filepath.Join(nsjailToolsSubDir, "src", path.String())
+}
+
+func (r *RuleBuilder) nsjailPathForInputRel(path Path) string {
+ rel, isRelSboxOut, _ := maybeRelErr(r.outDir.String(), path.String())
+ if isRelSboxOut {
+ return filepath.Join(nsjailOutDir, rel)
+ }
+ return path.String()
+}
+
+func (r *RuleBuilder) nsjailPathsForInputsRel(paths Paths) []string {
+ ret := make([]string, len(paths))
+ for i, path := range paths {
+ ret[i] = r.nsjailPathForInputRel(path)
+ }
+ return ret
+}
+
+func nsjailPathForPackagedToolRel(spec PackagingSpec) string {
+ return filepath.Join(nsjailToolsSubDir, "out", spec.relPathInPackage)
+}
+
// PathForPackagedTool takes a PackageSpec for a tool and returns the corresponding path for the
// tool after copying it into the sandbox. This can be used on the RuleBuilder command line to
// reference the tool.
func (c *RuleBuilderCommand) PathForPackagedTool(spec PackagingSpec) string {
- if !c.rule.sboxTools {
- panic("PathForPackagedTool() requires SandboxTools()")
+ if c.rule.sboxTools {
+ return filepath.Join(sboxSandboxBaseDir, sboxPathForPackagedToolRel(spec))
+ } else if c.rule.nsjail {
+ return nsjailPathForPackagedToolRel(spec)
+ } else {
+ panic("PathForPackagedTool() requires SandboxTools() or Nsjail()")
}
-
- return filepath.Join(sboxSandboxBaseDir, sboxPathForPackagedToolRel(spec))
}
// PathForTool takes a path to a tool, which may be an output file or a source file, and returns
@@ -962,6 +1100,8 @@
func (c *RuleBuilderCommand) PathForTool(path Path) string {
if c.rule.sbox && c.rule.sboxTools {
return filepath.Join(sboxSandboxBaseDir, sboxPathForToolRel(c.rule.ctx, path))
+ } else if c.rule.nsjail {
+ return nsjailPathForToolRel(c.rule.ctx, path)
}
return path.String()
}
@@ -976,6 +1116,12 @@
ret = append(ret, filepath.Join(sboxSandboxBaseDir, sboxPathForToolRel(c.rule.ctx, path)))
}
return ret
+ } else if c.rule.nsjail {
+ var ret []string
+ for _, path := range paths {
+ ret = append(ret, nsjailPathForToolRel(c.rule.ctx, path))
+ }
+ return ret
}
return paths.Strings()
}
@@ -983,20 +1129,22 @@
// PackagedTool adds the specified tool path to the command line. It can only be used with tool
// sandboxing enabled by SandboxTools(), and will copy the tool into the sandbox.
func (c *RuleBuilderCommand) PackagedTool(spec PackagingSpec) *RuleBuilderCommand {
- if !c.rule.sboxTools {
- panic("PackagedTool() requires SandboxTools()")
- }
-
c.packagedTools = append(c.packagedTools, spec)
- c.Text(sboxPathForPackagedToolRel(spec))
+ if c.rule.sboxTools {
+ c.Text(sboxPathForPackagedToolRel(spec))
+ } else if c.rule.nsjail {
+ c.Text(nsjailPathForPackagedToolRel(spec))
+ } else {
+ panic("PackagedTool() requires SandboxTools() or Nsjail()")
+ }
return c
}
// ImplicitPackagedTool copies the specified tool into the sandbox without modifying the command
// line. It can only be used with tool sandboxing enabled by SandboxTools().
func (c *RuleBuilderCommand) ImplicitPackagedTool(spec PackagingSpec) *RuleBuilderCommand {
- if !c.rule.sboxTools {
- panic("ImplicitPackagedTool() requires SandboxTools()")
+ if !c.rule.sboxTools && !c.rule.nsjail {
+ panic("ImplicitPackagedTool() requires SandboxTools() or Nsjail()")
}
c.packagedTools = append(c.packagedTools, spec)
@@ -1006,8 +1154,8 @@
// ImplicitPackagedTools copies the specified tools into the sandbox without modifying the command
// line. It can only be used with tool sandboxing enabled by SandboxTools().
func (c *RuleBuilderCommand) ImplicitPackagedTools(specs []PackagingSpec) *RuleBuilderCommand {
- if !c.rule.sboxTools {
- panic("ImplicitPackagedTools() requires SandboxTools()")
+ if !c.rule.sboxTools && !c.rule.nsjail {
+ panic("ImplicitPackagedTools() requires SandboxTools() or Nsjail()")
}
c.packagedTools = append(c.packagedTools, specs...)
diff --git a/android/variable.go b/android/variable.go
index e0d512d..7041f49 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -428,9 +428,6 @@
EnforceProductPartitionInterface *bool `json:",omitempty"`
- EnforceInterPartitionJavaSdkLibrary *bool `json:",omitempty"`
- InterPartitionJavaLibraryAllowList []string `json:",omitempty"`
-
BoardUsesRecoveryAsBoot *bool `json:",omitempty"`
BoardKernelBinaries []string `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index 0caf37c..5f4d823 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -68,8 +68,6 @@
ctx.Transition("apex", &apexTransitionMutator{})
ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator).Parallel()
- // Register after apex_info mutator so that it can use ApexVariationName
- ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel()
}
type apexBundleProperties struct {
@@ -583,7 +581,7 @@
dataPaths []android.DataPath // becomes LOCAL_TEST_DATA
jacocoReportClassesFile android.Path // only for javalibs and apps
- lintDepSets java.LintDepSets // only for javalibs and apps
+ lintInfo *java.LintInfo // only for javalibs and apps
certificate java.Certificate // only for apps
overriddenPackageName string // only for apps
@@ -1115,34 +1113,6 @@
enforceAppUpdatability(mctx)
}
-// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
-// This check is enforced for updatable modules
-func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) {
- if !mctx.Module().Enabled(mctx) {
- return
- }
- if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting(mctx) {
- mctx.WalkDeps(func(child, parent android.Module) bool {
- // b/208656169 Do not propagate strict updatability linting to libcore/
- // These libs are available on the classpath during compilation
- // These libs are transitive deps of the sdk. See java/sdk.go:decodeSdkDep
- // Only skip libraries defined in libcore root, not subdirectories
- if mctx.OtherModuleDir(child) == "libcore" {
- // Do not traverse transitive deps of libcore/ libs
- return false
- }
- if android.InList(child.Name(), skipLintJavalibAllowlist) {
- return false
- }
- if lintable, ok := child.(java.LintDepSetsIntf); ok {
- lintable.SetStrictUpdatabilityLinting(true)
- }
- // visit transitive deps
- return true
- })
- }
-}
-
// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
if !mctx.Module().Enabled(mctx) {
@@ -1203,20 +1173,9 @@
"test_jitzygote_com.android.art",
// go/keep-sorted end
}
-
- // TODO: b/215736885 Remove this list
- skipLintJavalibAllowlist = []string{
- "conscrypt.module.platform.api.stubs",
- "conscrypt.module.public.api.stubs",
- "conscrypt.module.public.api.stubs.system",
- "conscrypt.module.public.api.stubs.module_lib",
- "framework-media.stubs",
- "framework-media.stubs.system",
- "framework-media.stubs.module_lib",
- }
)
-func (a *apexBundle) checkStrictUpdatabilityLinting(mctx android.TopDownMutatorContext) bool {
+func (a *apexBundle) checkStrictUpdatabilityLinting(mctx android.ModuleContext) bool {
// The allowlist contains the base apex name, so use that instead of the ApexVariationName
return a.Updatable() && !android.InList(mctx.ModuleName(), skipStrictUpdatabilityLintAllowlist)
}
@@ -1662,7 +1621,6 @@
BaseModuleName() string
DexJarBuildPath(ctx android.ModuleErrorfContext) java.OptionalDexJarPath
JacocoReportClassesFile() android.Path
- LintDepSets() java.LintDepSets
Stem() string
}
@@ -1682,7 +1640,9 @@
dirInApex := "javalib"
af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
af.jacocoReportClassesFile = module.JacocoReportClassesFile()
- af.lintDepSets = module.LintDepSets()
+ if lintInfo, ok := android.OtherModuleProvider(ctx, module, java.LintProvider); ok {
+ af.lintInfo = lintInfo
+ }
af.customStem = module.Stem() + ".jar"
// TODO: b/338641779 - Remove special casing of sdkLibrary once bcpf and sscpf depends
// on the implementation library
@@ -1720,7 +1680,6 @@
JacocoReportClassesFile() android.Path
Certificate() java.Certificate
BaseModuleName() string
- LintDepSets() java.LintDepSets
PrivAppAllowlist() android.OptionalPath
}
@@ -1756,7 +1715,9 @@
af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
- af.lintDepSets = aapp.LintDepSets()
+ if lintInfo, ok := android.OtherModuleProvider(ctx, aapp, java.LintProvider); ok {
+ af.lintInfo = lintInfo
+ }
af.certificate = aapp.Certificate()
if app, ok := aapp.(interface {
@@ -1807,7 +1768,7 @@
// visited module, the `do` callback is executed. Returning true in the callback continues the visit
// to the child modules. Returning false makes the visit to continue in the sibling or the parent
// modules. This is used in check* functions below.
-func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
+func (a *apexBundle) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
ctx.WalkDeps(func(child, parent android.Module) bool {
am, ok := child.(android.ApexModule)
if !ok || !am.CanHaveApexVariants() {
@@ -1974,12 +1935,12 @@
})
}
-func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
+func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent android.Module) bool {
depTag := ctx.OtherModuleDependencyTag(child)
if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
return false
}
- if mod, ok := child.(android.Module); ok && !mod.Enabled(ctx) {
+ if !child.Enabled(ctx) {
return false
}
depName := ctx.OtherModuleName(child)
@@ -2323,7 +2284,7 @@
checkDuplicate: a.shouldCheckDuplicate(ctx),
unwantedTransitiveDeps: a.properties.Unwanted_transitive_deps,
}
- ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
+ ctx.WalkDeps(func(child, parent android.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
vctx.normalizeFileInfo(ctx)
if a.privateKeyFile == nil {
if ctx.Config().AllowMissingDependencies() {
@@ -2653,7 +2614,7 @@
abInfo, _ := android.ModuleProvider(ctx, android.ApexBundleInfoProvider)
- a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
+ a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
if ccm, ok := to.(*cc.Module); ok {
apexName := ctx.ModuleName()
fromName := ctx.OtherModuleName(from)
@@ -2724,7 +2685,7 @@
func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
// Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
// java's checkLinkType guarantees correct usage for transitive deps
- ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
+ ctx.VisitDirectDeps(func(module android.Module) {
tag := ctx.OtherModuleDependencyTag(module)
switch tag {
case javaLibTag, androidAppTag:
@@ -2765,7 +2726,7 @@
return
}
- a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
+ a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
// As soon as the dependency graph crosses the APEX boundary, don't go further.
if externalDep {
return false
@@ -2817,7 +2778,7 @@
// checkStaticExecutable ensures that executables in an APEX are not static.
func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
- ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
+ ctx.VisitDirectDeps(func(module android.Module) {
if ctx.OtherModuleDependencyTag(module) != executableTag {
return
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index feab7a3..7465f40 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -5429,11 +5429,11 @@
apex_available: ["myapex"],
shared_library: false,
permitted_packages: ["bar"],
+ prefer: true,
}
java_sdk_library {
name: "libbar",
- enabled: false,
srcs: ["foo/bar/MyClass.java"],
unsafe_ignore_missing_latest_api: true,
apex_available: ["myapex"],
@@ -9693,120 +9693,84 @@
}
testCases := []struct {
- testCaseName string
- apexUpdatable bool
- javaStrictUpdtabilityLint bool
- lintFileExists bool
- disallowedFlagExpected bool
+ testCaseName string
+ apexUpdatable bool
+ javaStrictUpdtabilityLint bool
+ lintFileExists bool
+ disallowedFlagExpectedOnApex bool
+ disallowedFlagExpectedOnJavalib bool
}{
{
- testCaseName: "lint-baseline.xml does not exist, no disallowed flag necessary in lint cmd",
- apexUpdatable: true,
- javaStrictUpdtabilityLint: true,
- lintFileExists: false,
- disallowedFlagExpected: false,
+ testCaseName: "lint-baseline.xml does not exist, no disallowed flag necessary in lint cmd",
+ apexUpdatable: true,
+ javaStrictUpdtabilityLint: true,
+ lintFileExists: false,
+ disallowedFlagExpectedOnApex: false,
+ disallowedFlagExpectedOnJavalib: false,
},
{
- testCaseName: "non-updatable apex respects strict_updatability of javalib",
- apexUpdatable: false,
- javaStrictUpdtabilityLint: false,
- lintFileExists: true,
- disallowedFlagExpected: false,
+ testCaseName: "non-updatable apex respects strict_updatability of javalib",
+ apexUpdatable: false,
+ javaStrictUpdtabilityLint: false,
+ lintFileExists: true,
+ disallowedFlagExpectedOnApex: false,
+ disallowedFlagExpectedOnJavalib: false,
},
{
- testCaseName: "non-updatable apex respects strict updatability of javalib",
- apexUpdatable: false,
- javaStrictUpdtabilityLint: true,
- lintFileExists: true,
- disallowedFlagExpected: true,
+ testCaseName: "non-updatable apex respects strict updatability of javalib",
+ apexUpdatable: false,
+ javaStrictUpdtabilityLint: true,
+ lintFileExists: true,
+ disallowedFlagExpectedOnApex: false,
+ disallowedFlagExpectedOnJavalib: true,
},
{
- testCaseName: "updatable apex sets strict updatability of javalib to true",
- apexUpdatable: true,
- javaStrictUpdtabilityLint: false, // will be set to true by mutator
- lintFileExists: true,
- disallowedFlagExpected: true,
+ testCaseName: "updatable apex checks strict updatability of javalib",
+ apexUpdatable: true,
+ javaStrictUpdtabilityLint: false,
+ lintFileExists: true,
+ disallowedFlagExpectedOnApex: true,
+ disallowedFlagExpectedOnJavalib: false,
},
}
for _, testCase := range testCases {
- fixtures := []android.FixturePreparer{}
- baselineProperty := ""
- if testCase.lintFileExists {
- fixtures = append(fixtures, fs.AddToFixture())
- baselineProperty = "baseline_filename: \"lint-baseline.xml\""
- }
- bp := fmt.Sprintf(bpTemplate, testCase.apexUpdatable, testCase.javaStrictUpdtabilityLint, baselineProperty)
-
- result := testApex(t, bp, fixtures...)
- myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29")
- sboxProto := android.RuleBuilderSboxProtoForTests(t, result, myjavalib.Output("lint.sbox.textproto"))
- disallowedFlagActual := strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml --disallowed_issues NewApi")
-
- if disallowedFlagActual != testCase.disallowedFlagExpected {
- t.Errorf("Failed testcase: %v \nActual lint cmd: %v", testCase.testCaseName, *sboxProto.Commands[0].Command)
- }
- }
-}
-
-func TestUpdatabilityLintSkipLibcore(t *testing.T) {
- bp := `
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["myjavalib"],
- updatable: true,
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- }
- java_library {
- name: "myjavalib",
- srcs: ["MyClass.java"],
- apex_available: [ "myapex" ],
- sdk_version: "current",
- min_sdk_version: "29",
- lint: {
- baseline_filename: "lint-baseline.xml",
+ t.Run(testCase.testCaseName, func(t *testing.T) {
+ fixtures := []android.FixturePreparer{}
+ baselineProperty := ""
+ if testCase.lintFileExists {
+ fixtures = append(fixtures, fs.AddToFixture())
+ baselineProperty = "baseline_filename: \"lint-baseline.xml\""
}
- }
- `
+ bp := fmt.Sprintf(bpTemplate, testCase.apexUpdatable, testCase.javaStrictUpdtabilityLint, baselineProperty)
- testCases := []struct {
- testCaseName string
- moduleDirectory string
- disallowedFlagExpected bool
- }{
- {
- testCaseName: "lintable module defined outside libcore",
- moduleDirectory: "",
- disallowedFlagExpected: true,
- },
- {
- testCaseName: "lintable module defined in libcore root directory",
- moduleDirectory: "libcore/",
- disallowedFlagExpected: false,
- },
- {
- testCaseName: "lintable module defined in libcore child directory",
- moduleDirectory: "libcore/childdir/",
- disallowedFlagExpected: true,
- },
- }
+ result := testApex(t, bp, fixtures...)
- for _, testCase := range testCases {
- lintFileCreator := android.FixtureAddTextFile(testCase.moduleDirectory+"lint-baseline.xml", "")
- bpFileCreator := android.FixtureAddTextFile(testCase.moduleDirectory+"Android.bp", bp)
- result := testApex(t, "", lintFileCreator, bpFileCreator)
- myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29")
- sboxProto := android.RuleBuilderSboxProtoForTests(t, result, myjavalib.Output("lint.sbox.textproto"))
- cmdFlags := fmt.Sprintf("--baseline %vlint-baseline.xml --disallowed_issues NewApi", testCase.moduleDirectory)
- disallowedFlagActual := strings.Contains(*sboxProto.Commands[0].Command, cmdFlags)
+ checkModule := func(m android.TestingBuildParams, name string, expectStrictUpdatability bool) {
+ if expectStrictUpdatability {
+ if m.Rule == nil {
+ t.Errorf("expected strict updatability check rule on %s", name)
+ } else {
+ android.AssertStringDoesContain(t, fmt.Sprintf("strict updatability check rule for %s", name),
+ m.RuleParams.Command, "--disallowed_issues NewApi")
+ android.AssertStringListContains(t, fmt.Sprintf("strict updatability check baselines for %s", name),
+ m.Inputs.Strings(), "lint-baseline.xml")
+ }
+ } else {
+ if m.Rule != nil {
+ t.Errorf("expected no strict updatability check rule on %s", name)
+ }
+ }
+ }
- if disallowedFlagActual != testCase.disallowedFlagExpected {
- t.Errorf("Failed testcase: %v \nActual lint cmd: %v", testCase.testCaseName, *sboxProto.Commands[0].Command)
- }
+ myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29")
+ apex := result.ModuleForTests("myapex", "android_common_myapex")
+ apexStrictUpdatabilityCheck := apex.MaybeOutput("lint_strict_updatability_check.stamp")
+ javalibStrictUpdatabilityCheck := myjavalib.MaybeOutput("lint_strict_updatability_check.stamp")
+
+ checkModule(apexStrictUpdatabilityCheck, "myapex", testCase.disallowedFlagExpectedOnApex)
+ checkModule(javalibStrictUpdatabilityCheck, "myjavalib", testCase.disallowedFlagExpectedOnJavalib)
+ })
}
}
@@ -9848,11 +9812,12 @@
}
result := testApex(t, bp, dexpreopt.FixtureSetApexBootJars("myapex:myjavalib"), fs.AddToFixture())
- myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29")
- sboxProto := android.RuleBuilderSboxProtoForTests(t, result, myjavalib.Output("lint.sbox.textproto"))
- if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml --disallowed_issues NewApi") {
- t.Errorf("Strict updabality lint missing in myjavalib coming from bootclasspath_fragment mybootclasspath-fragment\nActual lint cmd: %v", *sboxProto.Commands[0].Command)
- }
+ apex := result.ModuleForTests("myapex", "android_common_myapex")
+ apexStrictUpdatabilityCheck := apex.Output("lint_strict_updatability_check.stamp")
+ android.AssertStringDoesContain(t, "strict updatability check rule for myapex",
+ apexStrictUpdatabilityCheck.RuleParams.Command, "--disallowed_issues NewApi")
+ android.AssertStringListContains(t, "strict updatability check baselines for myapex",
+ apexStrictUpdatabilityCheck.Inputs.Strings(), "lint-baseline.xml")
}
func TestApexLintBcpFragmentSdkLibDeps(t *testing.T) {
@@ -10277,14 +10242,15 @@
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 12 {
- t.Fatalf("Expected 12 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 14 {
+ t.Fatalf("Expected 14 commands, got %d in:\n%s", len(copyCmds), s)
}
ensureListContainsMatch(t, copyCmds, "^cp -f .*/aconfig_flags.pb .*/image.apex/etc/aconfig_flags.pb")
ensureListContainsMatch(t, copyCmds, "^cp -f .*/package.map .*/image.apex/etc/package.map")
ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.map .*/image.apex/etc/flag.map")
ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.val .*/image.apex/etc/flag.val")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.info.*/image.apex/etc/flag.info")
inputs := []string{
"my_aconfig_declarations_foo/intermediate.pb",
@@ -10294,6 +10260,7 @@
VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map")
VerifyAconfigRule(t, &mod, "create_aconfig_flag_map_file", inputs, "android_common_myapex/flag.map", "myapex", "flag_map")
VerifyAconfigRule(t, &mod, "create_aconfig_flag_val_file", inputs, "android_common_myapex/flag.val", "myapex", "flag_val")
+ VerifyAconfigRule(t, &mod, "create_aconfig_flag_info_file", inputs, "android_common_myapex/flag.info", "myapex", "flag_info")
}
func TestAconfigFilesJavaAndCcDeps(t *testing.T) {
@@ -10412,14 +10379,15 @@
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 16 {
- t.Fatalf("Expected 16 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 18 {
+ t.Fatalf("Expected 18 commands, got %d in:\n%s", len(copyCmds), s)
}
ensureListContainsMatch(t, copyCmds, "^cp -f .*/aconfig_flags.pb .*/image.apex/etc/aconfig_flags.pb")
ensureListContainsMatch(t, copyCmds, "^cp -f .*/package.map .*/image.apex/etc/package.map")
ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.map .*/image.apex/etc/flag.map")
ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.val .*/image.apex/etc/flag.val")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.info .*/image.apex/etc/flag.info")
inputs := []string{
"my_aconfig_declarations_foo/intermediate.pb",
@@ -10430,6 +10398,7 @@
VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map")
VerifyAconfigRule(t, &mod, "create_aconfig_flag_map_file", inputs, "android_common_myapex/flag.map", "myapex", "flag_map")
VerifyAconfigRule(t, &mod, "create_aconfig_flag_val_file", inputs, "android_common_myapex/flag.val", "myapex", "flag_val")
+ VerifyAconfigRule(t, &mod, "create_aconfig_flag_info_file", inputs, "android_common_myapex/flag.info", "myapex", "flag_info")
}
func TestAconfigFilesRustDeps(t *testing.T) {
@@ -10580,14 +10549,15 @@
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 36 {
- t.Fatalf("Expected 36 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 38 {
+ t.Fatalf("Expected 38 commands, got %d in:\n%s", len(copyCmds), s)
}
ensureListContainsMatch(t, copyCmds, "^cp -f .*/aconfig_flags.pb .*/image.apex/etc/aconfig_flags.pb")
ensureListContainsMatch(t, copyCmds, "^cp -f .*/package.map .*/image.apex/etc/package.map")
ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.map .*/image.apex/etc/flag.map")
ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.val .*/image.apex/etc/flag.val")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.info .*/image.apex/etc/flag.info")
inputs := []string{
"my_aconfig_declarations_foo/intermediate.pb",
@@ -10599,6 +10569,7 @@
VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map")
VerifyAconfigRule(t, &mod, "create_aconfig_flag_map_file", inputs, "android_common_myapex/flag.map", "myapex", "flag_map")
VerifyAconfigRule(t, &mod, "create_aconfig_flag_val_file", inputs, "android_common_myapex/flag.val", "myapex", "flag_val")
+ VerifyAconfigRule(t, &mod, "create_aconfig_flag_info_file", inputs, "android_common_myapex/flag.info", "myapex", "flag_info")
}
func VerifyAconfigRule(t *testing.T, mod *android.TestingModule, desc string, inputs []string, output string, container string, file_type string) {
diff --git a/apex/builder.go b/apex/builder.go
index 437189f..bf3ba9f 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -96,6 +96,7 @@
{"package.map", "create_aconfig_package_map_file", "package_map"},
{"flag.map", "create_aconfig_flag_map_file", "flag_map"},
{"flag.val", "create_aconfig_flag_val_file", "flag_val"},
+ {"flag.info", "create_aconfig_flag_info_file", "flag_info"},
}
var (
@@ -1091,7 +1092,7 @@
}
depInfos := android.DepNameToDepInfoMap{}
- a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
+ a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
if from.Name() == to.Name() {
// This can happen for cc.reuseObjTag. We are not interested in tracking this.
// As soon as the dependency graph crosses the APEX boundary, don't go further.
@@ -1158,10 +1159,23 @@
func (a *apexBundle) buildLintReports(ctx android.ModuleContext) {
depSetsBuilder := java.NewLintDepSetBuilder()
for _, fi := range a.filesInfo {
- depSetsBuilder.Transitive(fi.lintDepSets)
+ if fi.lintInfo != nil {
+ depSetsBuilder.Transitive(fi.lintInfo)
+ }
}
- a.lintReports = java.BuildModuleLintReportZips(ctx, depSetsBuilder.Build())
+ depSets := depSetsBuilder.Build()
+ var validations android.Paths
+
+ if a.checkStrictUpdatabilityLinting(ctx) {
+ baselines := depSets.Baseline.ToList()
+ if len(baselines) > 0 {
+ outputFile := java.VerifyStrictUpdatabilityChecks(ctx, baselines)
+ validations = append(validations, outputFile)
+ }
+ }
+
+ a.lintReports = java.BuildModuleLintReportZips(ctx, depSets, validations)
}
func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.OutputPath {
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index 9c2d899..f4da31e 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -409,6 +409,9 @@
// The fragments.
`com.android.art:art-bootclasspath-fragment`,
`myapex:my-bootclasspath-fragment`,
+
+ // Impl lib of sdk_library for transitive srcjar generation
+ `platform:foo.impl`,
})
}
@@ -565,6 +568,9 @@
// The fragments.
"myapex:mybootclasspath-fragment",
"myapex:prebuilt_mybootclasspath-fragment",
+
+ // Impl lib of sdk_library for transitive srcjar generation
+ "platform:foo.impl",
})
}
diff --git a/apex/vndk.go b/apex/vndk.go
index 3ececc5..5e630c0 100644
--- a/apex/vndk.go
+++ b/apex/vndk.go
@@ -20,6 +20,7 @@
"android/soong/android"
"android/soong/cc"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -66,7 +67,14 @@
vndkApexName := "com.android.vndk." + vndkVersion
if mctx.OtherModuleExists(vndkApexName) {
- mctx.AddReverseDependency(mctx.Module(), sharedLibTag, vndkApexName)
+ // Reverse dependencies must exactly specify the variant they want, starting from the
+ // current module's variant. But unlike cc modules, the vndk apex doesn't have
+ // arch/image/link variations, so we explicitly remove them here.
+ mctx.AddReverseVariationDependency([]blueprint.Variation{
+ {Mutator: "arch", Variation: "common"},
+ {Mutator: "image", Variation: ""},
+ {Mutator: "link", Variation: ""},
+ }, sharedLibTag, vndkApexName)
}
} else if a, ok := mctx.Module().(*apexBundle); ok && a.vndkApex {
if a.IsNativeBridgeSupported() {
diff --git a/bazel/configurability.go b/bazel/configurability.go
index 2c9a536..3a65614 100644
--- a/bazel/configurability.go
+++ b/bazel/configurability.go
@@ -100,9 +100,7 @@
// Copy of archFeatures from android/arch_list.go because the bazel
// package can't access the android package
archFeatures := map[string][]string{
- "arm": {
- "neon",
- },
+ "arm": {},
"arm64": {
"dotprod",
},
diff --git a/cc/cc.go b/cc/cc.go
index 96795d3..a8ff474 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -137,7 +137,7 @@
// LLNDK headers for the ABI checker to check LLNDK implementation library.
// An LLNDK implementation is the core variant. LLNDK header libs are reexported by the vendor variant.
- // The core variant cannot depend on the vendor variant because of the order of CreateVariations.
+ // The core variant cannot depend on the vendor variant because of the order of imageTransitionMutator.Split().
// Instead, the LLNDK implementation depends on the LLNDK header libs.
LlndkHeaderLibs []string
}
diff --git a/cc/check.go b/cc/check.go
index fa1926d..8e2844f 100644
--- a/cc/check.go
+++ b/cc/check.go
@@ -40,6 +40,8 @@
ctx.PropertyErrorf(prop, "Bad flag: `%s`, use native_coverage instead", flag)
} else if flag == "-fwhole-program-vtables" {
ctx.PropertyErrorf(prop, "Bad flag: `%s`, use whole_program_vtables instead", flag)
+ } else if flag == "-gsplit-dwarf" {
+ ctx.PropertyErrorf(prop, "Bad flag: `%s`, soong cannot track dependencies to split dwarf debuginfo", flag)
} else if flag == "-fno-integrated-as" {
ctx.PropertyErrorf("Bad flag: `%s` is disallowed as it may invoke the `as` from the build host", flag)
} else if flag == "-Weverything" {
diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go
index 5aa2a7e..e7ac038 100644
--- a/cc/config/x86_64_device.go
+++ b/cc/config/x86_64_device.go
@@ -40,6 +40,9 @@
"-march=x86-64",
},
+ "alderlake": []string{
+ "-march=alderlake",
+ },
"broadwell": []string{
"-march=broadwell",
},
diff --git a/cc/config/x86_device.go b/cc/config/x86_device.go
index 4b0041c..a92881d 100644
--- a/cc/config/x86_device.go
+++ b/cc/config/x86_device.go
@@ -42,6 +42,9 @@
"x86_64": []string{
"-march=prescott",
},
+ "alderlake": []string{
+ "-march=alderlake",
+ },
"atom": []string{
"-march=atom",
},
diff --git a/cc/generated_cc_library.go b/cc/generated_cc_library.go
index b1084e4..709586b 100644
--- a/cc/generated_cc_library.go
+++ b/cc/generated_cc_library.go
@@ -18,7 +18,7 @@
"android/soong/android"
)
-func GeneratedCcLibraryModuleFactory(moduleName string, callbacks Generator) android.Module {
+func GeneratedCcLibraryModuleFactory(callbacks Generator) android.Module {
module, _ := NewLibrary(android.HostAndDeviceSupported)
// Can be used as both a static and a shared library.
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 577c6cc..5b1ae54 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -375,6 +375,7 @@
ctx.Register()
finalOutputFile, ninjaDeps := runSoongOnlyBuild(ctx)
+ ninjaDeps = append(ninjaDeps, configuration.ProductVariablesFileName)
ninjaDeps = append(ninjaDeps, usedEnvFile)
if shared.IsDebugging() {
// Add a non-existent file to the dependencies so that soong_build will rerun when the debugger is
diff --git a/compliance/Android.bp b/compliance/Android.bp
index 08736b4..80f5685 100644
--- a/compliance/Android.bp
+++ b/compliance/Android.bp
@@ -34,6 +34,7 @@
name: "notice_xml_system",
partition_name: "system",
visibility: [
+ "//build/make/target/product/generic",
"//device/google/cuttlefish/system_image",
],
}
diff --git a/filesystem/aconfig_files.go b/filesystem/aconfig_files.go
index 5c047bc..8af2ffa 100644
--- a/filesystem/aconfig_files.go
+++ b/filesystem/aconfig_files.go
@@ -79,6 +79,7 @@
generatePartitionAconfigStorageFile("package_map", "package.map")
generatePartitionAconfigStorageFile("flag_map", "flag.map")
generatePartitionAconfigStorageFile("flag_val", "flag.val")
+ generatePartitionAconfigStorageFile("flag_info", "flag.info")
android.WriteExecutableFileRuleVerbatim(ctx, aconfigFlagsBuilderPath, sb.String())
}
diff --git a/genrule/Android.bp b/genrule/Android.bp
index f4197e6..49df480 100644
--- a/genrule/Android.bp
+++ b/genrule/Android.bp
@@ -25,3 +25,53 @@
// Used by plugins
visibility: ["//visibility:public"],
}
+
+genrule {
+ name: "nsjail_genrule_test_input",
+ cmd: "echo nsjail_genrule_test_input > $(out)",
+ out: ["nsjail_genrule_test_input.txt"],
+}
+
+// Pseudo-test that's run on checkbuilds to verify consistent directory
+// structure for genrules using sbox or nsjail.
+genrule_defaults {
+ name: "nsjail_genrule_test_gen_defaults",
+ // verify both relative paths and its contents
+ cmd: "(echo $(out) $(genDir) && sha256sum " +
+ "$(location get_clang_version) " +
+ "$(location py3-cmd) " +
+ "$(location genrule.go) " +
+ "$(location :nsjail_genrule_test_input) " +
+ "$(locations *.go)) | sed 's@\\./@@g' > $(out)",
+ tools: [
+ "get_clang_version", // random tool
+ "py3-cmd", // random prebuilt tool
+ ],
+ tool_files: ["genrule.go"], // random local file
+ srcs: [
+ ":nsjail_genrule_test_input", // random OutputFileProducer
+ "*.go", // random glob
+ ],
+ out: ["nsjail_genrule_test.txt"],
+}
+
+genrule {
+ name: "nsjail_genrule_test_gen_without_nsjail",
+ defaults: ["nsjail_genrule_test_gen_defaults"],
+}
+
+genrule {
+ name: "nsjail_genrule_test_gen_with_nsjail",
+ defaults: ["nsjail_genrule_test_gen_defaults"],
+ use_nsjail: true,
+}
+
+genrule {
+ name: "nsjail_genrule_test",
+ srcs: [
+ ":nsjail_genrule_test_gen_without_nsjail",
+ ":nsjail_genrule_test_gen_with_nsjail",
+ ],
+ cmd: "diff $(in) > $(out)",
+ out: ["nsjail_genrule_test"],
+}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index a48038b..e5222a4 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -21,6 +21,7 @@
import (
"fmt"
"io"
+ "path/filepath"
"strconv"
"strings"
@@ -210,6 +211,9 @@
// For gensrsc sharding.
shard int
shards int
+
+ // For nsjail tasks
+ useNsjail bool
}
func (g *Module) GeneratedSourceFiles() android.Paths {
@@ -313,16 +317,14 @@
if len(g.properties.Tools) > 0 {
seenTools := make(map[string]bool)
- ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
+ ctx.VisitDirectDepsAllowDisabled(func(module android.Module) {
switch tag := ctx.OtherModuleDependencyTag(module).(type) {
case hostToolDependencyTag:
tool := ctx.OtherModuleName(module)
- if m, ok := module.(android.Module); ok {
- // Necessary to retrieve any prebuilt replacement for the tool, since
- // toolDepsMutator runs too late for the prebuilt mutators to have
- // replaced the dependency.
- module = android.PrebuiltGetPreferred(ctx, m)
- }
+ // Necessary to retrieve any prebuilt replacement for the tool, since
+ // toolDepsMutator runs too late for the prebuilt mutators to have
+ // replaced the dependency.
+ module = android.PrebuiltGetPreferred(ctx, module)
switch t := module.(type) {
case android.HostToolProvider:
@@ -454,21 +456,26 @@
// Pick a unique path outside the task.genDir for the sbox manifest textproto,
// a unique rule name, and the user-visible description.
- manifestName := "genrule.sbox.textproto"
+ var rule *android.RuleBuilder
desc := "generate"
name := "generator"
- if task.shards > 0 {
- manifestName = "genrule_" + strconv.Itoa(task.shard) + ".sbox.textproto"
- desc += " " + strconv.Itoa(task.shard)
- name += strconv.Itoa(task.shard)
- } else if len(task.out) == 1 {
- desc += " " + task.out[0].Base()
+ if task.useNsjail {
+ rule = android.NewRuleBuilder(pctx, ctx).Nsjail(task.genDir, android.PathForModuleOut(ctx, "nsjail_build_sandbox"))
+ } else {
+ manifestName := "genrule.sbox.textproto"
+ if task.shards > 0 {
+ manifestName = "genrule_" + strconv.Itoa(task.shard) + ".sbox.textproto"
+ desc += " " + strconv.Itoa(task.shard)
+ name += strconv.Itoa(task.shard)
+ } else if len(task.out) == 1 {
+ desc += " " + task.out[0].Base()
+ }
+
+ manifestPath := android.PathForModuleOut(ctx, manifestName)
+
+ // Use a RuleBuilder to create a rule that runs the command inside an sbox sandbox.
+ rule = getSandboxedRuleBuilder(ctx, android.NewRuleBuilder(pctx, ctx).Sbox(task.genDir, manifestPath))
}
-
- manifestPath := android.PathForModuleOut(ctx, manifestName)
-
- // Use a RuleBuilder to create a rule that runs the command inside an sbox sandbox.
- rule := getSandboxedRuleBuilder(ctx, android.NewRuleBuilder(pctx, ctx).Sbox(task.genDir, manifestPath))
if Bool(g.properties.Write_if_changed) {
rule.Restat()
}
@@ -569,6 +576,15 @@
cmd.OrderOnly(ctx.Config().BuildNumberFile(ctx))
}
+ if task.useNsjail {
+ for _, input := range task.in {
+ // can fail if input is a file.
+ if paths, err := ctx.GlobWithDeps(filepath.Join(input.String(), "**/*"), nil); err == nil {
+ rule.NsjailImplicits(android.PathsForSource(ctx, paths))
+ }
+ }
+ }
+
// Create the rule to run the genrule command inside sbox.
rule.Build(name, desc)
@@ -832,15 +848,18 @@
properties := &genRuleProperties{}
taskGenerator := func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) []generateTask {
+ useNsjail := Bool(properties.Use_nsjail)
+
outs := make(android.WritablePaths, len(properties.Out))
for i, out := range properties.Out {
outs[i] = android.PathForModuleGen(ctx, out)
}
return []generateTask{{
- in: srcFiles,
- out: outs,
- genDir: android.PathForModuleGen(ctx),
- cmd: rawCommand,
+ in: srcFiles,
+ out: outs,
+ genDir: android.PathForModuleGen(ctx),
+ cmd: rawCommand,
+ useNsjail: useNsjail,
}}
}
@@ -855,6 +874,8 @@
}
type genRuleProperties struct {
+ Use_nsjail *bool
+
// names of the output files that will be generated
Out []string `android:"arch_variant"`
}
diff --git a/java/Android.bp b/java/Android.bp
index 926a294..1101d7a 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -72,7 +72,7 @@
"rro.go",
"sdk.go",
"sdk_library.go",
- "sdk_library_external.go",
+ "sdk_library_internal.go",
"support_libraries.go",
"system_modules.go",
"systemserver_classpath_fragment.go",
diff --git a/java/aar.go b/java/aar.go
index b5e24c4..7d73b03 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -45,7 +45,7 @@
ctx.RegisterModuleType("android_library_import", AARImportFactory)
ctx.RegisterModuleType("android_library", AndroidLibraryFactory)
ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator)
+ ctx.Transition("propagate_rro_enforcement", &propagateRROEnforcementTransitionMutator{})
})
}
@@ -151,15 +151,67 @@
path android.Path
}
-// Propagate RRO enforcement flag to static lib dependencies transitively.
-func propagateRROEnforcementMutator(ctx android.TopDownMutatorContext) {
+// Propagate RRO enforcement flag to static lib dependencies transitively. If EnforceRROGlobally is set then
+// all modules will use the "" variant. If specific modules have RRO enforced, then modules (usually apps) with
+// RRO enabled will use the "" variation for themselves, but use the "rro" variant of direct and transitive static
+// android_library dependencies.
+type propagateRROEnforcementTransitionMutator struct{}
+
+func (p propagateRROEnforcementTransitionMutator) Split(ctx android.BaseModuleContext) []string {
+ // Never split modules, apps with or without RRO enabled use the "" variant, static android_library dependencies
+ // will use create the "rro" variant from incoming tranisitons.
+ return []string{""}
+}
+
+func (p propagateRROEnforcementTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
+ // Non-static dependencies are not involved in RRO and always use the empty variant.
+ if ctx.DepTag() != staticLibTag {
+ return ""
+ }
+
m := ctx.Module()
- if d, ok := m.(AndroidLibraryDependency); ok && d.IsRROEnforced(ctx) {
- ctx.VisitDirectDepsWithTag(staticLibTag, func(d android.Module) {
- if a, ok := d.(AndroidLibraryDependency); ok {
- a.SetRROEnforcedForDependent(true)
- }
- })
+ if _, ok := m.(AndroidLibraryDependency); ok {
+ // If RRO is enforced globally don't bother using "rro" variants, the empty variant will have RRO enabled.
+ if ctx.Config().EnforceRROGlobally() {
+ return ""
+ }
+
+ // If RRO is enabled for this module use the "rro" variants of static dependencies. IncomingTransition will
+ // rewrite this back to "" if the dependency is not an android_library.
+ if ctx.Config().EnforceRROForModule(ctx.Module().Name()) {
+ return "rro"
+ }
+ }
+
+ return sourceVariation
+}
+
+func (p propagateRROEnforcementTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
+ // Propagate the "rro" variant to android_library modules, but use the empty variant for everything else.
+ if incomingVariation == "rro" {
+ m := ctx.Module()
+ if _, ok := m.(AndroidLibraryDependency); ok {
+ return "rro"
+ }
+ return ""
+ }
+
+ return ""
+}
+
+func (p propagateRROEnforcementTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
+ m := ctx.Module()
+ if d, ok := m.(AndroidLibraryDependency); ok {
+ if variation == "rro" {
+ // This is the "rro" variant of a module that has both variants, mark this one as RRO enabled and
+ // hide it from make to avoid collisions with the non-RRO empty variant.
+ d.SetRROEnforcedForDependent(true)
+ m.HideFromMake()
+ } else if ctx.Config().EnforceRROGlobally() {
+ // RRO is enabled globally, mark it enabled for this module, but there is only one variant so no
+ // need to hide it from make.
+ d.SetRROEnforcedForDependent(true)
+ }
}
}
diff --git a/java/androidmk.go b/java/androidmk.go
index a1bc904..0539d25 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -415,7 +415,7 @@
} else {
var names []string
for _, jniLib := range app.jniLibs {
- names = append(names, jniLib.name)
+ names = append(names, jniLib.name+":"+jniLib.target.Arch.ArchType.Bitness())
}
entries.AddStrings("LOCAL_REQUIRED_MODULES", names...)
}
diff --git a/java/androidmk_test.go b/java/androidmk_test.go
index 243a279..1d98b18 100644
--- a/java/androidmk_test.go
+++ b/java/androidmk_test.go
@@ -286,7 +286,7 @@
}{
{
name: "app",
- expected: []string{"libjni"},
+ expected: []string{"libjni:64"},
},
{
name: "app_embedded",
diff --git a/java/app.go b/java/app.go
index 4ac42a7..b77793b 100644
--- a/java/app.go
+++ b/java/app.go
@@ -1135,7 +1135,7 @@
return jniLibs, prebuiltJniPackages
}
-func (a *AndroidApp) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
+func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
ctx.WalkDeps(func(child, parent android.Module) bool {
isExternal := !a.DepIsInSameApex(ctx, child)
if am, ok := child.(android.ApexModule); ok {
@@ -1153,7 +1153,7 @@
}
depsInfo := android.DepNameToDepInfoMap{}
- a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
+ a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
depName := to.Name()
// Skip dependencies that are only available to APEXes; they are developed with updatability
@@ -1417,7 +1417,8 @@
}
testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
- a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config, configs)
+ a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites,
+ a.testProperties.Auto_gen_config, configs, a.testProperties.Test_options.Test_runner_options)
a.testConfig = a.FixTestConfig(ctx, testConfig)
a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
@@ -1781,16 +1782,15 @@
}
}
- // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
- // This will be restricted to optional_uses_libs
- if sdklib, ok := m.(SdkLibraryDependency); ok {
- if tag == usesLibOptTag && sdklib.DexJarBuildPath(ctx).PathOrNil() == nil {
- u.shouldDisableDexpreopt = true
- return
- }
- }
-
if lib, ok := m.(UsesLibraryDependency); ok {
+ if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
+ // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
+ // This will be restricted to optional_uses_libs
+ if tag == usesLibOptTag && lib.DexJarBuildPath(ctx).PathOrNil() == nil {
+ u.shouldDisableDexpreopt = true
+ return
+ }
+ }
libName := dep
if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
libName = *ulib.ProvidesUsesLib()
diff --git a/java/app_import.go b/java/app_import.go
index 045a89a..a54cf2f 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -533,10 +533,6 @@
return android.SdkSpecPrivate.ApiLevel
}
-func (a *AndroidAppImport) LintDepSets() LintDepSets {
- return LintDepSets{}
-}
-
var _ android.ApexModule = (*AndroidAppImport)(nil)
// Implements android.ApexModule
diff --git a/java/app_test.go b/java/app_test.go
index d7f5f0c..2a2611d 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1419,26 +1419,31 @@
}
func TestAndroidResourceOverlays(t *testing.T) {
+ type moduleAndVariant struct {
+ module string
+ variant string
+ }
+
testCases := []struct {
name string
enforceRROTargets []string
enforceRROExcludedOverlays []string
- resourceFiles map[string][]string
- overlayFiles map[string][]string
- rroDirs map[string][]string
+ resourceFiles map[moduleAndVariant][]string
+ overlayFiles map[moduleAndVariant][]string
+ rroDirs map[moduleAndVariant][]string
}{
{
name: "no RRO",
enforceRROTargets: nil,
enforceRROExcludedOverlays: nil,
- resourceFiles: map[string][]string{
- "foo": nil,
- "bar": {"bar/res/res/values/strings.xml"},
- "lib": nil,
- "lib2": {"lib2/res/res/values/strings.xml"},
+ resourceFiles: map[moduleAndVariant][]string{
+ {"foo", "android_common"}: nil,
+ {"bar", "android_common"}: {"bar/res/res/values/strings.xml"},
+ {"lib", "android_common"}: nil,
+ {"lib2", "android_common"}: {"lib2/res/res/values/strings.xml"},
},
- overlayFiles: map[string][]string{
- "foo": {
+ overlayFiles: map[moduleAndVariant][]string{
+ {"foo", "android_common"}: {
"out/soong/.intermediates/lib2/android_common/package-res.apk",
"out/soong/.intermediates/lib/android_common/package-res.apk",
"out/soong/.intermediates/lib3/android_common/package-res.apk",
@@ -1447,57 +1452,65 @@
"device/vendor/blah/overlay/foo/res/values/strings.xml",
"product/vendor/blah/overlay/foo/res/values/strings.xml",
},
- "bar": {
+ {"bar", "android_common"}: {
"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
"device/vendor/blah/overlay/bar/res/values/strings.xml",
},
- "lib": {
+ {"lib", "android_common"}: {
"out/soong/.intermediates/lib2/android_common/package-res.apk",
"lib/res/res/values/strings.xml",
"device/vendor/blah/overlay/lib/res/values/strings.xml",
},
},
- rroDirs: map[string][]string{
- "foo": nil,
- "bar": nil,
+ rroDirs: map[moduleAndVariant][]string{
+ {"foo", "android_common"}: nil,
+ {"bar", "android_common"}: nil,
},
},
{
name: "enforce RRO on foo",
enforceRROTargets: []string{"foo"},
enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
- resourceFiles: map[string][]string{
- "foo": nil,
- "bar": {"bar/res/res/values/strings.xml"},
- "lib": nil,
- "lib2": {"lib2/res/res/values/strings.xml"},
+ resourceFiles: map[moduleAndVariant][]string{
+ {"foo", "android_common"}: nil,
+ {"bar", "android_common"}: {"bar/res/res/values/strings.xml"},
+ {"lib", "android_common"}: nil,
+ {"lib", "android_common_rro"}: nil,
+ {"lib2", "android_common"}: {"lib2/res/res/values/strings.xml"},
+ {"lib2", "android_common_rro"}: {"lib2/res/res/values/strings.xml"},
},
- overlayFiles: map[string][]string{
- "foo": {
- "out/soong/.intermediates/lib2/android_common/package-res.apk",
- "out/soong/.intermediates/lib/android_common/package-res.apk",
- "out/soong/.intermediates/lib3/android_common/package-res.apk",
+ overlayFiles: map[moduleAndVariant][]string{
+ {"foo", "android_common"}: {
+ "out/soong/.intermediates/lib2/android_common_rro/package-res.apk",
+ "out/soong/.intermediates/lib/android_common_rro/package-res.apk",
+ "out/soong/.intermediates/lib3/android_common_rro/package-res.apk",
"foo/res/res/values/strings.xml",
"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
},
- "bar": {
+ {"bar", "android_common"}: {
"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
"device/vendor/blah/overlay/bar/res/values/strings.xml",
},
- "lib": {
+ {"lib", "android_common"}: {
"out/soong/.intermediates/lib2/android_common/package-res.apk",
"lib/res/res/values/strings.xml",
+ "device/vendor/blah/overlay/lib/res/values/strings.xml",
+ },
+ {"lib", "android_common_rro"}: {
+ "out/soong/.intermediates/lib2/android_common_rro/package-res.apk",
+ "lib/res/res/values/strings.xml",
},
},
- rroDirs: map[string][]string{
- "foo": {
+ rroDirs: map[moduleAndVariant][]string{
+ {"foo", "android_common"}: {
"device:device/vendor/blah/overlay/foo/res",
"product:product/vendor/blah/overlay/foo/res",
"device:device/vendor/blah/overlay/lib/res",
},
- "bar": nil,
- "lib": {"device:device/vendor/blah/overlay/lib/res"},
+ {"bar", "android_common"}: nil,
+ {"lib", "android_common"}: nil,
+ {"lib", "android_common_rro"}: {"device:device/vendor/blah/overlay/lib/res"},
},
},
{
@@ -1508,35 +1521,35 @@
"device/vendor/blah/static_overlay/foo",
"device/vendor/blah/static_overlay/bar/res",
},
- resourceFiles: map[string][]string{
- "foo": nil,
- "bar": {"bar/res/res/values/strings.xml"},
- "lib": nil,
- "lib2": {"lib2/res/res/values/strings.xml"},
+ resourceFiles: map[moduleAndVariant][]string{
+ {"foo", "android_common"}: nil,
+ {"bar", "android_common"}: {"bar/res/res/values/strings.xml"},
+ {"lib", "android_common"}: nil,
+ {"lib2", "android_common"}: {"lib2/res/res/values/strings.xml"},
},
- overlayFiles: map[string][]string{
- "foo": {
+ overlayFiles: map[moduleAndVariant][]string{
+ {"foo", "android_common"}: {
"out/soong/.intermediates/lib2/android_common/package-res.apk",
"out/soong/.intermediates/lib/android_common/package-res.apk",
"out/soong/.intermediates/lib3/android_common/package-res.apk",
"foo/res/res/values/strings.xml",
"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
},
- "bar": {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
- "lib": {
+ {"bar", "android_common"}: {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
+ {"lib", "android_common"}: {
"out/soong/.intermediates/lib2/android_common/package-res.apk",
"lib/res/res/values/strings.xml",
},
},
- rroDirs: map[string][]string{
- "foo": {
+ rroDirs: map[moduleAndVariant][]string{
+ {"foo", "android_common"}: {
"device:device/vendor/blah/overlay/foo/res",
"product:product/vendor/blah/overlay/foo/res",
// Lib dep comes after the direct deps
"device:device/vendor/blah/overlay/lib/res",
},
- "bar": {"device:device/vendor/blah/overlay/bar/res"},
- "lib": {"device:device/vendor/blah/overlay/lib/res"},
+ {"bar", "android_common"}: {"device:device/vendor/blah/overlay/bar/res"},
+ {"lib", "android_common"}: {"device:device/vendor/blah/overlay/lib/res"},
},
},
}
@@ -1621,19 +1634,19 @@
for _, o := range list {
res := module.MaybeOutput(o)
if res.Rule != nil {
- // If the overlay is compiled as part of this module (i.e. a .arsc.flat file),
+ // If the overlay is compiled as part of this moduleAndVariant (i.e. a .arsc.flat file),
// verify the inputs to the .arsc.flat rule.
files = append(files, res.Inputs.Strings()...)
} else {
- // Otherwise, verify the full path to the output of the other module
+ // Otherwise, verify the full path to the output of the other moduleAndVariant
files = append(files, o)
}
}
return files
}
- getResources := func(moduleName string) (resourceFiles, overlayFiles, rroDirs []string) {
- module := result.ModuleForTests(moduleName, "android_common")
+ getResources := func(moduleName, variantName string) (resourceFiles, overlayFiles, rroDirs []string) {
+ module := result.ModuleForTests(moduleName, variantName)
resourceList := module.MaybeOutput("aapt2/res.list")
if resourceList.Rule != nil {
resourceFiles = resourceListToFiles(module, android.PathsRelativeToTop(resourceList.Inputs))
@@ -1658,21 +1671,33 @@
return resourceFiles, overlayFiles, rroDirs
}
- modules := []string{"foo", "bar", "lib", "lib2"}
- for _, module := range modules {
- resourceFiles, overlayFiles, rroDirs := getResources(module)
+ modules := []moduleAndVariant{
+ {"foo", "android_common"},
+ {"foo", "android_common_rro"},
+ {"bar", "android_common"},
+ {"bar", "android_common_rro"},
+ {"lib", "android_common"},
+ {"lib", "android_common_rro"},
+ {"lib2", "android_common"},
+ {"lib2", "android_common_rro"},
+ }
+ for _, moduleAndVariant := range modules {
+ if _, exists := testCase.resourceFiles[moduleAndVariant]; !exists {
+ continue
+ }
+ resourceFiles, overlayFiles, rroDirs := getResources(moduleAndVariant.module, moduleAndVariant.variant)
- if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[module]) {
+ if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[moduleAndVariant]) {
t.Errorf("expected %s resource files:\n %#v\n got:\n %#v",
- module, testCase.resourceFiles[module], resourceFiles)
+ moduleAndVariant, testCase.resourceFiles[moduleAndVariant], resourceFiles)
}
- if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[module]) {
+ if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[moduleAndVariant]) {
t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v",
- module, testCase.overlayFiles[module], overlayFiles)
+ moduleAndVariant, testCase.overlayFiles[moduleAndVariant], overlayFiles)
}
- if !reflect.DeepEqual(rroDirs, testCase.rroDirs[module]) {
+ if !reflect.DeepEqual(rroDirs, testCase.rroDirs[moduleAndVariant]) {
t.Errorf("expected %s rroDirs: %#v\n got:\n %#v",
- module, testCase.rroDirs[module], rroDirs)
+ moduleAndVariant, testCase.rroDirs[moduleAndVariant], rroDirs)
}
}
})
diff --git a/java/base.go b/java/base.go
index b64eb5b..7c26cc3 100644
--- a/java/base.go
+++ b/java/base.go
@@ -708,9 +708,6 @@
ctx.SetOutputFiles(android.Paths{m.dexer.proguardDictionary.Path()}, ".proguard_map")
}
ctx.SetOutputFiles(m.properties.Generated_srcjars, ".generated_srcjars")
- if m.linter.outputs.xml != nil {
- ctx.SetOutputFiles(android.Paths{m.linter.outputs.xml}, ".lint")
- }
}
func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
@@ -854,33 +851,6 @@
// Add dependency on libraries that provide additional hidden api annotations.
ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...)
- if ctx.Config().EnforceInterPartitionJavaSdkLibrary() {
- // Require java_sdk_library at inter-partition java dependency to ensure stable
- // interface between partitions. If inter-partition java_library dependency is detected,
- // raise build error because java_library doesn't have a stable interface.
- //
- // Inputs:
- // PRODUCT_ENFORCE_INTER_PARTITION_JAVA_SDK_LIBRARY
- // if true, enable enforcement
- // PRODUCT_INTER_PARTITION_JAVA_LIBRARY_ALLOWLIST
- // exception list of java_library names to allow inter-partition dependency
- for idx := range j.properties.Libs {
- if libDeps[idx] == nil {
- continue
- }
-
- if javaDep, ok := libDeps[idx].(javaSdkLibraryEnforceContext); ok {
- // java_sdk_library is always allowed at inter-partition dependency.
- // So, skip check.
- if _, ok := javaDep.(*SdkLibrary); ok {
- continue
- }
-
- j.checkPartitionsForJavaDependency(ctx, "libs", javaDep)
- }
- }
- }
-
// For library dependencies that are component libraries (like stubs), add the implementation
// as a dependency (dexpreopt needs to be against the implementation library, not stubs).
for _, dep := range libDeps {
@@ -1736,8 +1706,12 @@
return
}
+ completeStaticLibsImplementationJarsToCombine := completeStaticLibsImplementationJars
+
if j.shouldInstrument(ctx) {
- outputFile = j.instrument(ctx, flags, outputFile, jarName, specs)
+ instrumentedOutputFile := j.instrument(ctx, flags, outputFile, jarName, specs)
+ completeStaticLibsImplementationJarsToCombine = android.NewDepSet(android.PREORDER, android.Paths{instrumentedOutputFile}, nil)
+ outputFile = instrumentedOutputFile
}
// merge implementation jar with resources if necessary
@@ -1745,7 +1719,7 @@
if ctx.Config().UseTransitiveJarsInClasspath() {
resourceJars := completeStaticLibsResourceJars.ToList()
if len(resourceJars) > 0 {
- implementationAndResourcesJarsToCombine = append(resourceJars, completeStaticLibsImplementationJars.ToList()...)
+ implementationAndResourcesJarsToCombine = append(resourceJars, completeStaticLibsImplementationJarsToCombine.ToList()...)
implementationAndResourcesJarsToCombine = append(implementationAndResourcesJarsToCombine, extraDepCombinedJars...)
}
} else {
@@ -2414,10 +2388,9 @@
return
}
- if _, ok := module.(SdkLibraryDependency); ok {
+ if sdkInfo, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
switch tag {
case sdkLibTag, libTag, staticLibTag:
- sdkInfo, _ := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider)
generatingLibsString := android.PrettyConcat(
getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or")
ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString)
@@ -2726,7 +2699,7 @@
module := ctx.Module()
moduleName := module.Name()
- ctx.VisitDirectDepsIgnoreBlueprint(func(m android.Module) {
+ ctx.VisitDirectDeps(func(m android.Module) {
tag := ctx.OtherModuleDependencyTag(m)
// This logic mirrors that in (*Module).collectDeps above. There are several places
// where we explicitly return RenameUseExclude, even though it is the default, to
@@ -2749,7 +2722,7 @@
if IsJniDepTag(tag) || tag == certificateTag || tag == proguardRaiseTag {
return RenameUseExclude, "tags"
}
- if _, ok := m.(SdkLibraryDependency); ok {
+ if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
switch tag {
case sdkLibTag, libTag:
return RenameUseExclude, "sdklibdep" // matches collectDeps()
diff --git a/java/dex.go b/java/dex.go
index e0e642c..faf51a3 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -220,14 +220,28 @@
deps = append(deps, f)
}
+ var requestReleaseMode bool
+ requestReleaseMode, flags = android.RemoveFromList("--release", flags)
+
if ctx.Config().Getenv("NO_OPTIMIZE_DX") != "" {
flags = append(flags, "--debug")
+ requestReleaseMode = false
}
if ctx.Config().Getenv("GENERATE_DEX_DEBUG") != "" {
flags = append(flags,
"--debug",
"--verbose")
+ requestReleaseMode = false
+ }
+
+ // Don't strip out debug information for eng builds, unless the target
+ // explicitly provided the `--release` build flag. This allows certain
+ // test targets to remain optimized as part of eng test_suites builds.
+ if requestReleaseMode {
+ flags = append(flags, "--release")
+ } else if ctx.Config().Eng() {
+ flags = append(flags, "--debug")
}
// Supplying the platform build flag disables various features like API modeling and desugaring.
@@ -384,11 +398,6 @@
// TODO(ccross): if this is an instrumentation test of an obfuscated app, use the
// dictionary of the app and move the app from libraryjars to injars.
- // Don't strip out debug information for eng builds.
- if ctx.Config().Eng() {
- r8Flags = append(r8Flags, "--debug")
- }
-
// TODO(b/180878971): missing classes should be added to the relevant builds.
// TODO(b/229727645): do not use true as default for Android platform builds.
if proptools.BoolDefault(opt.Ignore_warnings, true) {
diff --git a/java/dex_test.go b/java/dex_test.go
index 4862d06..8bc28e6 100644
--- a/java/dex_test.go
+++ b/java/dex_test.go
@@ -713,3 +713,97 @@
}
}`)
}
+
+func TestDebugReleaseFlags(t *testing.T) {
+ bp := `
+ android_app {
+ name: "app",
+ srcs: ["foo.java"],
+ platform_apis: true,
+ dxflags: ["%s"]
+ }
+ `
+
+ testcases := []struct {
+ name string
+ envVar string
+ isEng bool
+ dxFlags string
+ expectedFlags string
+ }{
+ {
+ name: "app_no_optimize_dx",
+ envVar: "NO_OPTIMIZE_DX",
+ expectedFlags: "--debug",
+ },
+ {
+ name: "app_release_no_optimize_dx",
+ envVar: "NO_OPTIMIZE_DX",
+ dxFlags: "--release",
+ // Global env vars override explicit dxflags.
+ expectedFlags: "--debug",
+ },
+ {
+ name: "app_generate_dex_debug",
+ envVar: "GENERATE_DEX_DEBUG",
+ expectedFlags: "--debug",
+ },
+ {
+ name: "app_release_generate_dex_debug",
+ envVar: "GENERATE_DEX_DEBUG",
+ dxFlags: "--release",
+ // Global env vars override explicit dxflags.
+ expectedFlags: "--debug",
+ },
+ {
+ name: "app_eng",
+ isEng: true,
+ expectedFlags: "--debug",
+ },
+ {
+ name: "app_release_eng",
+ isEng: true,
+ dxFlags: "--release",
+ // Eng mode does *not* override explicit dxflags.
+ expectedFlags: "--release",
+ },
+ }
+
+ for _, tc := range testcases {
+ t.Run(tc.name, func(t *testing.T) {
+ fixturePreparer := PrepareForTestWithJavaDefaultModules
+ fixturePreparer = android.GroupFixturePreparers(
+ fixturePreparer,
+ android.FixtureModifyProductVariables(
+ func(variables android.FixtureProductVariables) {
+ variables.Eng = proptools.BoolPtr(tc.isEng)
+ },
+ ),
+ )
+ if tc.envVar != "" {
+ fixturePreparer = android.GroupFixturePreparers(
+ fixturePreparer,
+ android.FixtureMergeEnv(map[string]string{
+ tc.envVar: "true",
+ }),
+ )
+ }
+ result := fixturePreparer.RunTestWithBp(t, fmt.Sprintf(bp, tc.dxFlags))
+
+ appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
+ android.AssertStringDoesContain(t, "expected flag in R8 flags",
+ appR8.Args["r8Flags"], tc.expectedFlags)
+
+ var unexpectedFlags string
+ if tc.expectedFlags == "--debug" {
+ unexpectedFlags = "--release"
+ } else if tc.expectedFlags == "--release" {
+ unexpectedFlags = "--debug"
+ }
+ if unexpectedFlags != "" {
+ android.AssertStringDoesNotContain(t, "unexpected flag in R8 flags",
+ appR8.Args["r8Flags"], unexpectedFlags)
+ }
+ })
+ }
+}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index a2e4734..7a77b15 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -463,6 +463,7 @@
func RegisterDexpreoptBootJarsComponents(ctx android.RegistrationContext) {
ctx.RegisterParallelSingletonModuleType("dex_bootjars", dexpreoptBootJarsFactory)
+ ctx.RegisterModuleType("art_boot_images", artBootImagesFactory)
ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("dex_bootjars_deps", DexpreoptBootJarsMutator).Parallel()
})
@@ -601,6 +602,7 @@
d.defaultBootImage = defaultBootImageConfig(ctx)
d.otherImages = make([]*bootImageConfig, 0, len(imageConfigs)-1)
var profileInstalls android.RuleBuilderInstalls
+ var artBootImageHostInstalls android.RuleBuilderInstalls
for _, name := range getImageNames() {
config := imageConfigs[name]
if config != d.defaultBootImage {
@@ -616,6 +618,18 @@
d.bootFrameworkProfile = bootProfile
profileInstalls = append(profileInstalls, installs...)
}
+ // Gather the install files of the host variant of the ART boot image.
+ // These installed files will be used in ART tests.
+ if config.name == "art" {
+ for _, variant := range config.variants {
+ if variant.target.Os != ctx.Config().BuildOS {
+ // not a host variant
+ continue
+ }
+ artBootImageHostInstalls = append(artBootImageHostInstalls, variant.installs...)
+ artBootImageHostInstalls = append(artBootImageHostInstalls, variant.vdexInstalls...)
+ }
+ }
}
if len(profileInstalls) > 0 {
android.SetProvider(ctx, profileInstallInfoProvider, profileInstallInfo{
@@ -626,6 +640,15 @@
installFile(ctx, install)
}
}
+ // Set a provider containing the install files of the host variant of the ART boot image.
+ // The actual install rules will be created by `art_boot_images`
+ android.SetProvider(
+ ctx,
+ artBootImageHostInfoProvider,
+ artBootImageHostInfo{
+ installs: artBootImageHostInstalls,
+ },
+ )
}
// GenerateSingletonBuildActions generates build rules for the dexpreopt config for Make.
@@ -968,6 +991,14 @@
}
}
+var artBootImageHostInfoProvider = blueprint.NewProvider[artBootImageHostInfo]()
+
+// artBootImageHostInfo contains the install locations of the host variant of ART boot image
+// this contains both the primary and secondary arch locations
+type artBootImageHostInfo struct {
+ installs android.RuleBuilderInstalls
+}
+
// Generate boot image build rules for a specific target.
func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, profile android.Path) bootImageVariantOutputs {
@@ -1344,18 +1375,7 @@
}
image := d.defaultBootImage
- if image != nil {
- if profileInstallInfo, ok := android.OtherModuleProvider(ctx, d, profileInstallInfoProvider); ok {
- ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", profileInstallInfo.profileInstalls.String())
- if profileInstallInfo.profileLicenseMetadataFile.Valid() {
- ctx.Strict("DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA", profileInstallInfo.profileLicenseMetadataFile.String())
- }
- }
-
- if SkipDexpreoptBootJars(ctx) {
- return
- }
-
+ if image != nil && !SkipDexpreoptBootJars(ctx) {
global := dexpreopt.GetGlobalConfig(ctx)
dexPaths, dexLocations := bcpForDexpreopt(ctx, global.PreoptWithUpdatableBcp)
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(dexPaths.Strings(), " "))
@@ -1396,3 +1416,70 @@
OutputFile: android.OptionalPathForPath(d.bootFrameworkProfile),
}}
}
+
+// artBootImages is a thin wrapper around `dex_bootjars`.
+// it creates the installation rules for the host variant of the ART boot image.
+type artBootImages struct {
+ android.ModuleBase
+
+ // A non-empty file that will be written as `LOCAL_SOONG_INSTALLED_MODULE` in out/soong/Android-*.mk
+ outputFile android.OptionalPath
+}
+
+func artBootImagesFactory() android.Module {
+ m := &artBootImages{}
+ android.InitAndroidMultiTargetsArchModule(m, android.HostSupported, android.MultilibCommon)
+ return m
+}
+
+func (dbj *artBootImages) DepsMutator(ctx android.BottomUpMutatorContext) {
+ // Create a dependency on `dex_bootjars` to access the intermediate locations of host art boot image.
+ ctx.AddDependency(ctx.Module(), dexpreoptBootJarDepTag, "dex_bootjars")
+}
+
+func (d *artBootImages) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ ctx.VisitDirectDepsWithTag(dexpreoptBootJarDepTag, func(m android.Module) {
+ hostInstallsInfo, ok := android.OtherModuleProvider(ctx, m, artBootImageHostInfoProvider)
+ if !ok {
+ ctx.ModuleErrorf("Could not find information about the host variant of ART boot image")
+ }
+ installs := d.installFile(ctx, hostInstallsInfo.installs)
+ if len(installs) > 0 {
+ d.outputFile = android.OptionalPathForPath(installs[0])
+ // Create a phony target that can ART run-tests can depend on.
+ ctx.Phony(d.Name(), installs...)
+ } else {
+ // this might be true e.g. when building with `WITH_DEXPREOPT=false`
+ // create an empty file so that the `art_boot_images` is known to the packaging system.
+ d.outputFile = android.OptionalPathForPath(android.PathForModuleOut(ctx, "undefined_art_boot_images"))
+ }
+ })
+}
+
+// Creates an installation rule for host variant of ART boot image files.
+// Returns the list of install locations (out/host/linux-x86/...)
+func (d *artBootImages) installFile(ctx android.ModuleContext, ruleBuilderInstalls android.RuleBuilderInstalls) android.Paths {
+ var ret android.Paths
+ for _, ruleBuilderInstall := range ruleBuilderInstalls {
+ installDir := android.PathForModuleInstall(
+ ctx,
+ strings.TrimPrefix(filepath.Dir(ruleBuilderInstall.To), "/"),
+ )
+ filename := filepath.Base(ruleBuilderInstall.To)
+ ctx.InstallFile(
+ installDir,
+ filename,
+ ruleBuilderInstall.From,
+ )
+ ret = append(ret, installDir.Join(ctx, filename))
+ }
+ return ret
+}
+
+// Set `OutputFile` expclitly so that this module does not get elided when generating out/soong/Android-*.mk
+func (d *artBootImages) AndroidMkEntries() []android.AndroidMkEntries {
+ return []android.AndroidMkEntries{{
+ Class: "ETC",
+ OutputFile: d.outputFile,
+ }}
+}
diff --git a/java/dexpreopt_config_testing.go b/java/dexpreopt_config_testing.go
index 37c54b9..33c682b 100644
--- a/java/dexpreopt_config_testing.go
+++ b/java/dexpreopt_config_testing.go
@@ -1335,8 +1335,6 @@
DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTboot=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/boot.art
DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTmainline=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/boot.art:out/soong/dexpreopt_arm64/dex_mainlinejars/android/system/framework/boot-framework-foo.art
DEXPREOPT_IMAGE_NAMES=art boot mainline
-DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED=out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof:/system/etc/boot-image.prof out/soong/dexpreopt_arm64/dex_bootjars/boot.bprof:/system/etc/boot-image.bprof
-DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-extra1.oat:/apex/art_boot_images/javalib/arm/boot-extra1.oat
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-extra1.oat:/apex/art_boot_images/javalib/arm64/boot-extra1.oat
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.oat:/apex/art_boot_images/javalib/x86/boot-extra1.oat
diff --git a/java/droiddoc.go b/java/droiddoc.go
index a7e92d9..2980d91 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -373,8 +373,7 @@
panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
}
case libTag, sdkLibTag:
- if _, ok := module.(SdkLibraryDependency); ok {
- sdkInfo, _ := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider)
+ if sdkInfo, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
generatingLibsString := android.PrettyConcat(
getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or")
ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString)
diff --git a/java/fuzz.go b/java/fuzz.go
index d37c558..e5f1f04 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -85,10 +85,11 @@
func (j *JavaFuzzTest) DepsMutator(ctx android.BottomUpMutatorContext) {
if j.Os().Class.String() == deviceString {
- j.testProperties.Jni_libs = append(j.testProperties.Jni_libs, artDeps...)
+ j.testProperties.Jni_libs.AppendSimpleValue(artDeps)
}
- if len(j.testProperties.Jni_libs) > 0 {
+ jniLibs := j.testProperties.Jni_libs.GetOrDefault(ctx, nil)
+ if len(jniLibs) > 0 {
if j.fuzzPackagedModule.FuzzProperties.Fuzz_config == nil {
config := &fuzz.FuzzConfig{}
j.fuzzPackagedModule.FuzzProperties.Fuzz_config = config
@@ -98,7 +99,7 @@
j.fuzzPackagedModule.FuzzProperties.Fuzz_config.IsJni = proptools.BoolPtr(true)
for _, target := range ctx.MultiTargets() {
sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
- ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, j.testProperties.Jni_libs...)
+ ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, jniLibs...)
}
}
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index 4144de8..3650058 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -298,13 +298,12 @@
// available, or reports an error.
func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module, kind android.SdkKind) android.Path {
var dexJar OptionalDexJarPath
- if sdkLibrary, ok := module.(SdkLibraryDependency); ok {
+ if sdkLibrary, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
if ctx.Config().ReleaseHiddenApiExportableStubs() {
- dexJar = sdkLibrary.SdkApiExportableStubDexJar(ctx, kind)
+ dexJar = sdkLibrary.ExportableStubDexJarPaths[kind]
} else {
- dexJar = sdkLibrary.SdkApiStubDexJar(ctx, kind)
+ dexJar = sdkLibrary.EverythingStubDexJarPaths[kind]
}
-
} else if j, ok := module.(UsesLibraryDependency); ok {
dexJar = j.DexJarBuildPath(ctx)
} else {
@@ -853,15 +852,15 @@
i.StubDexJarsByScope.addStubDexJar(ctx, module, apiScope, dexJar)
}
- if sdkLibrary, ok := module.(SdkLibraryDependency); ok {
- removedTxtFile := sdkLibrary.SdkRemovedTxtFile(ctx, sdkKind)
+ if sdkLibrary, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
+ removedTxtFile := sdkLibrary.RemovedTxtFiles[sdkKind]
i.RemovedTxtFiles = append(i.RemovedTxtFiles, removedTxtFile.AsPaths()...)
}
}
// If the contents includes any java_sdk_library modules then add them to the stubs.
for _, module := range contents {
- if _, ok := module.(SdkLibraryDependency); ok {
+ if _, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
// Add information for every possible API scope needed by hidden API.
for _, apiScope := range hiddenAPISdkLibrarySupportedScopes {
addFromModule(ctx, module, apiScope)
diff --git a/java/java.go b/java/java.go
index 91c4d6d..661422b 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1301,7 +1301,7 @@
Test_options TestOptions
// Names of modules containing JNI libraries that should be installed alongside the test.
- Jni_libs []string
+ Jni_libs proptools.Configurable[[]string]
// Install the test into a folder named for the module in all test suites.
Per_testcase_directory *bool
@@ -1485,10 +1485,11 @@
}
}
- if len(j.testProperties.Jni_libs) > 0 {
+ jniLibs := j.testProperties.Jni_libs.GetOrDefault(ctx, nil)
+ if len(jniLibs) > 0 {
for _, target := range ctx.MultiTargets() {
sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
- ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, j.testProperties.Jni_libs...)
+ ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, jniLibs...)
}
}
@@ -2612,17 +2613,6 @@
return nil
}
-func (j *Import) LintDepSets() LintDepSets {
- return LintDepSets{}
-}
-
-func (j *Import) getStrictUpdatabilityLinting() bool {
- return false
-}
-
-func (j *Import) setStrictUpdatabilityLinting(bool) {
-}
-
func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs.GetOrDefault(ctx, nil)...)
@@ -2700,7 +2690,7 @@
transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
}
}
- } else if _, ok := module.(SdkLibraryDependency); ok {
+ } else if _, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
switch tag {
case libTag, sdkLibTag:
sdkInfo, _ := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider)
@@ -3098,21 +3088,10 @@
return nil
}
-func (a *DexImport) LintDepSets() LintDepSets {
- return LintDepSets{}
-}
-
func (j *DexImport) IsInstallable() bool {
return true
}
-func (j *DexImport) getStrictUpdatabilityLinting() bool {
- return false
-}
-
-func (j *DexImport) setStrictUpdatabilityLinting(bool) {
-}
-
func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if len(j.properties.Jars) != 1 {
ctx.PropertyErrorf("jars", "exactly one jar must be provided")
@@ -3315,7 +3294,7 @@
depName := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(depModule))
var sdkLib *string
- if lib, ok := depModule.(SdkLibraryDependency); ok && lib.sharedLibrary() {
+ if lib, ok := android.OtherModuleProvider(ctx, depModule, SdkLibraryInfoProvider); ok && lib.SharedLibrary {
// A shared SDK library. This should be added as a top-level CLC element.
sdkLib = &depName
} else if lib, ok := depModule.(SdkLibraryComponentDependency); ok && lib.OptionalSdkLibraryImplementation() != nil {
diff --git a/java/java_test.go b/java/java_test.go
index e0fd0f2..e976b08 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -3065,6 +3065,43 @@
"baz.jar", bazOutputPaths[0].Rel())
}
+func TestCoverage(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ prepareForTestWithFrameworkJacocoInstrumentation,
+ PrepareForTestWithTransitiveClasspathEnabled,
+ ).RunTestWithBp(t, `
+ android_app {
+ name: "foo",
+ srcs: ["foo.java"],
+ static_libs: ["android.car"],
+ platform_apis: true,
+ }
+
+ // A library in InstrumentFrameworkModules
+ java_library {
+ name: "android.car",
+ srcs: ["android.car.java"],
+ }
+ `)
+
+ foo := result.ModuleForTests("foo", "android_common")
+ androidCar := result.ModuleForTests("android.car", "android_common")
+
+ fooJacoco := foo.Rule("jacoco")
+ fooCombine := foo.Description("for javac")
+
+ androidCarJacoco := androidCar.Rule("jacoco")
+ androidCarJavac := androidCar.Rule("javac")
+
+ android.AssertStringEquals(t, "foo instrumentation rule inputs", fooJacoco.Input.String(), fooCombine.Output.String())
+ android.AssertStringEquals(t, "android.car instrumentation rule inputs", androidCarJacoco.Input.String(), androidCarJavac.Output.String())
+
+ // The input to instrumentation for the `foo` app contains the non-instrumented android.car classes.
+ android.AssertStringListContains(t, "foo combined inputs", fooCombine.Inputs.Strings(), androidCarJavac.Output.String())
+ android.AssertStringListDoesNotContain(t, "foo combined inputs", fooCombine.Inputs.Strings(), androidCarJacoco.Output.String())
+}
+
func assertTestOnlyAndTopLevel(t *testing.T, ctx *android.TestResult, expectedTestOnly []string, expectedTopLevel []string) {
t.Helper()
actualTrueModules := []string{}
@@ -3095,3 +3132,37 @@
t.Errorf("top-level: Expected but not found: %v, Found but not expected: %v", left, right)
}
}
+
+// Test that a dependency edge is created to the "first" variant of a native library listed in `required` of java_binary
+func TestNativeRequiredDepOfJavaBinary(t *testing.T) {
+ findDepsOfModule := func(ctx *android.TestContext, module android.Module, depName string) []blueprint.Module {
+ var ret []blueprint.Module
+ ctx.VisitDirectDeps(module, func(dep blueprint.Module) {
+ if dep.Name() == depName {
+ ret = append(ret, dep)
+ }
+ })
+ return ret
+ }
+
+ bp := cc.GatherRequiredDepsForTest(android.Android) + `
+java_binary {
+ name: "myjavabin",
+ main_class: "com.android.MyJava",
+ required: ["mynativelib"],
+}
+cc_library_shared {
+ name: "mynativelib",
+}
+`
+ res, _ := testJava(t, bp)
+ // The first variant installs the native library via the common variant, so check the deps of both variants.
+ nativeVariantDepsWithDups := findDepsOfModule(res, res.ModuleForTests("myjavabin", "android_arm64_armv8-a").Module(), "mynativelib")
+ nativeVariantDepsWithDups = append(nativeVariantDepsWithDups, findDepsOfModule(res, res.ModuleForTests("myjavabin", "android_common").Module(), "mynativelib")...)
+
+ nativeVariantDepsUnique := map[blueprint.Module]bool{}
+ for _, dep := range nativeVariantDepsWithDups {
+ nativeVariantDepsUnique[dep] = true
+ }
+ android.AssertIntEquals(t, "Create a dep on the first variant", 1, len(nativeVariantDepsUnique))
+}
diff --git a/java/lint.go b/java/lint.go
index 6782adc..2cbefc3 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -19,6 +19,7 @@
"sort"
"strings"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -90,7 +91,6 @@
compileSdkKind android.SdkKind
javaLanguageLevel string
kotlinLanguageLevel string
- outputs lintOutputs
properties LintProperties
extraMainlineLintErrors []string
compile_data android.Paths
@@ -100,68 +100,55 @@
buildModuleReportZip bool
}
-type lintOutputs struct {
- html android.Path
- text android.Path
- xml android.Path
- referenceBaseline android.Path
-
- depSets LintDepSets
-}
-
-type lintOutputsIntf interface {
- lintOutputs() *lintOutputs
-}
-
-type LintDepSetsIntf interface {
- LintDepSets() LintDepSets
-
- // Methods used to propagate strict_updatability_linting values.
- GetStrictUpdatabilityLinting() bool
- SetStrictUpdatabilityLinting(bool)
-}
-
type LintDepSets struct {
- HTML, Text, XML *android.DepSet[android.Path]
+ HTML, Text, XML, Baseline *android.DepSet[android.Path]
}
type LintDepSetsBuilder struct {
- HTML, Text, XML *android.DepSetBuilder[android.Path]
+ HTML, Text, XML, Baseline *android.DepSetBuilder[android.Path]
}
func NewLintDepSetBuilder() LintDepSetsBuilder {
return LintDepSetsBuilder{
- HTML: android.NewDepSetBuilder[android.Path](android.POSTORDER),
- Text: android.NewDepSetBuilder[android.Path](android.POSTORDER),
- XML: android.NewDepSetBuilder[android.Path](android.POSTORDER),
+ HTML: android.NewDepSetBuilder[android.Path](android.POSTORDER),
+ Text: android.NewDepSetBuilder[android.Path](android.POSTORDER),
+ XML: android.NewDepSetBuilder[android.Path](android.POSTORDER),
+ Baseline: android.NewDepSetBuilder[android.Path](android.POSTORDER),
}
}
-func (l LintDepSetsBuilder) Direct(html, text, xml android.Path) LintDepSetsBuilder {
+func (l LintDepSetsBuilder) Direct(html, text, xml android.Path, baseline android.OptionalPath) LintDepSetsBuilder {
l.HTML.Direct(html)
l.Text.Direct(text)
l.XML.Direct(xml)
+ if baseline.Valid() {
+ l.Baseline.Direct(baseline.Path())
+ }
return l
}
-func (l LintDepSetsBuilder) Transitive(depSets LintDepSets) LintDepSetsBuilder {
- if depSets.HTML != nil {
- l.HTML.Transitive(depSets.HTML)
+func (l LintDepSetsBuilder) Transitive(info *LintInfo) LintDepSetsBuilder {
+ if info.TransitiveHTML != nil {
+ l.HTML.Transitive(info.TransitiveHTML)
}
- if depSets.Text != nil {
- l.Text.Transitive(depSets.Text)
+ if info.TransitiveText != nil {
+ l.Text.Transitive(info.TransitiveText)
}
- if depSets.XML != nil {
- l.XML.Transitive(depSets.XML)
+ if info.TransitiveXML != nil {
+ l.XML.Transitive(info.TransitiveXML)
+ }
+ if info.TransitiveBaseline != nil {
+ l.Baseline.Transitive(info.TransitiveBaseline)
}
return l
}
func (l LintDepSetsBuilder) Build() LintDepSets {
return LintDepSets{
- HTML: l.HTML.Build(),
- Text: l.Text.Build(),
- XML: l.XML.Build(),
+ HTML: l.HTML.Build(),
+ Text: l.Text.Build(),
+ XML: l.XML.Build(),
+ Baseline: l.Baseline.Build(),
}
}
@@ -209,24 +196,18 @@
},
}
-func (l *linter) LintDepSets() LintDepSets {
- return l.outputs.depSets
-}
+var LintProvider = blueprint.NewProvider[*LintInfo]()
-func (l *linter) GetStrictUpdatabilityLinting() bool {
- return BoolDefault(l.properties.Lint.Strict_updatability_linting, false)
-}
+type LintInfo struct {
+ HTML android.Path
+ Text android.Path
+ XML android.Path
+ ReferenceBaseline android.Path
-func (l *linter) SetStrictUpdatabilityLinting(strictLinting bool) {
- l.properties.Lint.Strict_updatability_linting = &strictLinting
-}
-
-var _ LintDepSetsIntf = (*linter)(nil)
-
-var _ lintOutputsIntf = (*linter)(nil)
-
-func (l *linter) lintOutputs() *lintOutputs {
- return &l.outputs
+ TransitiveHTML *android.DepSet[android.Path]
+ TransitiveText *android.DepSet[android.Path]
+ TransitiveXML *android.DepSet[android.Path]
+ TransitiveBaseline *android.DepSet[android.Path]
}
func (l *linter) enabled() bool {
@@ -262,7 +243,9 @@
return ctx.Config().GetenvWithDefault("RBE_LINT_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
}
-func (l *linter) writeLintProjectXML(ctx android.ModuleContext, rule *android.RuleBuilder, srcsList android.Path) lintPaths {
+func (l *linter) writeLintProjectXML(ctx android.ModuleContext, rule *android.RuleBuilder, srcsList android.Path,
+ baselines android.Paths) lintPaths {
+
projectXMLPath := android.PathForModuleOut(ctx, "lint", "project.xml")
// Lint looks for a lint.xml file next to the project.xml file, give it one.
configXMLPath := android.PathForModuleOut(ctx, "lint", "lint.xml")
@@ -325,12 +308,10 @@
cmd.FlagForEachArg("--error_check ", l.properties.Lint.Error_checks)
cmd.FlagForEachArg("--fatal_check ", l.properties.Lint.Fatal_checks)
- if l.GetStrictUpdatabilityLinting() {
+ if Bool(l.properties.Lint.Strict_updatability_linting) && len(baselines) > 0 {
// Verify the module does not baseline issues that endanger safe updatability.
- if l.properties.Lint.Baseline_filename != nil {
- cmd.FlagWithInput("--baseline ", android.PathForModuleSrc(ctx, *l.properties.Lint.Baseline_filename))
- cmd.FlagForEachArg("--disallowed_issues ", updatabilityChecks)
- }
+ strictUpdatabilityChecksOutputFile := VerifyStrictUpdatabilityChecks(ctx, baselines)
+ cmd.Validation(strictUpdatabilityChecksOutputFile)
}
return lintPaths{
@@ -342,6 +323,22 @@
}
+func VerifyStrictUpdatabilityChecks(ctx android.ModuleContext, baselines android.Paths) android.Path {
+ rule := android.NewRuleBuilder(pctx, ctx)
+ baselineRspFile := android.PathForModuleOut(ctx, "lint_strict_updatability_check_baselines.rsp")
+ outputFile := android.PathForModuleOut(ctx, "lint_strict_updatability_check.stamp")
+ rule.Command().Text("rm -f").Output(outputFile)
+ rule.Command().
+ BuiltTool("lint_strict_updatability_checks").
+ FlagWithArg("--name ", ctx.ModuleName()).
+ FlagWithRspFileInputList("--baselines ", baselineRspFile, baselines).
+ FlagForEachArg("--disallowed_issues ", updatabilityChecks)
+ rule.Command().Text("touch").Output(outputFile)
+ rule.Build("lint_strict_updatability_checks", "lint strict updatability checks")
+
+ return outputFile
+}
+
// generateManifest adds a command to the rule to write a simple manifest that contains the
// minSdkVersion and targetSdkVersion for modules (like java_library) that don't have a manifest.
func (l *linter) generateManifest(ctx android.ModuleContext, rule *android.RuleBuilder) android.WritablePath {
@@ -411,6 +408,26 @@
l.extraLintCheckJars = append(l.extraLintCheckJars, android.PathForSource(ctx,
"prebuilts/cmdline-tools/AndroidGlobalLintChecker.jar"))
+ var baseline android.OptionalPath
+ if l.properties.Lint.Baseline_filename != nil {
+ baseline = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *l.properties.Lint.Baseline_filename))
+ }
+
+ html := android.PathForModuleOut(ctx, "lint", "lint-report.html")
+ text := android.PathForModuleOut(ctx, "lint", "lint-report.txt")
+ xml := android.PathForModuleOut(ctx, "lint", "lint-report.xml")
+ referenceBaseline := android.PathForModuleOut(ctx, "lint", "lint-baseline.xml")
+
+ depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml, baseline)
+
+ ctx.VisitDirectDepsWithTag(staticLibTag, func(dep android.Module) {
+ if info, ok := android.OtherModuleProvider(ctx, dep, LintProvider); ok {
+ depSetsBuilder.Transitive(info)
+ }
+ })
+
+ depSets := depSetsBuilder.Build()
+
rule := android.NewRuleBuilder(pctx, ctx).
Sbox(android.PathForModuleOut(ctx, "lint"),
android.PathForModuleOut(ctx, "lint.sbox.textproto")).
@@ -437,20 +454,9 @@
srcsListRsp := android.PathForModuleOut(ctx, "lint-srcs.list.rsp")
rule.Command().Text("cp").FlagWithRspFileInputList("", srcsListRsp, l.srcs).Output(srcsList).Implicits(l.compile_data)
- lintPaths := l.writeLintProjectXML(ctx, rule, srcsList)
+ baselines := depSets.Baseline.ToList()
- html := android.PathForModuleOut(ctx, "lint", "lint-report.html")
- text := android.PathForModuleOut(ctx, "lint", "lint-report.txt")
- xml := android.PathForModuleOut(ctx, "lint", "lint-report.xml")
- referenceBaseline := android.PathForModuleOut(ctx, "lint", "lint-baseline.xml")
-
- depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml)
-
- ctx.VisitDirectDepsWithTag(staticLibTag, func(dep android.Module) {
- if depLint, ok := dep.(LintDepSetsIntf); ok {
- depSetsBuilder.Transitive(depLint.LintDepSets())
- }
- })
+ lintPaths := l.writeLintProjectXML(ctx, rule, srcsList, baselines)
rule.Command().Text("rm -rf").Flag(lintPaths.cacheDir.String()).Flag(lintPaths.homeDir.String())
rule.Command().Text("mkdir -p").Flag(lintPaths.cacheDir.String()).Flag(lintPaths.homeDir.String())
@@ -505,8 +511,8 @@
cmd.FlagWithArg("--check ", checkOnly)
}
- if l.properties.Lint.Baseline_filename != nil {
- cmd.FlagWithInput("--baseline ", android.PathForModuleSrc(ctx, *l.properties.Lint.Baseline_filename))
+ if baseline.Valid() {
+ cmd.FlagWithInput("--baseline ", baseline.Path())
}
cmd.FlagWithOutput("--write-reference-baseline ", referenceBaseline)
@@ -530,25 +536,30 @@
rule.Build("lint", "lint")
- l.outputs = lintOutputs{
- html: html,
- text: text,
- xml: xml,
- referenceBaseline: referenceBaseline,
+ android.SetProvider(ctx, LintProvider, &LintInfo{
+ HTML: html,
+ Text: text,
+ XML: xml,
+ ReferenceBaseline: referenceBaseline,
- depSets: depSetsBuilder.Build(),
- }
+ TransitiveHTML: depSets.HTML,
+ TransitiveText: depSets.Text,
+ TransitiveXML: depSets.XML,
+ TransitiveBaseline: depSets.Baseline,
+ })
if l.buildModuleReportZip {
- l.reports = BuildModuleLintReportZips(ctx, l.LintDepSets())
+ l.reports = BuildModuleLintReportZips(ctx, depSets, nil)
}
// Create a per-module phony target to run the lint check.
phonyName := ctx.ModuleName() + "-lint"
ctx.Phony(phonyName, xml)
+
+ ctx.SetOutputFiles(android.Paths{xml}, ".lint")
}
-func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets) android.Paths {
+func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets, validations android.Paths) android.Paths {
htmlList := android.SortedUniquePaths(depSets.HTML.ToList())
textList := android.SortedUniquePaths(depSets.Text.ToList())
xmlList := android.SortedUniquePaths(depSets.XML.ToList())
@@ -558,13 +569,13 @@
}
htmlZip := android.PathForModuleOut(ctx, "lint-report-html.zip")
- lintZip(ctx, htmlList, htmlZip)
+ lintZip(ctx, htmlList, htmlZip, validations)
textZip := android.PathForModuleOut(ctx, "lint-report-text.zip")
- lintZip(ctx, textList, textZip)
+ lintZip(ctx, textList, textZip, validations)
xmlZip := android.PathForModuleOut(ctx, "lint-report-xml.zip")
- lintZip(ctx, xmlList, xmlZip)
+ lintZip(ctx, xmlList, xmlZip, validations)
return android.Paths{htmlZip, textZip, xmlZip}
}
@@ -642,7 +653,7 @@
return
}
- var outputs []*lintOutputs
+ var outputs []*LintInfo
var dirs []string
ctx.VisitAllModules(func(m android.Module) {
if ctx.Config().KatiEnabled() && !m.ExportedToMake() {
@@ -658,14 +669,14 @@
}
}
- if l, ok := m.(lintOutputsIntf); ok {
- outputs = append(outputs, l.lintOutputs())
+ if lintInfo, ok := android.OtherModuleProvider(ctx, m, LintProvider); ok {
+ outputs = append(outputs, lintInfo)
}
})
dirs = android.SortedUniqueStrings(dirs)
- zip := func(outputPath android.WritablePath, get func(*lintOutputs) android.Path) {
+ zip := func(outputPath android.WritablePath, get func(*LintInfo) android.Path) {
var paths android.Paths
for _, output := range outputs {
@@ -674,20 +685,20 @@
}
}
- lintZip(ctx, paths, outputPath)
+ lintZip(ctx, paths, outputPath, nil)
}
l.htmlZip = android.PathForOutput(ctx, "lint-report-html.zip")
- zip(l.htmlZip, func(l *lintOutputs) android.Path { return l.html })
+ zip(l.htmlZip, func(l *LintInfo) android.Path { return l.HTML })
l.textZip = android.PathForOutput(ctx, "lint-report-text.zip")
- zip(l.textZip, func(l *lintOutputs) android.Path { return l.text })
+ zip(l.textZip, func(l *LintInfo) android.Path { return l.Text })
l.xmlZip = android.PathForOutput(ctx, "lint-report-xml.zip")
- zip(l.xmlZip, func(l *lintOutputs) android.Path { return l.xml })
+ zip(l.xmlZip, func(l *LintInfo) android.Path { return l.XML })
l.referenceBaselineZip = android.PathForOutput(ctx, "lint-report-reference-baselines.zip")
- zip(l.referenceBaselineZip, func(l *lintOutputs) android.Path { return l.referenceBaseline })
+ zip(l.referenceBaselineZip, func(l *LintInfo) android.Path { return l.ReferenceBaseline })
ctx.Phony("lint-check", l.htmlZip, l.textZip, l.xmlZip, l.referenceBaselineZip)
}
@@ -703,17 +714,9 @@
func init() {
android.RegisterParallelSingletonType("lint",
func() android.Singleton { return &lintSingleton{} })
-
- registerLintBuildComponents(android.InitRegistrationContext)
}
-func registerLintBuildComponents(ctx android.RegistrationContext) {
- ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("enforce_strict_updatability_linting", enforceStrictUpdatabilityLintingMutator).Parallel()
- })
-}
-
-func lintZip(ctx android.BuilderContext, paths android.Paths, outputPath android.WritablePath) {
+func lintZip(ctx android.BuilderContext, paths android.Paths, outputPath android.WritablePath, validations android.Paths) {
paths = android.SortedUniquePaths(android.CopyOfPaths(paths))
sort.Slice(paths, func(i, j int) bool {
@@ -725,19 +728,8 @@
rule.Command().BuiltTool("soong_zip").
FlagWithOutput("-o ", outputPath).
FlagWithArg("-C ", android.PathForIntermediates(ctx).String()).
- FlagWithRspFileInputList("-r ", outputPath.ReplaceExtension(ctx, "rsp"), paths)
+ FlagWithRspFileInputList("-r ", outputPath.ReplaceExtension(ctx, "rsp"), paths).
+ Validations(validations)
rule.Build(outputPath.Base(), outputPath.Base())
}
-
-// Enforce the strict updatability linting to all applicable transitive dependencies.
-func enforceStrictUpdatabilityLintingMutator(ctx android.TopDownMutatorContext) {
- m := ctx.Module()
- if d, ok := m.(LintDepSetsIntf); ok && d.GetStrictUpdatabilityLinting() {
- ctx.VisitDirectDepsWithTag(staticLibTag, func(d android.Module) {
- if a, ok := d.(LintDepSetsIntf); ok {
- a.SetStrictUpdatabilityLinting(true)
- }
- })
- }
-}
diff --git a/java/lint_test.go b/java/lint_test.go
index b51753f..afe3914 100644
--- a/java/lint_test.go
+++ b/java/lint_test.go
@@ -164,7 +164,7 @@
sdk_version: "current",
lint: {
strict_updatability_linting: true,
- baseline_filename: "lint-baseline.xml",
+ baseline_filename: "foo_lint_baseline.xml",
},
}
@@ -176,7 +176,7 @@
min_sdk_version: "29",
sdk_version: "current",
lint: {
- baseline_filename: "lint-baseline.xml",
+ baseline_filename: "bar_lint_baseline.xml",
}
}
`
@@ -188,18 +188,13 @@
RunTestWithBp(t, bp)
foo := result.ModuleForTests("foo", "android_common")
- sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, foo.Output("lint.sbox.textproto"))
- if !strings.Contains(*sboxProto.Commands[0].Command,
- "--baseline lint-baseline.xml --disallowed_issues NewApi") {
+ strictUpdatabilityCheck := foo.Output("lint_strict_updatability_check.stamp")
+ if !strings.Contains(strictUpdatabilityCheck.RuleParams.Command,
+ "--disallowed_issues NewApi") {
t.Error("did not restrict baselining NewApi")
}
-
- bar := result.ModuleForTests("bar", "android_common")
- sboxProto = android.RuleBuilderSboxProtoForTests(t, result.TestContext, bar.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")
- }
+ android.AssertStringListContains(t, "strict updatability check baseline inputs", strictUpdatabilityCheck.Inputs.Strings(), "foo_lint_baseline.xml")
+ android.AssertStringListContains(t, "strict updatability check baseline inputs", strictUpdatabilityCheck.Inputs.Strings(), "bar_lint_baseline.xml")
}
func TestJavaLintDatabaseSelectionFull(t *testing.T) {
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index d794e51..5bb7754 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -33,6 +33,7 @@
platformBootclasspathArtBootJarDepTag = bootclasspathDependencyTag{name: "art-boot-jar"}
platformBootclasspathBootJarDepTag = bootclasspathDependencyTag{name: "platform-boot-jar"}
platformBootclasspathApexBootJarDepTag = bootclasspathDependencyTag{name: "apex-boot-jar"}
+ platformBootclasspathImplLibDepTag = dependencyTag{name: "impl-lib-tag"}
)
type platformBootclasspathModule struct {
@@ -111,12 +112,18 @@
// Add dependencies on all the ART jars.
global := dexpreopt.GetGlobalConfig(ctx)
addDependenciesOntoSelectedBootImageApexes(ctx, "com.android.art")
+
+ var bootImageModuleNames []string
+
// TODO: b/308174306 - Remove the mechanism of depending on the java_sdk_library(_import) directly
addDependenciesOntoBootImageModules(ctx, global.ArtApexJars, platformBootclasspathArtBootJarDepTag)
+ bootImageModuleNames = append(bootImageModuleNames, global.ArtApexJars.CopyOfJars()...)
// Add dependencies on all the non-updatable jars, which are on the platform or in non-updatable
// APEXes.
- addDependenciesOntoBootImageModules(ctx, b.platformJars(ctx), platformBootclasspathBootJarDepTag)
+ platformJars := b.platformJars(ctx)
+ addDependenciesOntoBootImageModules(ctx, platformJars, platformBootclasspathBootJarDepTag)
+ bootImageModuleNames = append(bootImageModuleNames, platformJars.CopyOfJars()...)
// Add dependencies on all the updatable jars, except the ART jars.
apexJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars
@@ -127,9 +134,17 @@
addDependenciesOntoSelectedBootImageApexes(ctx, android.FirstUniqueStrings(apexes)...)
// TODO: b/308174306 - Remove the mechanism of depending on the java_sdk_library(_import) directly
addDependenciesOntoBootImageModules(ctx, apexJars, platformBootclasspathApexBootJarDepTag)
+ bootImageModuleNames = append(bootImageModuleNames, apexJars.CopyOfJars()...)
// Add dependencies on all the fragments.
b.properties.BootclasspathFragmentsDepsProperties.addDependenciesOntoFragments(ctx)
+
+ for _, bootImageModuleName := range bootImageModuleNames {
+ implLibName := implLibraryModuleName(bootImageModuleName)
+ if ctx.OtherModuleExists(implLibName) {
+ ctx.AddFarVariationDependencies(nil, platformBootclasspathImplLibDepTag, implLibName)
+ }
+ }
}
func addDependenciesOntoBootImageModules(ctx android.BottomUpMutatorContext, modules android.ConfiguredJarList, tag bootclasspathDependencyTag) {
@@ -166,8 +181,15 @@
allModules = append(allModules, apexModules...)
b.configuredModules = allModules
+ // Do not add implLibModule to allModules as the impl lib is only used to collect the
+ // transitive source files
+ var implLibModule []android.Module
+ ctx.VisitDirectDepsWithTag(implLibraryTag, func(m android.Module) {
+ implLibModule = append(implLibModule, m)
+ })
+
var transitiveSrcFiles android.Paths
- for _, module := range allModules {
+ for _, module := range append(allModules, implLibModule...) {
if depInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
if depInfo.TransitiveSrcFiles != nil {
transitiveSrcFiles = append(transitiveSrcFiles, depInfo.TransitiveSrcFiles.ToList()...)
diff --git a/java/rro_test.go b/java/rro_test.go
index 742c839..4d79130 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -282,7 +282,7 @@
enforceRROTargets: []string{"foo"},
rroDirs: map[string][]string{
"foo": {"product/vendor/blah/overlay/lib2/res"},
- "bar": {"product/vendor/blah/overlay/lib2/res"},
+ "bar": nil,
},
},
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index bb0d7d0..f308772 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -29,11 +29,6 @@
"android/soong/android"
"android/soong/dexpreopt"
- "android/soong/etc"
-)
-
-const (
- sdkXmlFileSuffix = ".xml"
)
// A tag to associated a dependency with a specific api scope.
@@ -927,7 +922,7 @@
c.initSdkLibraryComponent(module)
}
-func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied(ctx android.DefaultableHookContext) bool {
+func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied() bool {
namePtr := proptools.StringPtr(c.module.RootLibraryName())
c.sdkLibraryComponentProperties.SdkLibraryName = namePtr
@@ -949,62 +944,32 @@
return c.sharedLibrary()
}
-func (c *commonToSdkLibraryAndImport) generateCommonBuildActions(ctx android.ModuleContext) {
+func (c *commonToSdkLibraryAndImport) generateCommonBuildActions(ctx android.ModuleContext) SdkLibraryInfo {
c.doctagPaths = android.PathsForModuleSrc(ctx, c.commonSdkLibraryProperties.Doctag_files)
-}
-func (c *commonToSdkLibraryAndImport) getImplLibraryModule() *Library {
- return c.implLibraryModule
-}
+ everythingStubPaths := make(map[android.SdkKind]OptionalDexJarPath)
+ exportableStubPaths := make(map[android.SdkKind]OptionalDexJarPath)
+ removedApiFilePaths := make(map[android.SdkKind]android.OptionalPath)
+ for kind := android.SdkNone; kind <= android.SdkPrivate; kind += 1 {
+ everythingStubPath := makeUnsetDexJarPath()
+ exportableStubPath := makeUnsetDexJarPath()
+ removedApiFilePath := android.OptionalPath{}
+ if scopePath := c.findClosestScopePath(sdkKindToApiScope(kind)); scopePath != nil {
+ everythingStubPath = scopePath.stubsDexJarPath
+ exportableStubPath = scopePath.exportableStubsDexJarPath
+ removedApiFilePath = scopePath.removedApiFilePath
+ }
+ everythingStubPaths[kind] = everythingStubPath
+ exportableStubPaths[kind] = exportableStubPath
+ removedApiFilePaths[kind] = removedApiFilePath
+ }
-// Module name of the runtime implementation library
-func (c *commonToSdkLibraryAndImport) implLibraryModuleName() string {
- return c.module.RootLibraryName() + ".impl"
-}
-
-// Module name of the XML file for the lib
-func (c *commonToSdkLibraryAndImport) xmlPermissionsModuleName() string {
- return c.module.RootLibraryName() + sdkXmlFileSuffix
-}
-
-// Name of the java_library module that compiles the stubs source.
-func (c *commonToSdkLibraryAndImport) stubsLibraryModuleName(apiScope *apiScope) string {
- baseName := c.module.RootLibraryName()
- return apiScope.stubsLibraryModuleName(baseName)
-}
-
-// Name of the java_library module that compiles the exportable stubs source.
-func (c *commonToSdkLibraryAndImport) exportableStubsLibraryModuleName(apiScope *apiScope) string {
- baseName := c.module.RootLibraryName()
- return apiScope.exportableStubsLibraryModuleName(baseName)
-}
-
-// Name of the droidstubs module that generates the stubs source and may also
-// generate/check the API.
-func (c *commonToSdkLibraryAndImport) stubsSourceModuleName(apiScope *apiScope) string {
- baseName := c.module.RootLibraryName()
- return apiScope.stubsSourceModuleName(baseName)
-}
-
-// Name of the java_api_library module that generates the from-text stubs source
-// and compiles to a jar file.
-func (c *commonToSdkLibraryAndImport) apiLibraryModuleName(apiScope *apiScope) string {
- baseName := c.module.RootLibraryName()
- return apiScope.apiLibraryModuleName(baseName)
-}
-
-// Name of the java_library module that compiles the stubs
-// generated from source Java files.
-func (c *commonToSdkLibraryAndImport) sourceStubsLibraryModuleName(apiScope *apiScope) string {
- baseName := c.module.RootLibraryName()
- return apiScope.sourceStubsLibraryModuleName(baseName)
-}
-
-// Name of the java_library module that compiles the exportable stubs
-// generated from source Java files.
-func (c *commonToSdkLibraryAndImport) exportableSourceStubsLibraryModuleName(apiScope *apiScope) string {
- baseName := c.module.RootLibraryName()
- return apiScope.exportableSourceStubsLibraryModuleName(baseName)
+ return SdkLibraryInfo{
+ EverythingStubDexJarPaths: everythingStubPaths,
+ ExportableStubDexJarPaths: exportableStubPaths,
+ RemovedTxtFiles: removedApiFilePaths,
+ SharedLibrary: c.sharedLibrary(),
+ }
}
// The component names for different outputs of the java_sdk_library.
@@ -1078,29 +1043,6 @@
return nil
}
-// selectScopePaths returns the *scopePaths appropriate for the specific kind.
-//
-// If the module does not support the specific kind then it will return the *scopePaths for the
-// closest kind which is a subset of the requested kind. e.g. if requesting android.SdkModule then
-// it will return *scopePaths for android.SdkSystem if available or android.SdkPublic of not.
-func (c *commonToSdkLibraryAndImport) selectScopePaths(ctx android.BaseModuleContext, kind android.SdkKind) *scopePaths {
- apiScope := sdkKindToApiScope(kind)
-
- paths := c.findClosestScopePath(apiScope)
- if paths == nil {
- var scopes []string
- for _, s := range AllApiScopes {
- if c.findScopePaths(s) != nil {
- scopes = append(scopes, s.name)
- }
- }
- ctx.ModuleErrorf("requires api scope %s from %s but it only has %q available", apiScope.name, c.module.RootLibraryName(), scopes)
- return nil
- }
-
- return paths
-}
-
// sdkKindToApiScope maps from android.SdkKind to apiScope.
func sdkKindToApiScope(kind android.SdkKind) *apiScope {
var apiScope *apiScope
@@ -1119,37 +1061,6 @@
return apiScope
}
-// to satisfy SdkLibraryDependency interface
-func (c *commonToSdkLibraryAndImport) SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath {
- paths := c.selectScopePaths(ctx, kind)
- if paths == nil {
- return makeUnsetDexJarPath()
- }
-
- return paths.stubsDexJarPath
-}
-
-// to satisfy SdkLibraryDependency interface
-func (c *commonToSdkLibraryAndImport) SdkApiExportableStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath {
- paths := c.selectScopePaths(ctx, kind)
- if paths == nil {
- return makeUnsetDexJarPath()
- }
-
- return paths.exportableStubsDexJarPath
-}
-
-// to satisfy SdkLibraryDependency interface
-func (c *commonToSdkLibraryAndImport) SdkRemovedTxtFile(ctx android.BaseModuleContext, kind android.SdkKind) android.OptionalPath {
- apiScope := sdkKindToApiScope(kind)
- paths := c.findScopePaths(apiScope)
- if paths == nil {
- return android.OptionalPath{}
- }
-
- return paths.removedApiFilePath
-}
-
func (c *commonToSdkLibraryAndImport) sdkComponentPropertiesForChildLibrary() interface{} {
componentProps := &struct {
SdkLibraryName *string
@@ -1240,36 +1151,25 @@
var _ SdkLibraryComponentDependency = (*SdkLibrary)(nil)
var _ SdkLibraryComponentDependency = (*SdkLibraryImport)(nil)
-// Provides access to sdk_version related files, e.g. header and implementation jars.
-type SdkLibraryDependency interface {
- SdkLibraryComponentDependency
-
- // SdkApiStubDexJar returns the dex jar for the stubs for the prebuilt
- // java_sdk_library_import module. It is needed by the hiddenapi processing tool which
- // processes dex files.
- SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath
-
- // SdkApiExportableStubDexJar returns the exportable dex jar for the stubs for
- // java_sdk_library module. It is needed by the hiddenapi processing tool which processes
- // dex files.
- SdkApiExportableStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath
-
- // SdkRemovedTxtFile returns the optional path to the removed.txt file for the specified sdk kind.
- SdkRemovedTxtFile(ctx android.BaseModuleContext, kind android.SdkKind) android.OptionalPath
-
- // sharedLibrary returns true if this can be used as a shared library.
- sharedLibrary() bool
-
- // getImplLibraryModule returns the pointer to the implementation library submodule of this
- // sdk library.
- getImplLibraryModule() *Library
-}
-
type SdkLibraryInfo struct {
// GeneratingLibs is the names of the library modules that this sdk library
// generates. Note that this only includes the name of the modules that other modules can
// depend on, and is not a holistic list of generated modules.
GeneratingLibs []string
+
+ // Map of sdk kind to the dex jar for the "everything" stubs.
+ // It is needed by the hiddenapi processing tool which processes dex files.
+ EverythingStubDexJarPaths map[android.SdkKind]OptionalDexJarPath
+
+ // Map of sdk kind to the dex jar for the "exportable" stubs.
+ // It is needed by the hiddenapi processing tool which processes dex files.
+ ExportableStubDexJarPaths map[android.SdkKind]OptionalDexJarPath
+
+ // Map of sdk kind to the optional path to the removed.txt file.
+ RemovedTxtFiles map[android.SdkKind]android.OptionalPath
+
+ // Whether if this can be used as a shared library.
+ SharedLibrary bool
}
var SdkLibraryInfoProvider = blueprint.NewProvider[SdkLibraryInfo]()
@@ -1303,12 +1203,13 @@
builtInstalledForApex []dexpreopterInstall
}
-var _ SdkLibraryDependency = (*SdkLibrary)(nil)
-
func (module *SdkLibrary) generateTestAndSystemScopesByDefault() bool {
return module.sdkLibraryProperties.Generate_system_and_test_apis
}
+var _ UsesLibraryDependency = (*SdkLibrary)(nil)
+
+// To satisfy the UsesLibraryDependency interface
func (module *SdkLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
if module.implLibraryModule != nil {
return module.implLibraryModule.DexJarBuildPath(ctx)
@@ -1316,6 +1217,7 @@
return makeUnsetDexJarPath()
}
+// To satisfy the UsesLibraryDependency interface
func (module *SdkLibrary) DexJarInstallPath() android.Path {
if module.implLibraryModule != nil {
return module.implLibraryModule.DexJarInstallPath()
@@ -1378,7 +1280,7 @@
}
func CheckMinSdkVersion(ctx android.ModuleContext, module *Library) {
- android.CheckMinSdkVersion(ctx, module.MinSdkVersion(ctx), func(c android.ModuleContext, do android.PayloadDepsCallback) {
+ android.CheckMinSdkVersion(ctx, module.MinSdkVersion(ctx), func(c android.BaseModuleContext, do android.PayloadDepsCallback) {
ctx.WalkDeps(func(child android.Module, parent android.Module) bool {
isExternal := !module.depIsInSameApex(ctx, child)
if am, ok := child.(android.ApexModule); ok {
@@ -1433,7 +1335,7 @@
ctx.AddVariationDependencies(nil, apiScope.exportableStubsTag, exportableStubModuleName)
// Add a dependency on the stubs source in order to access both stubs source and api information.
- ctx.AddVariationDependencies(nil, apiScope.stubsSourceAndApiTag, module.stubsSourceModuleName(apiScope))
+ ctx.AddVariationDependencies(nil, apiScope.stubsSourceAndApiTag, module.droidstubsModuleName(apiScope))
if module.compareAgainstLatestApi(apiScope) {
// Add dependencies on the latest finalized version of the API .txt file.
@@ -1503,8 +1405,6 @@
module.HideFromMake()
}
- module.generateCommonBuildActions(ctx)
-
module.stem = proptools.StringDefault(module.overridableProperties.Stem, ctx.ModuleName())
module.provideHiddenAPIPropertyInfo(ctx)
@@ -1537,11 +1437,11 @@
if dep, ok := android.OtherModuleProvider(ctx, to, JavaInfoProvider); ok {
module.implLibraryHeaderJars = append(module.implLibraryHeaderJars, dep.HeaderJars...)
module.implLibraryModule = to.(*Library)
- android.SetProvider(ctx, JavaInfoProvider, dep)
}
}
})
+ sdkLibInfo := module.generateCommonBuildActions(ctx)
apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
if !apexInfo.IsForPlatform() {
module.hideApexVariantFromMake = true
@@ -1570,7 +1470,10 @@
module.dexer.proguardDictionary = module.implLibraryModule.dexer.proguardDictionary
module.dexer.proguardUsageZip = module.implLibraryModule.dexer.proguardUsageZip
module.linter.reports = module.implLibraryModule.linter.reports
- module.linter.outputs.depSets = module.implLibraryModule.LintDepSets()
+
+ if lintInfo, ok := android.OtherModuleProvider(ctx, module.implLibraryModule, LintProvider); ok {
+ android.SetProvider(ctx, LintProvider, lintInfo)
+ }
if !module.Host() {
module.hostdexInstallFile = module.implLibraryModule.hostdexInstallFile
@@ -1625,9 +1528,8 @@
setOutputFiles(ctx, module.implLibraryModule.Module)
}
- android.SetProvider(ctx, SdkLibraryInfoProvider, SdkLibraryInfo{
- GeneratingLibs: generatingLibs,
- })
+ sdkLibInfo.GeneratingLibs = generatingLibs
+ android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo)
}
func (module *SdkLibrary) BuiltInstalledForApex() []dexpreopterInstall {
@@ -1734,420 +1636,6 @@
return visibility
}
-// Creates the implementation java library
-func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext) {
- visibility := childModuleVisibility(module.sdkLibraryProperties.Impl_library_visibility)
-
- staticLibs := module.properties.Static_libs.Clone()
- staticLibs.AppendSimpleValue(module.sdkLibraryProperties.Impl_only_static_libs)
- props := struct {
- Name *string
- Enabled proptools.Configurable[bool]
- Visibility []string
- Libs []string
- Static_libs proptools.Configurable[[]string]
- Apex_available []string
- Stem *string
- }{
- Name: proptools.StringPtr(module.implLibraryModuleName()),
- Enabled: module.EnabledProperty(),
- Visibility: visibility,
-
- Libs: append(module.properties.Libs, module.sdkLibraryProperties.Impl_only_libs...),
-
- Static_libs: staticLibs,
- // Pass the apex_available settings down so that the impl library can be statically
- // embedded within a library that is added to an APEX. Needed for updatable-media.
- Apex_available: module.ApexAvailable(),
-
- Stem: proptools.StringPtr(module.Name()),
- }
-
- properties := []interface{}{
- &module.properties,
- &module.protoProperties,
- &module.deviceProperties,
- &module.dexProperties,
- &module.dexpreoptProperties,
- &module.linter.properties,
- &module.overridableProperties,
- &props,
- module.sdkComponentPropertiesForChildLibrary(),
- }
- mctx.CreateModule(LibraryFactory, properties...)
-}
-
-type libraryProperties struct {
- Name *string
- Enabled proptools.Configurable[bool]
- Visibility []string
- Srcs []string
- Installable *bool
- Sdk_version *string
- System_modules *string
- Patch_module *string
- Libs []string
- Static_libs []string
- Compile_dex *bool
- Java_version *string
- Openjdk9 struct {
- Srcs []string
- Javacflags []string
- }
- Dist struct {
- Targets []string
- Dest *string
- Dir *string
- Tag *string
- }
- Is_stubs_module *bool
- Stub_contributing_api *string
-}
-
-func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
- props := libraryProperties{}
- props.Enabled = module.EnabledProperty()
- props.Visibility = []string{"//visibility:override", "//visibility:private"}
- // sources are generated from the droiddoc
- sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
- props.Sdk_version = proptools.StringPtr(sdkVersion)
- props.System_modules = module.deviceProperties.System_modules
- props.Patch_module = module.properties.Patch_module
- props.Installable = proptools.BoolPtr(false)
- props.Libs = module.sdkLibraryProperties.Stub_only_libs
- props.Libs = append(props.Libs, module.scopeToProperties[apiScope].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) {
- props.Libs = append(props.Libs, "stub-annotations")
- }
- props.Openjdk9.Srcs = module.properties.Openjdk9.Srcs
- props.Openjdk9.Javacflags = module.properties.Openjdk9.Javacflags
- // We compile the stubs for 1.8 in line with the main android.jar stubs, and potential
- // interop with older developer tools that don't support 1.9.
- props.Java_version = proptools.StringPtr("1.8")
- props.Is_stubs_module = proptools.BoolPtr(true)
- props.Stub_contributing_api = proptools.StringPtr(apiScope.kind.String())
-
- return props
-}
-
-// Creates a static java library that has API stubs
-func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
-
- props := module.stubsLibraryProps(mctx, apiScope)
- props.Name = proptools.StringPtr(module.sourceStubsLibraryModuleName(apiScope))
- props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope)}
-
- mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
-}
-
-// Create a static java library that compiles the "exportable" stubs
-func (module *SdkLibrary) createExportableStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
- props := module.stubsLibraryProps(mctx, apiScope)
- props.Name = proptools.StringPtr(module.exportableSourceStubsLibraryModuleName(apiScope))
- props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope) + "{.exportable}"}
-
- mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
-}
-
-// Creates a droidstubs module that creates stubs source files from the given full source
-// files and also updates and checks the API specification files.
-func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookContext, apiScope *apiScope, name string, scopeSpecificDroidstubsArgs []string) {
- props := struct {
- Name *string
- Enabled proptools.Configurable[bool]
- Visibility []string
- Srcs []string
- Installable *bool
- Sdk_version *string
- Api_surface *string
- System_modules *string
- Libs proptools.Configurable[[]string]
- Output_javadoc_comments *bool
- Arg_files []string
- Args *string
- Java_version *string
- Annotations_enabled *bool
- Merge_annotations_dirs []string
- Merge_inclusion_annotations_dirs []string
- Generate_stubs *bool
- Previous_api *string
- Aconfig_declarations []string
- Check_api struct {
- Current ApiToCheck
- Last_released ApiToCheck
-
- Api_lint struct {
- Enabled *bool
- New_since *string
- Baseline_file *string
- }
- }
- Aidl struct {
- Include_dirs []string
- Local_include_dirs []string
- }
- Dists []android.Dist
- }{}
-
- // The stubs source processing uses the same compile time classpath when extracting the
- // API from the implementation library as it does when compiling it. i.e. the same
- // * sdk version
- // * system_modules
- // * libs (static_libs/libs)
-
- props.Name = proptools.StringPtr(name)
- props.Enabled = module.EnabledProperty()
- props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_source_visibility)
- props.Srcs = append(props.Srcs, module.properties.Srcs...)
- props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
- props.Sdk_version = module.deviceProperties.Sdk_version
- props.Api_surface = &apiScope.name
- props.System_modules = module.deviceProperties.System_modules
- props.Installable = proptools.BoolPtr(false)
- // A droiddoc module has only one Libs property and doesn't distinguish between
- // shared libs and static libs. So we need to add both of these libs to Libs property.
- props.Libs = proptools.NewConfigurable[[]string](nil, nil)
- props.Libs.AppendSimpleValue(module.properties.Libs)
- props.Libs.Append(module.properties.Static_libs)
- props.Libs.AppendSimpleValue(module.sdkLibraryProperties.Stub_only_libs)
- props.Libs.AppendSimpleValue(module.scopeToProperties[apiScope].Libs)
- props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
- props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
- props.Java_version = module.properties.Java_version
-
- props.Annotations_enabled = module.sdkLibraryProperties.Annotations_enabled
- props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
- props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
- props.Aconfig_declarations = module.sdkLibraryProperties.Aconfig_declarations
-
- droidstubsArgs := []string{}
- if len(module.sdkLibraryProperties.Api_packages) != 0 {
- droidstubsArgs = append(droidstubsArgs, "--stub-packages "+strings.Join(module.sdkLibraryProperties.Api_packages, ":"))
- }
- droidstubsArgs = append(droidstubsArgs, module.sdkLibraryProperties.Droiddoc_options...)
- disabledWarnings := []string{"HiddenSuperclass"}
- if proptools.BoolDefault(module.sdkLibraryProperties.Api_lint.Legacy_errors_allowed, true) {
- disabledWarnings = append(disabledWarnings,
- "BroadcastBehavior",
- "DeprecationMismatch",
- "MissingPermission",
- "SdkConstant",
- "Todo",
- )
- }
- droidstubsArgs = append(droidstubsArgs, android.JoinWithPrefix(disabledWarnings, "--hide "))
-
- // Output Javadoc comments for public scope.
- if apiScope == apiScopePublic {
- props.Output_javadoc_comments = proptools.BoolPtr(true)
- }
-
- // Add in scope specific arguments.
- droidstubsArgs = append(droidstubsArgs, scopeSpecificDroidstubsArgs...)
- props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
- props.Args = proptools.StringPtr(strings.Join(droidstubsArgs, " "))
-
- // List of APIs identified from the provided source files are created. They are later
- // compared against to the not-yet-released (a.k.a current) list of APIs and to the
- // last-released (a.k.a numbered) list of API.
- currentApiFileName := apiScope.apiFilePrefix + "current.txt"
- removedApiFileName := apiScope.apiFilePrefix + "removed.txt"
- apiDir := module.getApiDir()
- currentApiFileName = path.Join(apiDir, currentApiFileName)
- removedApiFileName = path.Join(apiDir, removedApiFileName)
-
- // check against the not-yet-release API
- props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
- props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
-
- if module.compareAgainstLatestApi(apiScope) {
- // check against the latest released API
- latestApiFilegroupName := proptools.StringPtr(module.latestApiFilegroupName(apiScope))
- props.Previous_api = latestApiFilegroupName
- props.Check_api.Last_released.Api_file = latestApiFilegroupName
- props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
- module.latestRemovedApiFilegroupName(apiScope))
- props.Check_api.Last_released.Baseline_file = proptools.StringPtr(
- module.latestIncompatibilitiesFilegroupName(apiScope))
-
- if proptools.Bool(module.sdkLibraryProperties.Api_lint.Enabled) {
- // Enable api lint.
- props.Check_api.Api_lint.Enabled = proptools.BoolPtr(true)
- props.Check_api.Api_lint.New_since = latestApiFilegroupName
-
- // If it exists then pass a lint-baseline.txt through to droidstubs.
- baselinePath := path.Join(apiDir, apiScope.apiFilePrefix+"lint-baseline.txt")
- baselinePathRelativeToRoot := path.Join(mctx.ModuleDir(), baselinePath)
- paths, err := mctx.GlobWithDeps(baselinePathRelativeToRoot, nil)
- if err != nil {
- mctx.ModuleErrorf("error checking for presence of %s: %s", baselinePathRelativeToRoot, err)
- }
- if len(paths) == 1 {
- props.Check_api.Api_lint.Baseline_file = proptools.StringPtr(baselinePath)
- } else if len(paths) != 0 {
- mctx.ModuleErrorf("error checking for presence of %s: expected one path, found: %v", baselinePathRelativeToRoot, paths)
- }
- }
- }
-
- if !Bool(module.sdkLibraryProperties.No_dist) {
- // Dist the api txt and removed api txt artifacts for sdk builds.
- distDir := proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
- stubsTypeTagPrefix := ""
- if mctx.Config().ReleaseHiddenApiExportableStubs() {
- stubsTypeTagPrefix = ".exportable"
- }
- for _, p := range []struct {
- tag string
- pattern string
- }{
- // "exportable" api files are copied to the dist directory instead of the
- // "everything" api files when "RELEASE_HIDDEN_API_EXPORTABLE_STUBS" build flag
- // is set. Otherwise, the "everything" api files are copied to the dist directory.
- {tag: "%s.api.txt", pattern: "%s.txt"},
- {tag: "%s.removed-api.txt", pattern: "%s-removed.txt"},
- } {
- props.Dists = append(props.Dists, android.Dist{
- Targets: []string{"sdk", "win_sdk"},
- Dir: distDir,
- Dest: proptools.StringPtr(fmt.Sprintf(p.pattern, module.distStem())),
- Tag: proptools.StringPtr(fmt.Sprintf(p.tag, stubsTypeTagPrefix)),
- })
- }
- }
-
- mctx.CreateModule(DroidstubsFactory, &props, module.sdkComponentPropertiesForChildLibrary()).(*Droidstubs).CallHookIfAvailable(mctx)
-}
-
-func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
- props := struct {
- Name *string
- Enabled proptools.Configurable[bool]
- Visibility []string
- Api_contributions []string
- Libs proptools.Configurable[[]string]
- Static_libs []string
- System_modules *string
- Enable_validation *bool
- Stubs_type *string
- Sdk_version *string
- Previous_api *string
- }{}
-
- props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope))
- props.Enabled = module.EnabledProperty()
- props.Visibility = []string{"//visibility:override", "//visibility:private"}
-
- apiContributions := []string{}
-
- // Api surfaces are not independent of each other, but have subset relationships,
- // and so does the api files. To generate from-text stubs for api surfaces other than public,
- // all subset api domains' api_contriubtions must be added as well.
- scope := apiScope
- for scope != nil {
- apiContributions = append(apiContributions, module.stubsSourceModuleName(scope)+".api.contribution")
- scope = scope.extends
- }
- if apiScope == apiScopePublic {
- additionalApiContribution := module.apiLibraryAdditionalApiContribution()
- if additionalApiContribution != "" {
- apiContributions = append(apiContributions, additionalApiContribution)
- }
- }
-
- props.Api_contributions = apiContributions
-
- // Ensure that stub-annotations is added to the classpath before any other libs
- props.Libs = proptools.NewConfigurable[[]string](nil, nil)
- props.Libs.AppendSimpleValue([]string{"stub-annotations"})
- props.Libs.AppendSimpleValue(module.properties.Libs)
- props.Libs.Append(module.properties.Static_libs)
- props.Libs.AppendSimpleValue(module.sdkLibraryProperties.Stub_only_libs)
- props.Libs.AppendSimpleValue(module.scopeToProperties[apiScope].Libs)
- props.Static_libs = module.sdkLibraryProperties.Stub_only_static_libs
-
- props.System_modules = module.deviceProperties.System_modules
- props.Enable_validation = proptools.BoolPtr(true)
- props.Stubs_type = proptools.StringPtr("everything")
-
- if module.deviceProperties.Sdk_version != nil {
- props.Sdk_version = module.deviceProperties.Sdk_version
- }
-
- if module.compareAgainstLatestApi(apiScope) {
- // check against the latest released API
- latestApiFilegroupName := proptools.StringPtr(module.latestApiFilegroupName(apiScope))
- props.Previous_api = latestApiFilegroupName
- }
-
- mctx.CreateModule(ApiLibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
-}
-
-func (module *SdkLibrary) topLevelStubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope, doDist bool) libraryProperties {
- props := libraryProperties{}
-
- props.Enabled = module.EnabledProperty()
- props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
- sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
- props.Sdk_version = proptools.StringPtr(sdkVersion)
-
- props.System_modules = module.deviceProperties.System_modules
-
- // The imports need to be compiled to dex if the java_sdk_library requests it.
- compileDex := module.dexProperties.Compile_dex
- if module.stubLibrariesCompiledForDex() {
- compileDex = proptools.BoolPtr(true)
- }
- props.Compile_dex = compileDex
-
- props.Stub_contributing_api = proptools.StringPtr(apiScope.kind.String())
-
- if !Bool(module.sdkLibraryProperties.No_dist) && doDist {
- props.Dist.Targets = []string{"sdk", "win_sdk"}
- props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.distStem()))
- props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
- props.Dist.Tag = proptools.StringPtr(".jar")
- }
- props.Is_stubs_module = proptools.BoolPtr(true)
-
- return props
-}
-
-func (module *SdkLibrary) createTopLevelStubsLibrary(
- mctx android.DefaultableHookContext, apiScope *apiScope) {
-
- // Dist the "everything" stubs when the RELEASE_HIDDEN_API_EXPORTABLE_STUBS build flag is false
- doDist := !mctx.Config().ReleaseHiddenApiExportableStubs()
- props := module.topLevelStubsLibraryProps(mctx, apiScope, doDist)
- props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
-
- // Add the stub compiling java_library/java_api_library as static lib based on build config
- staticLib := module.sourceStubsLibraryModuleName(apiScope)
- if mctx.Config().BuildFromTextStub() && module.ModuleBuildFromTextStubs() {
- staticLib = module.apiLibraryModuleName(apiScope)
- }
- props.Static_libs = append(props.Static_libs, staticLib)
-
- mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
-}
-
-func (module *SdkLibrary) createTopLevelExportableStubsLibrary(
- mctx android.DefaultableHookContext, apiScope *apiScope) {
-
- // Dist the "exportable" stubs when the RELEASE_HIDDEN_API_EXPORTABLE_STUBS build flag is true
- doDist := mctx.Config().ReleaseHiddenApiExportableStubs()
- props := module.topLevelStubsLibraryProps(mctx, apiScope, doDist)
- props.Name = proptools.StringPtr(module.exportableStubsLibraryModuleName(apiScope))
-
- staticLib := module.exportableSourceStubsLibraryModuleName(apiScope)
- props.Static_libs = append(props.Static_libs, staticLib)
-
- mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
-}
-
func (module *SdkLibrary) compareAgainstLatestApi(apiScope *apiScope) bool {
return !(apiScope.unstable || module.sdkLibraryProperties.Unsafe_ignore_missing_latest_api)
}
@@ -2173,40 +1661,6 @@
return proptools.BoolDefault(module.sdkLibraryProperties.Build_from_text_stub, true)
}
-// Creates the xml file that publicizes the runtime library
-func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) {
- moduleMinApiLevel := module.Library.MinSdkVersion(mctx)
- var moduleMinApiLevelStr = moduleMinApiLevel.String()
- if moduleMinApiLevel == android.NoneApiLevel {
- moduleMinApiLevelStr = "current"
- }
- props := struct {
- Name *string
- Enabled proptools.Configurable[bool]
- Lib_name *string
- Apex_available []string
- On_bootclasspath_since *string
- On_bootclasspath_before *string
- Min_device_sdk *string
- Max_device_sdk *string
- Sdk_library_min_api_level *string
- Uses_libs_dependencies []string
- }{
- Name: proptools.StringPtr(module.xmlPermissionsModuleName()),
- Enabled: module.EnabledProperty(),
- Lib_name: proptools.StringPtr(module.BaseModuleName()),
- Apex_available: module.ApexProperties.Apex_available,
- On_bootclasspath_since: module.commonSdkLibraryProperties.On_bootclasspath_since,
- On_bootclasspath_before: module.commonSdkLibraryProperties.On_bootclasspath_before,
- Min_device_sdk: module.commonSdkLibraryProperties.Min_device_sdk,
- Max_device_sdk: module.commonSdkLibraryProperties.Max_device_sdk,
- Sdk_library_min_api_level: &moduleMinApiLevelStr,
- Uses_libs_dependencies: module.usesLibraryProperties.Uses_libs,
- }
-
- mctx.CreateModule(sdkLibraryXmlFactory, &props)
-}
-
var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
func javaSdkLibraries(config android.Config) *[]string {
@@ -2272,10 +1726,10 @@
for _, scope := range generatedScopes {
// Use the stubs source name for legacy reasons.
- module.createStubsSourcesAndApi(mctx, scope, module.stubsSourceModuleName(scope), scope.droidstubsArgs)
+ module.createDroidstubs(mctx, scope, module.droidstubsModuleName(scope), scope.droidstubsArgs)
- module.createStubsLibrary(mctx, scope)
- module.createExportableStubsLibrary(mctx, scope)
+ module.createFromSourceStubsLibrary(mctx, scope)
+ module.createExportableFromSourceStubsLibrary(mctx, scope)
if mctx.Config().BuildFromTextStub() && module.ModuleBuildFromTextStubs() {
module.createApiLibrary(mctx, scope)
@@ -2386,7 +1840,7 @@
module.commonSdkLibraryProperties.Shared_library = proptools.BoolPtr(false)
}
- if module.initCommonAfterDefaultsApplied(ctx) {
+ if module.initCommonAfterDefaultsApplied() {
module.CreateInternalModules(ctx)
}
})
@@ -2465,8 +1919,6 @@
installFile android.Path
}
-var _ SdkLibraryDependency = (*SdkLibraryImport)(nil)
-
// The type of a structure that contains a field of type sdkLibraryScopeProperties
// for each apiscope in allApiScopes, e.g. something like:
//
@@ -2522,7 +1974,7 @@
InitJavaModule(module, android.HostAndDeviceSupported)
module.SetDefaultableHook(func(mctx android.DefaultableHookContext) {
- if module.initCommonAfterDefaultsApplied(mctx) {
+ if module.initCommonAfterDefaultsApplied() {
module.createInternalModules(mctx)
}
})
@@ -2576,86 +2028,6 @@
*javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
}
-func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
- // Creates a java import for the jar with ".stubs" suffix
- props := struct {
- Name *string
- Source_module_name *string
- Created_by_java_sdk_library_name *string
- Sdk_version *string
- Libs []string
- Jars []string
- Compile_dex *bool
- Is_stubs_module *bool
-
- android.UserSuppliedPrebuiltProperties
- }{}
- props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
- props.Source_module_name = proptools.StringPtr(apiScope.stubsLibraryModuleName(module.BaseModuleName()))
- props.Created_by_java_sdk_library_name = proptools.StringPtr(module.RootLibraryName())
- props.Sdk_version = scopeProperties.Sdk_version
- // Prepend any of the libs from the legacy public properties to the libs for each of the
- // scopes to avoid having to duplicate them in each scope.
- props.Libs = append(module.properties.Libs, scopeProperties.Libs...)
- props.Jars = scopeProperties.Jars
-
- // The imports are preferred if the java_sdk_library_import is preferred.
- props.CopyUserSuppliedPropertiesFromPrebuilt(&module.prebuilt)
-
- // The imports need to be compiled to dex if the java_sdk_library_import requests it.
- compileDex := module.properties.Compile_dex
- if module.stubLibrariesCompiledForDex() {
- compileDex = proptools.BoolPtr(true)
- }
- props.Compile_dex = compileDex
- props.Is_stubs_module = proptools.BoolPtr(true)
-
- mctx.CreateModule(ImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
-}
-
-func (module *SdkLibraryImport) createPrebuiltStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
- props := struct {
- Name *string
- Source_module_name *string
- Created_by_java_sdk_library_name *string
- Srcs []string
-
- android.UserSuppliedPrebuiltProperties
- }{}
- props.Name = proptools.StringPtr(module.stubsSourceModuleName(apiScope))
- props.Source_module_name = proptools.StringPtr(apiScope.stubsSourceModuleName(module.BaseModuleName()))
- props.Created_by_java_sdk_library_name = proptools.StringPtr(module.RootLibraryName())
- props.Srcs = scopeProperties.Stub_srcs
-
- // The stubs source is preferred if the java_sdk_library_import is preferred.
- props.CopyUserSuppliedPropertiesFromPrebuilt(&module.prebuilt)
-
- mctx.CreateModule(PrebuiltStubsSourcesFactory, &props, module.sdkComponentPropertiesForChildLibrary())
-}
-
-func (module *SdkLibraryImport) createPrebuiltApiContribution(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
- api_file := scopeProperties.Current_api
- api_surface := &apiScope.name
-
- props := struct {
- Name *string
- Source_module_name *string
- Created_by_java_sdk_library_name *string
- Api_surface *string
- Api_file *string
- Visibility []string
- }{}
-
- props.Name = proptools.StringPtr(module.stubsSourceModuleName(apiScope) + ".api.contribution")
- props.Source_module_name = proptools.StringPtr(apiScope.stubsSourceModuleName(module.BaseModuleName()) + ".api.contribution")
- props.Created_by_java_sdk_library_name = proptools.StringPtr(module.RootLibraryName())
- props.Api_surface = api_surface
- props.Api_file = api_file
- props.Visibility = []string{"//visibility:override", "//visibility:public"}
-
- mctx.CreateModule(ApiContributionImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
-}
-
// Add the dependencies on the child module in the component deps mutator so that it
// creates references to the prebuilt and not the source modules.
func (module *SdkLibraryImport) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
@@ -2669,7 +2041,7 @@
if len(scopeProperties.Stub_srcs) > 0 {
// Add dependencies to the prebuilt stubs source library
- ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, android.PrebuiltNameFromSource(module.stubsSourceModuleName(apiScope)))
+ ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, android.PrebuiltNameFromSource(module.droidstubsModuleName(apiScope)))
}
}
}
@@ -2723,8 +2095,6 @@
var _ hiddenAPIModule = (*SdkLibraryImport)(nil)
func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- module.generateCommonBuildActions(ctx)
-
// Assume that source module(sdk_library) is installed in /<sdk_library partition>/framework
module.installFile = android.PathForModuleInstall(ctx, "framework", module.Stem()+".jar")
@@ -2754,6 +2124,7 @@
}
}
})
+ sdkLibInfo := module.generateCommonBuildActions(ctx)
// Populate the scope paths with information from the properties.
for apiScope, scopeProperties := range module.scopeProperties {
@@ -2795,11 +2166,12 @@
setOutputFiles(ctx, module.implLibraryModule.Module)
}
- android.SetProvider(ctx, SdkLibraryInfoProvider, SdkLibraryInfo{
- GeneratingLibs: generatingLibs,
- })
+ sdkLibInfo.GeneratingLibs = generatingLibs
+ android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo)
}
+var _ UsesLibraryDependency = (*SdkLibraryImport)(nil)
+
// to satisfy UsesLibraryDependency interface
func (module *SdkLibraryImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
// The dex implementation jar extracted from the .apex file should be used in preference to the
@@ -2837,29 +2209,6 @@
}
// to satisfy apex.javaDependency interface
-func (module *SdkLibraryImport) LintDepSets() LintDepSets {
- if module.implLibraryModule == nil {
- return LintDepSets{}
- } else {
- return module.implLibraryModule.LintDepSets()
- }
-}
-
-func (module *SdkLibraryImport) GetStrictUpdatabilityLinting() bool {
- if module.implLibraryModule == nil {
- return false
- } else {
- return module.implLibraryModule.GetStrictUpdatabilityLinting()
- }
-}
-
-func (module *SdkLibraryImport) SetStrictUpdatabilityLinting(strictLinting bool) {
- if module.implLibraryModule != nil {
- module.implLibraryModule.SetStrictUpdatabilityLinting(strictLinting)
- }
-}
-
-// to satisfy apex.javaDependency interface
func (module *SdkLibraryImport) Stem() string {
return module.BaseModuleName()
}
@@ -2900,333 +2249,6 @@
return proptools.Bool(j.importDexpreoptProperties.Dex_preopt.Profile_guided)
}
-// java_sdk_library_xml
-type sdkLibraryXml struct {
- android.ModuleBase
- android.DefaultableModuleBase
- android.ApexModuleBase
-
- properties sdkLibraryXmlProperties
-
- outputFilePath android.OutputPath
- installDirPath android.InstallPath
-
- hideApexVariantFromMake bool
-}
-
-type sdkLibraryXmlProperties struct {
- // canonical name of the lib
- Lib_name *string
-
- // Signals that this shared library is part of the bootclasspath starting
- // on the version indicated in this attribute.
- //
- // This will make platforms at this level and above to ignore
- // <uses-library> tags with this library name because the library is already
- // available
- On_bootclasspath_since *string
-
- // Signals that this shared library was part of the bootclasspath before
- // (but not including) the version indicated in this attribute.
- //
- // The system will automatically add a <uses-library> tag with this library to
- // apps that target any SDK less than the version indicated in this attribute.
- On_bootclasspath_before *string
-
- // Indicates that PackageManager should ignore this shared library if the
- // platform is below the version indicated in this attribute.
- //
- // This means that the device won't recognise this library as installed.
- Min_device_sdk *string
-
- // Indicates that PackageManager should ignore this shared library if the
- // platform is above the version indicated in this attribute.
- //
- // This means that the device won't recognise this library as installed.
- Max_device_sdk *string
-
- // The SdkLibrary's min api level as a string
- //
- // This value comes from the ApiLevel of the MinSdkVersion property.
- Sdk_library_min_api_level *string
-
- // Uses-libs dependencies that the shared library requires to work correctly.
- //
- // This will add dependency="foo:bar" to the <library> section.
- Uses_libs_dependencies []string
-}
-
-// java_sdk_library_xml builds the permission xml file for a java_sdk_library.
-// Not to be used directly by users. java_sdk_library internally uses this.
-func sdkLibraryXmlFactory() android.Module {
- module := &sdkLibraryXml{}
-
- module.AddProperties(&module.properties)
-
- android.InitApexModule(module)
- android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
-
- return module
-}
-
-func (module *sdkLibraryXml) UniqueApexVariations() bool {
- // sdkLibraryXml needs a unique variation per APEX because the generated XML file contains the path to the
- // mounted APEX, which contains the name of the APEX.
- return true
-}
-
-// from android.PrebuiltEtcModule
-func (module *sdkLibraryXml) BaseDir() string {
- return "etc"
-}
-
-// from android.PrebuiltEtcModule
-func (module *sdkLibraryXml) SubDir() string {
- return "permissions"
-}
-
-var _ etc.PrebuiltEtcModule = (*sdkLibraryXml)(nil)
-
-// from android.ApexModule
-func (module *sdkLibraryXml) AvailableFor(what string) bool {
- return true
-}
-
-func (module *sdkLibraryXml) DepsMutator(ctx android.BottomUpMutatorContext) {
- // do nothing
-}
-
-var _ android.ApexModule = (*sdkLibraryXml)(nil)
-
-// Implements android.ApexModule
-func (module *sdkLibraryXml) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
- // sdkLibraryXml doesn't need to be checked separately because java_sdk_library is checked
- return nil
-}
-
-// File path to the runtime implementation library
-func (module *sdkLibraryXml) implPath(ctx android.ModuleContext) string {
- implName := proptools.String(module.properties.Lib_name)
- if apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider); !apexInfo.IsForPlatform() {
- // TODO(b/146468504): ApexVariationName() is only a soong module name, not apex name.
- // In most cases, this works fine. But when apex_name is set or override_apex is used
- // this can be wrong.
- return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexInfo.BaseApexName, implName)
- }
- partition := "system"
- if module.SocSpecific() {
- partition = "vendor"
- } else if module.DeviceSpecific() {
- partition = "odm"
- } else if module.ProductSpecific() {
- partition = "product"
- } else if module.SystemExtSpecific() {
- partition = "system_ext"
- }
- return "/" + partition + "/framework/" + implName + ".jar"
-}
-
-func formattedOptionalSdkLevelAttribute(ctx android.ModuleContext, attrName string, value *string) string {
- if value == nil {
- return ""
- }
- apiLevel, err := android.ApiLevelFromUser(ctx, *value)
- if err != nil {
- // attributes in bp files have underscores but in the xml have dashes.
- ctx.PropertyErrorf(strings.ReplaceAll(attrName, "-", "_"), err.Error())
- return ""
- }
- if apiLevel.IsCurrent() {
- // passing "current" would always mean a future release, never the current (or the current in
- // progress) which means some conditions would never be triggered.
- ctx.PropertyErrorf(strings.ReplaceAll(attrName, "-", "_"),
- `"current" is not an allowed value for this attribute`)
- return ""
- }
- // "safeValue" is safe because it translates finalized codenames to a string
- // with their SDK int.
- safeValue := apiLevel.String()
- return formattedOptionalAttribute(attrName, &safeValue)
-}
-
-// formats an attribute for the xml permissions file if the value is not null
-// returns empty string otherwise
-func formattedOptionalAttribute(attrName string, value *string) string {
- if value == nil {
- return ""
- }
- return fmt.Sprintf(" %s=\"%s\"\n", attrName, *value)
-}
-
-func formattedDependenciesAttribute(dependencies []string) string {
- if dependencies == nil {
- return ""
- }
- return fmt.Sprintf(" dependency=\"%s\"\n", strings.Join(dependencies, ":"))
-}
-
-func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) string {
- libName := proptools.String(module.properties.Lib_name)
- libNameAttr := formattedOptionalAttribute("name", &libName)
- filePath := module.implPath(ctx)
- filePathAttr := formattedOptionalAttribute("file", &filePath)
- implicitFromAttr := formattedOptionalSdkLevelAttribute(ctx, "on-bootclasspath-since", module.properties.On_bootclasspath_since)
- implicitUntilAttr := formattedOptionalSdkLevelAttribute(ctx, "on-bootclasspath-before", module.properties.On_bootclasspath_before)
- minSdkAttr := formattedOptionalSdkLevelAttribute(ctx, "min-device-sdk", module.properties.Min_device_sdk)
- maxSdkAttr := formattedOptionalSdkLevelAttribute(ctx, "max-device-sdk", module.properties.Max_device_sdk)
- dependenciesAttr := formattedDependenciesAttribute(module.properties.Uses_libs_dependencies)
- // <library> is understood in all android versions whereas <apex-library> is only understood from API T (and ignored before that).
- // similarly, min_device_sdk is only understood from T. So if a library is using that, we need to use the apex-library to make sure this library is not loaded before T
- var libraryTag string
- if module.properties.Min_device_sdk != nil {
- libraryTag = " <apex-library\n"
- } else {
- libraryTag = " <library\n"
- }
-
- return strings.Join([]string{
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",
- "<!-- Copyright (C) 2018 The Android Open Source Project\n",
- "\n",
- " Licensed under the Apache License, Version 2.0 (the \"License\");\n",
- " you may not use this file except in compliance with the License.\n",
- " You may obtain a copy of the License at\n",
- "\n",
- " http://www.apache.org/licenses/LICENSE-2.0\n",
- "\n",
- " Unless required by applicable law or agreed to in writing, software\n",
- " distributed under the License is distributed on an \"AS IS\" BASIS,\n",
- " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
- " See the License for the specific language governing permissions and\n",
- " limitations under the License.\n",
- "-->\n",
- "<permissions>\n",
- libraryTag,
- libNameAttr,
- filePathAttr,
- implicitFromAttr,
- implicitUntilAttr,
- minSdkAttr,
- maxSdkAttr,
- dependenciesAttr,
- " />\n",
- "</permissions>\n",
- }, "")
-}
-
-func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
- module.hideApexVariantFromMake = !apexInfo.IsForPlatform()
-
- libName := proptools.String(module.properties.Lib_name)
- module.selfValidate(ctx)
- xmlContent := module.permissionsContents(ctx)
-
- module.outputFilePath = android.PathForModuleOut(ctx, libName+".xml").OutputPath
- android.WriteFileRuleVerbatim(ctx, module.outputFilePath, xmlContent)
-
- module.installDirPath = android.PathForModuleInstall(ctx, "etc", module.SubDir())
- ctx.PackageFile(module.installDirPath, libName+".xml", module.outputFilePath)
-
- ctx.SetOutputFiles(android.OutputPaths{module.outputFilePath}.Paths(), "")
-}
-
-func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries {
- if module.hideApexVariantFromMake {
- return []android.AndroidMkEntries{{
- Disabled: true,
- }}
- }
-
- return []android.AndroidMkEntries{{
- Class: "ETC",
- OutputFile: android.OptionalPathForPath(module.outputFilePath),
- ExtraEntries: []android.AndroidMkExtraEntriesFunc{
- func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_TAGS", "optional")
- entries.SetString("LOCAL_MODULE_PATH", module.installDirPath.String())
- entries.SetString("LOCAL_INSTALLED_MODULE_STEM", module.outputFilePath.Base())
- },
- },
- }}
-}
-
-func (module *sdkLibraryXml) selfValidate(ctx android.ModuleContext) {
- module.validateAtLeastTAttributes(ctx)
- module.validateMinAndMaxDeviceSdk(ctx)
- module.validateMinMaxDeviceSdkAndModuleMinSdk(ctx)
- module.validateOnBootclasspathBeforeRequirements(ctx)
-}
-
-func (module *sdkLibraryXml) validateAtLeastTAttributes(ctx android.ModuleContext) {
- t := android.ApiLevelOrPanic(ctx, "Tiramisu")
- module.attrAtLeastT(ctx, t, module.properties.Min_device_sdk, "min_device_sdk")
- module.attrAtLeastT(ctx, t, module.properties.Max_device_sdk, "max_device_sdk")
- module.attrAtLeastT(ctx, t, module.properties.On_bootclasspath_before, "on_bootclasspath_before")
- module.attrAtLeastT(ctx, t, module.properties.On_bootclasspath_since, "on_bootclasspath_since")
-}
-
-func (module *sdkLibraryXml) attrAtLeastT(ctx android.ModuleContext, t android.ApiLevel, attr *string, attrName string) {
- if attr != nil {
- if level, err := android.ApiLevelFromUser(ctx, *attr); err == nil {
- // we will inform the user of invalid inputs when we try to write the
- // permissions xml file so we don't need to do it here
- if t.GreaterThan(level) {
- ctx.PropertyErrorf(attrName, "Attribute value needs to be at least T")
- }
- }
- }
-}
-
-func (module *sdkLibraryXml) validateMinAndMaxDeviceSdk(ctx android.ModuleContext) {
- if module.properties.Min_device_sdk != nil && module.properties.Max_device_sdk != nil {
- min, minErr := android.ApiLevelFromUser(ctx, *module.properties.Min_device_sdk)
- max, maxErr := android.ApiLevelFromUser(ctx, *module.properties.Max_device_sdk)
- if minErr == nil && maxErr == nil {
- // we will inform the user of invalid inputs when we try to write the
- // permissions xml file so we don't need to do it here
- if min.GreaterThan(max) {
- ctx.ModuleErrorf("min_device_sdk can't be greater than max_device_sdk")
- }
- }
- }
-}
-
-func (module *sdkLibraryXml) validateMinMaxDeviceSdkAndModuleMinSdk(ctx android.ModuleContext) {
- moduleMinApi := android.ApiLevelOrPanic(ctx, *module.properties.Sdk_library_min_api_level)
- if module.properties.Min_device_sdk != nil {
- api, err := android.ApiLevelFromUser(ctx, *module.properties.Min_device_sdk)
- if err == nil {
- if moduleMinApi.GreaterThan(api) {
- ctx.PropertyErrorf("min_device_sdk", "Can't be less than module's min sdk (%s)", moduleMinApi)
- }
- }
- }
- if module.properties.Max_device_sdk != nil {
- api, err := android.ApiLevelFromUser(ctx, *module.properties.Max_device_sdk)
- if err == nil {
- if moduleMinApi.GreaterThan(api) {
- ctx.PropertyErrorf("max_device_sdk", "Can't be less than module's min sdk (%s)", moduleMinApi)
- }
- }
- }
-}
-
-func (module *sdkLibraryXml) validateOnBootclasspathBeforeRequirements(ctx android.ModuleContext) {
- moduleMinApi := android.ApiLevelOrPanic(ctx, *module.properties.Sdk_library_min_api_level)
- if module.properties.On_bootclasspath_before != nil {
- t := android.ApiLevelOrPanic(ctx, "Tiramisu")
- // if we use the attribute, then we need to do this validation
- if moduleMinApi.LessThan(t) {
- // if minAPi is < T, then we need to have min_device_sdk (which only accepts T+)
- if module.properties.Min_device_sdk == nil {
- ctx.PropertyErrorf("on_bootclasspath_before", "Using this property requires that the module's min_sdk_version or the shared library's min_device_sdk is at least T")
- }
- }
- }
-}
-
type sdkLibrarySdkMemberType struct {
android.SdkMemberTypeBase
}
@@ -3372,7 +2394,7 @@
s.Min_device_sdk = sdk.commonSdkLibraryProperties.Min_device_sdk
s.Max_device_sdk = sdk.commonSdkLibraryProperties.Max_device_sdk
- implLibrary := sdk.getImplLibraryModule()
+ implLibrary := sdk.implLibraryModule
if implLibrary != nil && implLibrary.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided {
s.DexPreoptProfileGuided = proptools.BoolPtr(true)
}
diff --git a/java/sdk_library_external.go b/java/sdk_library_external.go
deleted file mode 100644
index 4f83981..0000000
--- a/java/sdk_library_external.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2020 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 (
- "android/soong/android"
-)
-
-type partitionGroup int
-
-// Representation of partition group for checking inter-partition library dependencies.
-// Between system and system_ext, there are no restrictions of dependencies,
-// so we can treat these partitions as the same in terms of inter-partition dependency.
-// Same policy is applied between vendor and odm partiton.
-const (
- partitionGroupNone partitionGroup = iota
- // group for system, and system_ext partition
- partitionGroupSystem
- // group for vendor and odm partition
- partitionGroupVendor
- // product partition
- partitionGroupProduct
-)
-
-func (g partitionGroup) String() string {
- switch g {
- case partitionGroupSystem:
- return "system"
- case partitionGroupVendor:
- return "vendor"
- case partitionGroupProduct:
- return "product"
- }
-
- return ""
-}
-
-// Get partition group of java module that can be used at inter-partition dependency check.
-// We currently have three groups
-//
-// (system, system_ext) => system partition group
-// (vendor, odm) => vendor partition group
-// (product) => product partition group
-func (j *Module) partitionGroup(ctx android.EarlyModuleContext) partitionGroup {
- // system and system_ext partition can be treated as the same in terms of inter-partition dependency.
- if j.Platform() || j.SystemExtSpecific() {
- return partitionGroupSystem
- }
-
- // vendor and odm partition can be treated as the same in terms of inter-partition dependency.
- if j.SocSpecific() || j.DeviceSpecific() {
- return partitionGroupVendor
- }
-
- // product partition is independent.
- if j.ProductSpecific() {
- return partitionGroupProduct
- }
-
- panic("Cannot determine partition type")
-}
-
-func (j *Module) allowListedInterPartitionJavaLibrary(ctx android.EarlyModuleContext) bool {
- return inList(j.Name(), ctx.Config().InterPartitionJavaLibraryAllowList())
-}
-
-func (j *Module) syspropWithPublicStubs() bool {
- return j.deviceProperties.SyspropPublicStub != ""
-}
-
-type javaSdkLibraryEnforceContext interface {
- Name() string
- allowListedInterPartitionJavaLibrary(ctx android.EarlyModuleContext) bool
- partitionGroup(ctx android.EarlyModuleContext) partitionGroup
- syspropWithPublicStubs() bool
-}
-
-var _ javaSdkLibraryEnforceContext = (*Module)(nil)
-
-func (j *Module) checkPartitionsForJavaDependency(ctx android.EarlyModuleContext, propName string, dep javaSdkLibraryEnforceContext) {
- if dep.allowListedInterPartitionJavaLibrary(ctx) {
- return
- }
-
- if dep.syspropWithPublicStubs() {
- return
- }
-
- // If product interface is not enforced, skip check between system and product partition.
- // But still need to check between product and vendor partition because product interface flag
- // just represents enforcement between product and system, and vendor interface enforcement
- // that is enforced here by precondition is representing enforcement between vendor and other partitions.
- if !ctx.Config().EnforceProductPartitionInterface() {
- productToSystem := j.partitionGroup(ctx) == partitionGroupProduct && dep.partitionGroup(ctx) == partitionGroupSystem
- systemToProduct := j.partitionGroup(ctx) == partitionGroupSystem && dep.partitionGroup(ctx) == partitionGroupProduct
-
- if productToSystem || systemToProduct {
- return
- }
- }
-
- // If module and dependency library is inter-partition
- if j.partitionGroup(ctx) != dep.partitionGroup(ctx) {
- errorFormat := "dependency on java_library (%q) is not allowed across the partitions (%s -> %s), use java_sdk_library instead"
- ctx.PropertyErrorf(propName, errorFormat, dep.Name(), j.partitionGroup(ctx), dep.partitionGroup(ctx))
- }
-}
diff --git a/java/sdk_library_internal.go b/java/sdk_library_internal.go
new file mode 100644
index 0000000..ca088cf
--- /dev/null
+++ b/java/sdk_library_internal.go
@@ -0,0 +1,1017 @@
+// Copyright 2024 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 (
+ "android/soong/android"
+ "android/soong/etc"
+ "fmt"
+ "path"
+ "strings"
+
+ "github.com/google/blueprint/proptools"
+)
+
+// ---------------------------------------------------------------------------------------------
+// Naming scheme of the submodules generated by java_sdk_library and java_sdk_library_import
+// ---------------------------------------------------------------------------------------------
+
+const (
+ sdkXmlFileSuffix = ".xml"
+ implLibSuffix = ".impl"
+)
+
+func implLibraryModuleName(sdkLibName string) string {
+ return sdkLibName + implLibSuffix
+}
+
+// Module name of the runtime implementation library
+func (c *commonToSdkLibraryAndImport) implLibraryModuleName() string {
+ return implLibraryModuleName(c.module.RootLibraryName())
+}
+
+// Module name of the XML file for the lib
+func (c *commonToSdkLibraryAndImport) xmlPermissionsModuleName() string {
+ return c.module.RootLibraryName() + sdkXmlFileSuffix
+}
+
+// Name of the java_library module that compiles the stubs source.
+func (c *commonToSdkLibraryAndImport) stubsLibraryModuleName(apiScope *apiScope) string {
+ baseName := c.module.RootLibraryName()
+ return apiScope.stubsLibraryModuleName(baseName)
+}
+
+// Name of the java_library module that compiles the exportable stubs source.
+func (c *commonToSdkLibraryAndImport) exportableStubsLibraryModuleName(apiScope *apiScope) string {
+ baseName := c.module.RootLibraryName()
+ return apiScope.exportableStubsLibraryModuleName(baseName)
+}
+
+// Name of the droidstubs module that generates the stubs source and may also
+// generate/check the API.
+func (c *commonToSdkLibraryAndImport) droidstubsModuleName(apiScope *apiScope) string {
+ baseName := c.module.RootLibraryName()
+ return apiScope.stubsSourceModuleName(baseName)
+}
+
+// Name of the java_api_library module that generates the from-text stubs source
+// and compiles to a jar file.
+func (c *commonToSdkLibraryAndImport) fromTextStubsLibraryModuleName(apiScope *apiScope) string {
+ baseName := c.module.RootLibraryName()
+ return apiScope.apiLibraryModuleName(baseName)
+}
+
+// Name of the java_library module that compiles the stubs
+// generated from source Java files.
+func (c *commonToSdkLibraryAndImport) fromSourceStubsLibraryModuleName(apiScope *apiScope) string {
+ baseName := c.module.RootLibraryName()
+ return apiScope.sourceStubsLibraryModuleName(baseName)
+}
+
+// Name of the java_library module that compiles the exportable stubs
+// generated from source Java files.
+func (c *commonToSdkLibraryAndImport) exportableFromSourceStubsLibraryModuleName(apiScope *apiScope) string {
+ baseName := c.module.RootLibraryName()
+ return apiScope.exportableSourceStubsLibraryModuleName(baseName)
+}
+
+// ---------------------------------------------------------------------------------------------
+// Build rules of the submodules generated by java_sdk_library.
+// java_sdk_library "framework-foo" generates the following submodules:
+//
+// - "framework-foo.impl" (type: [Library]): the implementation library, which generates the
+// compilation outputs that include the implementation details and the private apis
+// (i.e. class/methods that are annotated @hide).
+//
+// - "framework-foo.stubs.source.<[apiScope.name]>" (type: [Droidstubs]): droidstubs module that
+// generates the stubs and the api files for the given api scope.
+//
+// - "framework-foo.stubs.<[apiScope.name]>" (type: [Library]): stub library module that
+// provides the compilation output of the stubs to the reverse dependencies. The module
+// itself does not perform any compilation actions; the module statically depends on one of
+// the from-source stub module or the from-text stub configuration based on the build
+// configuration.
+//
+// - "framework-foo.stubs.<[apiScope.name]>.from-source" (type: [Library]): stub library module
+// that compiles the stubs generated by the droidstubs submodule. This module is a static
+// dependency of the stub library module when
+// [android/soong/android/config.BuildFromTextStub()] is false.
+//
+// - "framework-foo.stubs.<[apiScope.name]>.from-text" (type: [ApiLibrary]): api library module
+// that generates and compiles the stubs from the api files checked in the tree instead of
+// the source Java files (e.g. *-current.txt files). This module is a static dependency of
+// the stub library module when [android/soong/android/config.BuildFromTextStub()] is true.
+//
+// - "framework-foo.stubs.exportable.<[apiScope.name]>" (type: [Library]): stub library module
+// that provides the "exportable" stubs. "exportable" stubs are the stubs that do not
+// include in-development flagged apis. This module is only used for SDK builds to generate
+// the SDK artifacts, and not purposed for consumption for other modules.
+//
+// - "framework-foo.stubs.exportable.<[apiScope.name]>.from-source" (type: [Library]): stub
+// library module that compiles the "exportable" stubs generated by the droidstubs
+// submodule. This module is always a static dependency of the "exportable" stub library
+// module given that from-text stubs cannot be used for SDK builds as it does not contain
+// documentations.
+//
+// - "framework-foo.xml" (type: [sdkLibraryXml]): xml library that generates the permission xml
+// file, which allows [SdkLibrary] to be used with <uses-permission> tag in the
+// AndroidManifest.xml files.
+// ---------------------------------------------------------------------------------------------
+
+// Creates the implementation [Library] with ".impl" suffix.
+func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext) {
+ visibility := childModuleVisibility(module.sdkLibraryProperties.Impl_library_visibility)
+
+ staticLibs := module.properties.Static_libs.Clone()
+ staticLibs.AppendSimpleValue(module.sdkLibraryProperties.Impl_only_static_libs)
+ props := struct {
+ Name *string
+ Enabled proptools.Configurable[bool]
+ Visibility []string
+ Libs []string
+ Static_libs proptools.Configurable[[]string]
+ Apex_available []string
+ Stem *string
+ }{
+ Name: proptools.StringPtr(module.implLibraryModuleName()),
+ Enabled: module.EnabledProperty(),
+ Visibility: visibility,
+
+ Libs: append(module.properties.Libs, module.sdkLibraryProperties.Impl_only_libs...),
+
+ Static_libs: staticLibs,
+ // Pass the apex_available settings down so that the impl library can be statically
+ // embedded within a library that is added to an APEX. Needed for updatable-media.
+ Apex_available: module.ApexAvailable(),
+
+ Stem: proptools.StringPtr(module.Name()),
+ }
+
+ properties := []interface{}{
+ &module.properties,
+ &module.protoProperties,
+ &module.deviceProperties,
+ &module.dexProperties,
+ &module.dexpreoptProperties,
+ &module.linter.properties,
+ &module.overridableProperties,
+ &props,
+ module.sdkComponentPropertiesForChildLibrary(),
+ }
+ mctx.CreateModule(LibraryFactory, properties...)
+}
+
+// Creates the [Droidstubs] module with ".stubs.source.<[apiScope.name]>" that creates stubs
+// source files from the given full source files and also updates and checks the API
+// specification files (i.e. "*-current.txt", "*-removed.txt" files).
+func (module *SdkLibrary) createDroidstubs(mctx android.DefaultableHookContext, apiScope *apiScope, name string, scopeSpecificDroidstubsArgs []string) {
+ props := struct {
+ Name *string
+ Enabled proptools.Configurable[bool]
+ Visibility []string
+ Srcs []string
+ Installable *bool
+ Sdk_version *string
+ Api_surface *string
+ System_modules *string
+ Libs proptools.Configurable[[]string]
+ Output_javadoc_comments *bool
+ Arg_files []string
+ Args *string
+ Java_version *string
+ Annotations_enabled *bool
+ Merge_annotations_dirs []string
+ Merge_inclusion_annotations_dirs []string
+ Generate_stubs *bool
+ Previous_api *string
+ Aconfig_declarations []string
+ Check_api struct {
+ Current ApiToCheck
+ Last_released ApiToCheck
+
+ Api_lint struct {
+ Enabled *bool
+ New_since *string
+ Baseline_file *string
+ }
+ }
+ Aidl struct {
+ Include_dirs []string
+ Local_include_dirs []string
+ }
+ Dists []android.Dist
+ }{}
+
+ // The stubs source processing uses the same compile time classpath when extracting the
+ // API from the implementation library as it does when compiling it. i.e. the same
+ // * sdk version
+ // * system_modules
+ // * libs (static_libs/libs)
+
+ props.Name = proptools.StringPtr(name)
+ props.Enabled = module.EnabledProperty()
+ props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_source_visibility)
+ props.Srcs = append(props.Srcs, module.properties.Srcs...)
+ props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
+ props.Sdk_version = module.deviceProperties.Sdk_version
+ props.Api_surface = &apiScope.name
+ props.System_modules = module.deviceProperties.System_modules
+ props.Installable = proptools.BoolPtr(false)
+ // A droiddoc module has only one Libs property and doesn't distinguish between
+ // shared libs and static libs. So we need to add both of these libs to Libs property.
+ props.Libs = proptools.NewConfigurable[[]string](nil, nil)
+ props.Libs.AppendSimpleValue(module.properties.Libs)
+ props.Libs.Append(module.properties.Static_libs)
+ props.Libs.AppendSimpleValue(module.sdkLibraryProperties.Stub_only_libs)
+ props.Libs.AppendSimpleValue(module.scopeToProperties[apiScope].Libs)
+ props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
+ props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
+ props.Java_version = module.properties.Java_version
+
+ props.Annotations_enabled = module.sdkLibraryProperties.Annotations_enabled
+ props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
+ props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
+ props.Aconfig_declarations = module.sdkLibraryProperties.Aconfig_declarations
+
+ droidstubsArgs := []string{}
+ if len(module.sdkLibraryProperties.Api_packages) != 0 {
+ droidstubsArgs = append(droidstubsArgs, "--stub-packages "+strings.Join(module.sdkLibraryProperties.Api_packages, ":"))
+ }
+ droidstubsArgs = append(droidstubsArgs, module.sdkLibraryProperties.Droiddoc_options...)
+ disabledWarnings := []string{"HiddenSuperclass"}
+ if proptools.BoolDefault(module.sdkLibraryProperties.Api_lint.Legacy_errors_allowed, true) {
+ disabledWarnings = append(disabledWarnings,
+ "BroadcastBehavior",
+ "DeprecationMismatch",
+ "MissingPermission",
+ "SdkConstant",
+ "Todo",
+ )
+ }
+ droidstubsArgs = append(droidstubsArgs, android.JoinWithPrefix(disabledWarnings, "--hide "))
+
+ // Output Javadoc comments for public scope.
+ if apiScope == apiScopePublic {
+ props.Output_javadoc_comments = proptools.BoolPtr(true)
+ }
+
+ // Add in scope specific arguments.
+ droidstubsArgs = append(droidstubsArgs, scopeSpecificDroidstubsArgs...)
+ props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
+ props.Args = proptools.StringPtr(strings.Join(droidstubsArgs, " "))
+
+ // List of APIs identified from the provided source files are created. They are later
+ // compared against to the not-yet-released (a.k.a current) list of APIs and to the
+ // last-released (a.k.a numbered) list of API.
+ currentApiFileName := apiScope.apiFilePrefix + "current.txt"
+ removedApiFileName := apiScope.apiFilePrefix + "removed.txt"
+ apiDir := module.getApiDir()
+ currentApiFileName = path.Join(apiDir, currentApiFileName)
+ removedApiFileName = path.Join(apiDir, removedApiFileName)
+
+ // check against the not-yet-release API
+ props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
+ props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
+
+ if module.compareAgainstLatestApi(apiScope) {
+ // check against the latest released API
+ latestApiFilegroupName := proptools.StringPtr(module.latestApiFilegroupName(apiScope))
+ props.Previous_api = latestApiFilegroupName
+ props.Check_api.Last_released.Api_file = latestApiFilegroupName
+ props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
+ module.latestRemovedApiFilegroupName(apiScope))
+ props.Check_api.Last_released.Baseline_file = proptools.StringPtr(
+ module.latestIncompatibilitiesFilegroupName(apiScope))
+
+ if proptools.Bool(module.sdkLibraryProperties.Api_lint.Enabled) {
+ // Enable api lint.
+ props.Check_api.Api_lint.Enabled = proptools.BoolPtr(true)
+ props.Check_api.Api_lint.New_since = latestApiFilegroupName
+
+ // If it exists then pass a lint-baseline.txt through to droidstubs.
+ baselinePath := path.Join(apiDir, apiScope.apiFilePrefix+"lint-baseline.txt")
+ baselinePathRelativeToRoot := path.Join(mctx.ModuleDir(), baselinePath)
+ paths, err := mctx.GlobWithDeps(baselinePathRelativeToRoot, nil)
+ if err != nil {
+ mctx.ModuleErrorf("error checking for presence of %s: %s", baselinePathRelativeToRoot, err)
+ }
+ if len(paths) == 1 {
+ props.Check_api.Api_lint.Baseline_file = proptools.StringPtr(baselinePath)
+ } else if len(paths) != 0 {
+ mctx.ModuleErrorf("error checking for presence of %s: expected one path, found: %v", baselinePathRelativeToRoot, paths)
+ }
+ }
+ }
+
+ if !Bool(module.sdkLibraryProperties.No_dist) {
+ // Dist the api txt and removed api txt artifacts for sdk builds.
+ distDir := proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
+ stubsTypeTagPrefix := ""
+ if mctx.Config().ReleaseHiddenApiExportableStubs() {
+ stubsTypeTagPrefix = ".exportable"
+ }
+ for _, p := range []struct {
+ tag string
+ pattern string
+ }{
+ // "exportable" api files are copied to the dist directory instead of the
+ // "everything" api files when "RELEASE_HIDDEN_API_EXPORTABLE_STUBS" build flag
+ // is set. Otherwise, the "everything" api files are copied to the dist directory.
+ {tag: "%s.api.txt", pattern: "%s.txt"},
+ {tag: "%s.removed-api.txt", pattern: "%s-removed.txt"},
+ } {
+ props.Dists = append(props.Dists, android.Dist{
+ Targets: []string{"sdk", "win_sdk"},
+ Dir: distDir,
+ Dest: proptools.StringPtr(fmt.Sprintf(p.pattern, module.distStem())),
+ Tag: proptools.StringPtr(fmt.Sprintf(p.tag, stubsTypeTagPrefix)),
+ })
+ }
+ }
+
+ mctx.CreateModule(DroidstubsFactory, &props, module.sdkComponentPropertiesForChildLibrary()).(*Droidstubs).CallHookIfAvailable(mctx)
+}
+
+type libraryProperties struct {
+ Name *string
+ Enabled proptools.Configurable[bool]
+ Visibility []string
+ Srcs []string
+ Installable *bool
+ Sdk_version *string
+ System_modules *string
+ Patch_module *string
+ Libs []string
+ Static_libs []string
+ Compile_dex *bool
+ Java_version *string
+ Openjdk9 struct {
+ Srcs []string
+ Javacflags []string
+ }
+ Dist struct {
+ Targets []string
+ Dest *string
+ Dir *string
+ Tag *string
+ }
+ Is_stubs_module *bool
+ Stub_contributing_api *string
+}
+
+func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
+ props := libraryProperties{}
+ props.Enabled = module.EnabledProperty()
+ props.Visibility = []string{"//visibility:override", "//visibility:private"}
+ // sources are generated from the droiddoc
+ sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
+ props.Sdk_version = proptools.StringPtr(sdkVersion)
+ props.System_modules = module.deviceProperties.System_modules
+ props.Patch_module = module.properties.Patch_module
+ props.Installable = proptools.BoolPtr(false)
+ props.Libs = module.sdkLibraryProperties.Stub_only_libs
+ props.Libs = append(props.Libs, module.scopeToProperties[apiScope].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) {
+ props.Libs = append(props.Libs, "stub-annotations")
+ }
+ props.Openjdk9.Srcs = module.properties.Openjdk9.Srcs
+ props.Openjdk9.Javacflags = module.properties.Openjdk9.Javacflags
+ // We compile the stubs for 1.8 in line with the main android.jar stubs, and potential
+ // interop with older developer tools that don't support 1.9.
+ props.Java_version = proptools.StringPtr("1.8")
+ props.Is_stubs_module = proptools.BoolPtr(true)
+ props.Stub_contributing_api = proptools.StringPtr(apiScope.kind.String())
+
+ return props
+}
+
+// Creates the from-source stub [Library] with ".stubs.<[apiScope.name]>.from-source" suffix.
+func (module *SdkLibrary) createFromSourceStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
+
+ props := module.stubsLibraryProps(mctx, apiScope)
+ props.Name = proptools.StringPtr(module.fromSourceStubsLibraryModuleName(apiScope))
+ props.Srcs = []string{":" + module.droidstubsModuleName(apiScope)}
+
+ mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
+}
+
+// Creates the "exportable" from-source stub [Library] with
+// ".stubs.exportable.<[apiScope.name]>" suffix.
+func (module *SdkLibrary) createExportableFromSourceStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
+ props := module.stubsLibraryProps(mctx, apiScope)
+ props.Name = proptools.StringPtr(module.exportableFromSourceStubsLibraryModuleName(apiScope))
+ props.Srcs = []string{":" + module.droidstubsModuleName(apiScope) + "{.exportable}"}
+
+ mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
+}
+
+// Creates the from-text stub [ApiLibrary] with ".stubs.<[apiScope.name]>.from-text" suffix.
+func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
+ props := struct {
+ Name *string
+ Enabled proptools.Configurable[bool]
+ Visibility []string
+ Api_contributions []string
+ Libs proptools.Configurable[[]string]
+ Static_libs []string
+ System_modules *string
+ Enable_validation *bool
+ Stubs_type *string
+ Sdk_version *string
+ Previous_api *string
+ }{}
+
+ props.Name = proptools.StringPtr(module.fromTextStubsLibraryModuleName(apiScope))
+ props.Enabled = module.EnabledProperty()
+ props.Visibility = []string{"//visibility:override", "//visibility:private"}
+
+ apiContributions := []string{}
+
+ // Api surfaces are not independent of each other, but have subset relationships,
+ // and so does the api files. To generate from-text stubs for api surfaces other than public,
+ // all subset api domains' api_contriubtions must be added as well.
+ scope := apiScope
+ for scope != nil {
+ apiContributions = append(apiContributions, module.droidstubsModuleName(scope)+".api.contribution")
+ scope = scope.extends
+ }
+ if apiScope == apiScopePublic {
+ additionalApiContribution := module.apiLibraryAdditionalApiContribution()
+ if additionalApiContribution != "" {
+ apiContributions = append(apiContributions, additionalApiContribution)
+ }
+ }
+
+ props.Api_contributions = apiContributions
+
+ // Ensure that stub-annotations is added to the classpath before any other libs
+ props.Libs = proptools.NewConfigurable[[]string](nil, nil)
+ props.Libs.AppendSimpleValue([]string{"stub-annotations"})
+ props.Libs.AppendSimpleValue(module.properties.Libs)
+ props.Libs.Append(module.properties.Static_libs)
+ props.Libs.AppendSimpleValue(module.sdkLibraryProperties.Stub_only_libs)
+ props.Libs.AppendSimpleValue(module.scopeToProperties[apiScope].Libs)
+ props.Static_libs = module.sdkLibraryProperties.Stub_only_static_libs
+
+ props.System_modules = module.deviceProperties.System_modules
+ props.Enable_validation = proptools.BoolPtr(true)
+ props.Stubs_type = proptools.StringPtr("everything")
+
+ if module.deviceProperties.Sdk_version != nil {
+ props.Sdk_version = module.deviceProperties.Sdk_version
+ }
+
+ if module.compareAgainstLatestApi(apiScope) {
+ // check against the latest released API
+ latestApiFilegroupName := proptools.StringPtr(module.latestApiFilegroupName(apiScope))
+ props.Previous_api = latestApiFilegroupName
+ }
+
+ mctx.CreateModule(ApiLibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
+}
+
+func (module *SdkLibrary) topLevelStubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope, doDist bool) libraryProperties {
+ props := libraryProperties{}
+
+ props.Enabled = module.EnabledProperty()
+ props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
+ sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
+ props.Sdk_version = proptools.StringPtr(sdkVersion)
+
+ props.System_modules = module.deviceProperties.System_modules
+
+ // The imports need to be compiled to dex if the java_sdk_library requests it.
+ compileDex := module.dexProperties.Compile_dex
+ if module.stubLibrariesCompiledForDex() {
+ compileDex = proptools.BoolPtr(true)
+ }
+ props.Compile_dex = compileDex
+
+ props.Stub_contributing_api = proptools.StringPtr(apiScope.kind.String())
+
+ if !Bool(module.sdkLibraryProperties.No_dist) && doDist {
+ props.Dist.Targets = []string{"sdk", "win_sdk"}
+ props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.distStem()))
+ props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
+ props.Dist.Tag = proptools.StringPtr(".jar")
+ }
+ props.Is_stubs_module = proptools.BoolPtr(true)
+
+ return props
+}
+
+// Creates the stub [Library] with ".stubs.<[apiScope.name]>" suffix.
+func (module *SdkLibrary) createTopLevelStubsLibrary(
+ mctx android.DefaultableHookContext, apiScope *apiScope) {
+
+ // Dist the "everything" stubs when the RELEASE_HIDDEN_API_EXPORTABLE_STUBS build flag is false
+ doDist := !mctx.Config().ReleaseHiddenApiExportableStubs()
+ props := module.topLevelStubsLibraryProps(mctx, apiScope, doDist)
+ props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
+
+ // Add the stub compiling java_library/java_api_library as static lib based on build config
+ staticLib := module.fromSourceStubsLibraryModuleName(apiScope)
+ if mctx.Config().BuildFromTextStub() && module.ModuleBuildFromTextStubs() {
+ staticLib = module.fromTextStubsLibraryModuleName(apiScope)
+ }
+ props.Static_libs = append(props.Static_libs, staticLib)
+
+ mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
+}
+
+// Creates the "exportable" stub [Library] with ".stubs.exportable.<[apiScope.name]>" suffix.
+func (module *SdkLibrary) createTopLevelExportableStubsLibrary(
+ mctx android.DefaultableHookContext, apiScope *apiScope) {
+
+ // Dist the "exportable" stubs when the RELEASE_HIDDEN_API_EXPORTABLE_STUBS build flag is true
+ doDist := mctx.Config().ReleaseHiddenApiExportableStubs()
+ props := module.topLevelStubsLibraryProps(mctx, apiScope, doDist)
+ props.Name = proptools.StringPtr(module.exportableStubsLibraryModuleName(apiScope))
+
+ staticLib := module.exportableFromSourceStubsLibraryModuleName(apiScope)
+ props.Static_libs = append(props.Static_libs, staticLib)
+
+ mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
+}
+
+// Creates the [sdkLibraryXml] with ".xml" suffix.
+func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) {
+ moduleMinApiLevel := module.Library.MinSdkVersion(mctx)
+ var moduleMinApiLevelStr = moduleMinApiLevel.String()
+ if moduleMinApiLevel == android.NoneApiLevel {
+ moduleMinApiLevelStr = "current"
+ }
+ props := struct {
+ Name *string
+ Enabled proptools.Configurable[bool]
+ Lib_name *string
+ Apex_available []string
+ On_bootclasspath_since *string
+ On_bootclasspath_before *string
+ Min_device_sdk *string
+ Max_device_sdk *string
+ Sdk_library_min_api_level *string
+ Uses_libs_dependencies []string
+ }{
+ Name: proptools.StringPtr(module.xmlPermissionsModuleName()),
+ Enabled: module.EnabledProperty(),
+ Lib_name: proptools.StringPtr(module.BaseModuleName()),
+ Apex_available: module.ApexProperties.Apex_available,
+ On_bootclasspath_since: module.commonSdkLibraryProperties.On_bootclasspath_since,
+ On_bootclasspath_before: module.commonSdkLibraryProperties.On_bootclasspath_before,
+ Min_device_sdk: module.commonSdkLibraryProperties.Min_device_sdk,
+ Max_device_sdk: module.commonSdkLibraryProperties.Max_device_sdk,
+ Sdk_library_min_api_level: &moduleMinApiLevelStr,
+ Uses_libs_dependencies: module.usesLibraryProperties.Uses_libs,
+ }
+
+ mctx.CreateModule(sdkLibraryXmlFactory, &props)
+}
+
+// ---------------------------------------------------------------------------------------------
+// Build rules of the submodules generated by java_sdk_library_import.
+// Note that the java_sdk_library_import module does not generate the implementation library.
+// Instead, it will create a dependency to the source implemenetation library if one exists.
+// java_sdk_library_import "framework-foo" generates the following submodules:
+//
+// - "framework-foo.stubs.<[apiScope.name]>" (type: [Import]): prebuilt stub library module that
+// provides the stub jar file checked in the tree.
+//
+// - "framework-foo.stubs.source.<[apiScope.name]>" (type: [PrebuiltStubsSources]): prebuilt
+// droidstubs module that provides the stub source jar file checked in the tree.
+//
+// - "framework-foo.stubs.source.<[apiScope.name]>.api.contribution"
+// (type [JavaApiContributionImport]): prebuilt java_api_contribution module that provides
+// the prebuilt api file for previously released from-text stub generation.
+// ---------------------------------------------------------------------------------------------
+
+// Creates the prebuilt stub [Import] with ".stubs.<[apiScope.name]>" suffix.
+func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
+ // Creates a java import for the jar with ".stubs" suffix
+ props := struct {
+ Name *string
+ Source_module_name *string
+ Created_by_java_sdk_library_name *string
+ Sdk_version *string
+ Libs []string
+ Jars []string
+ Compile_dex *bool
+ Is_stubs_module *bool
+
+ android.UserSuppliedPrebuiltProperties
+ }{}
+ props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
+ props.Source_module_name = proptools.StringPtr(apiScope.stubsLibraryModuleName(module.BaseModuleName()))
+ props.Created_by_java_sdk_library_name = proptools.StringPtr(module.RootLibraryName())
+ props.Sdk_version = scopeProperties.Sdk_version
+ // Prepend any of the libs from the legacy public properties to the libs for each of the
+ // scopes to avoid having to duplicate them in each scope.
+ props.Libs = append(module.properties.Libs, scopeProperties.Libs...)
+ props.Jars = scopeProperties.Jars
+
+ // The imports are preferred if the java_sdk_library_import is preferred.
+ props.CopyUserSuppliedPropertiesFromPrebuilt(&module.prebuilt)
+
+ // The imports need to be compiled to dex if the java_sdk_library_import requests it.
+ compileDex := module.properties.Compile_dex
+ if module.stubLibrariesCompiledForDex() {
+ compileDex = proptools.BoolPtr(true)
+ }
+ props.Compile_dex = compileDex
+ props.Is_stubs_module = proptools.BoolPtr(true)
+
+ mctx.CreateModule(ImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
+}
+
+func (module *SdkLibraryImport) createPrebuiltStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
+ props := struct {
+ Name *string
+ Source_module_name *string
+ Created_by_java_sdk_library_name *string
+ Srcs []string
+
+ android.UserSuppliedPrebuiltProperties
+ }{}
+ props.Name = proptools.StringPtr(module.droidstubsModuleName(apiScope))
+ props.Source_module_name = proptools.StringPtr(apiScope.stubsSourceModuleName(module.BaseModuleName()))
+ props.Created_by_java_sdk_library_name = proptools.StringPtr(module.RootLibraryName())
+ props.Srcs = scopeProperties.Stub_srcs
+
+ // The stubs source is preferred if the java_sdk_library_import is preferred.
+ props.CopyUserSuppliedPropertiesFromPrebuilt(&module.prebuilt)
+
+ mctx.CreateModule(PrebuiltStubsSourcesFactory, &props, module.sdkComponentPropertiesForChildLibrary())
+}
+
+// Creates the prebuilt api contribution [JavaApiContributionImport] with
+// ".stubs.source.<[apiScope.name]>.api.contribution" suffix.
+func (module *SdkLibraryImport) createPrebuiltApiContribution(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
+ api_file := scopeProperties.Current_api
+ api_surface := &apiScope.name
+
+ props := struct {
+ Name *string
+ Source_module_name *string
+ Created_by_java_sdk_library_name *string
+ Api_surface *string
+ Api_file *string
+ Visibility []string
+ }{}
+
+ props.Name = proptools.StringPtr(module.droidstubsModuleName(apiScope) + ".api.contribution")
+ props.Source_module_name = proptools.StringPtr(apiScope.stubsSourceModuleName(module.BaseModuleName()) + ".api.contribution")
+ props.Created_by_java_sdk_library_name = proptools.StringPtr(module.RootLibraryName())
+ props.Api_surface = api_surface
+ props.Api_file = api_file
+ props.Visibility = []string{"//visibility:override", "//visibility:public"}
+
+ mctx.CreateModule(ApiContributionImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
+}
+
+// ---------------------------------------------------------------------------------------------
+// End of the build rules of the submodules generated by java_sdk_library_import.
+// ---------------------------------------------------------------------------------------------
+
+// Definition of the [sdkLibraryXml] module. The module generates the permissions xml file,
+// so that the apps can specify the java_sdk_library using <uses-permission> tag in the
+// AndroidManifest.xml file.
+type sdkLibraryXml struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+ android.ApexModuleBase
+
+ properties sdkLibraryXmlProperties
+
+ outputFilePath android.OutputPath
+ installDirPath android.InstallPath
+
+ hideApexVariantFromMake bool
+}
+
+type sdkLibraryXmlProperties struct {
+ // canonical name of the lib
+ Lib_name *string
+
+ // Signals that this shared library is part of the bootclasspath starting
+ // on the version indicated in this attribute.
+ //
+ // This will make platforms at this level and above to ignore
+ // <uses-library> tags with this library name because the library is already
+ // available
+ On_bootclasspath_since *string
+
+ // Signals that this shared library was part of the bootclasspath before
+ // (but not including) the version indicated in this attribute.
+ //
+ // The system will automatically add a <uses-library> tag with this library to
+ // apps that target any SDK less than the version indicated in this attribute.
+ On_bootclasspath_before *string
+
+ // Indicates that PackageManager should ignore this shared library if the
+ // platform is below the version indicated in this attribute.
+ //
+ // This means that the device won't recognise this library as installed.
+ Min_device_sdk *string
+
+ // Indicates that PackageManager should ignore this shared library if the
+ // platform is above the version indicated in this attribute.
+ //
+ // This means that the device won't recognise this library as installed.
+ Max_device_sdk *string
+
+ // The SdkLibrary's min api level as a string
+ //
+ // This value comes from the ApiLevel of the MinSdkVersion property.
+ Sdk_library_min_api_level *string
+
+ // Uses-libs dependencies that the shared library requires to work correctly.
+ //
+ // This will add dependency="foo:bar" to the <library> section.
+ Uses_libs_dependencies []string
+}
+
+// java_sdk_library_xml builds the permission xml file for a java_sdk_library.
+// Not to be used directly by users. java_sdk_library internally uses this.
+func sdkLibraryXmlFactory() android.Module {
+ module := &sdkLibraryXml{}
+
+ module.AddProperties(&module.properties)
+
+ android.InitApexModule(module)
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+
+ return module
+}
+
+func (module *sdkLibraryXml) UniqueApexVariations() bool {
+ // sdkLibraryXml needs a unique variation per APEX because the generated XML file contains the path to the
+ // mounted APEX, which contains the name of the APEX.
+ return true
+}
+
+// from android.PrebuiltEtcModule
+func (module *sdkLibraryXml) BaseDir() string {
+ return "etc"
+}
+
+// from android.PrebuiltEtcModule
+func (module *sdkLibraryXml) SubDir() string {
+ return "permissions"
+}
+
+var _ etc.PrebuiltEtcModule = (*sdkLibraryXml)(nil)
+
+// from android.ApexModule
+func (module *sdkLibraryXml) AvailableFor(what string) bool {
+ return true
+}
+
+func (module *sdkLibraryXml) DepsMutator(ctx android.BottomUpMutatorContext) {
+ // do nothing
+}
+
+var _ android.ApexModule = (*sdkLibraryXml)(nil)
+
+// Implements android.ApexModule
+func (module *sdkLibraryXml) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
+ sdkVersion android.ApiLevel) error {
+ // sdkLibraryXml doesn't need to be checked separately because java_sdk_library is checked
+ return nil
+}
+
+// File path to the runtime implementation library
+func (module *sdkLibraryXml) implPath(ctx android.ModuleContext) string {
+ implName := proptools.String(module.properties.Lib_name)
+ if apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider); !apexInfo.IsForPlatform() {
+ // TODO(b/146468504): ApexVariationName() is only a soong module name, not apex name.
+ // In most cases, this works fine. But when apex_name is set or override_apex is used
+ // this can be wrong.
+ return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexInfo.BaseApexName, implName)
+ }
+ partition := "system"
+ if module.SocSpecific() {
+ partition = "vendor"
+ } else if module.DeviceSpecific() {
+ partition = "odm"
+ } else if module.ProductSpecific() {
+ partition = "product"
+ } else if module.SystemExtSpecific() {
+ partition = "system_ext"
+ }
+ return "/" + partition + "/framework/" + implName + ".jar"
+}
+
+func formattedOptionalSdkLevelAttribute(ctx android.ModuleContext, attrName string, value *string) string {
+ if value == nil {
+ return ""
+ }
+ apiLevel, err := android.ApiLevelFromUser(ctx, *value)
+ if err != nil {
+ // attributes in bp files have underscores but in the xml have dashes.
+ ctx.PropertyErrorf(strings.ReplaceAll(attrName, "-", "_"), err.Error())
+ return ""
+ }
+ if apiLevel.IsCurrent() {
+ // passing "current" would always mean a future release, never the current (or the current in
+ // progress) which means some conditions would never be triggered.
+ ctx.PropertyErrorf(strings.ReplaceAll(attrName, "-", "_"),
+ `"current" is not an allowed value for this attribute`)
+ return ""
+ }
+ // "safeValue" is safe because it translates finalized codenames to a string
+ // with their SDK int.
+ safeValue := apiLevel.String()
+ return formattedOptionalAttribute(attrName, &safeValue)
+}
+
+// formats an attribute for the xml permissions file if the value is not null
+// returns empty string otherwise
+func formattedOptionalAttribute(attrName string, value *string) string {
+ if value == nil {
+ return ""
+ }
+ return fmt.Sprintf(" %s=\"%s\"\n", attrName, *value)
+}
+
+func formattedDependenciesAttribute(dependencies []string) string {
+ if dependencies == nil {
+ return ""
+ }
+ return fmt.Sprintf(" dependency=\"%s\"\n", strings.Join(dependencies, ":"))
+}
+
+func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) string {
+ libName := proptools.String(module.properties.Lib_name)
+ libNameAttr := formattedOptionalAttribute("name", &libName)
+ filePath := module.implPath(ctx)
+ filePathAttr := formattedOptionalAttribute("file", &filePath)
+ implicitFromAttr := formattedOptionalSdkLevelAttribute(ctx, "on-bootclasspath-since", module.properties.On_bootclasspath_since)
+ implicitUntilAttr := formattedOptionalSdkLevelAttribute(ctx, "on-bootclasspath-before", module.properties.On_bootclasspath_before)
+ minSdkAttr := formattedOptionalSdkLevelAttribute(ctx, "min-device-sdk", module.properties.Min_device_sdk)
+ maxSdkAttr := formattedOptionalSdkLevelAttribute(ctx, "max-device-sdk", module.properties.Max_device_sdk)
+ dependenciesAttr := formattedDependenciesAttribute(module.properties.Uses_libs_dependencies)
+ // <library> is understood in all android versions whereas <apex-library> is only understood from API T (and ignored before that).
+ // similarly, min_device_sdk is only understood from T. So if a library is using that, we need to use the apex-library to make sure this library is not loaded before T
+ var libraryTag string
+ if module.properties.Min_device_sdk != nil {
+ libraryTag = " <apex-library\n"
+ } else {
+ libraryTag = " <library\n"
+ }
+
+ return strings.Join([]string{
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",
+ "<!-- Copyright (C) 2018 The Android Open Source Project\n",
+ "\n",
+ " Licensed under the Apache License, Version 2.0 (the \"License\");\n",
+ " you may not use this file except in compliance with the License.\n",
+ " You may obtain a copy of the License at\n",
+ "\n",
+ " http://www.apache.org/licenses/LICENSE-2.0\n",
+ "\n",
+ " Unless required by applicable law or agreed to in writing, software\n",
+ " distributed under the License is distributed on an \"AS IS\" BASIS,\n",
+ " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
+ " See the License for the specific language governing permissions and\n",
+ " limitations under the License.\n",
+ "-->\n",
+ "<permissions>\n",
+ libraryTag,
+ libNameAttr,
+ filePathAttr,
+ implicitFromAttr,
+ implicitUntilAttr,
+ minSdkAttr,
+ maxSdkAttr,
+ dependenciesAttr,
+ " />\n",
+ "</permissions>\n",
+ }, "")
+}
+
+func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
+ module.hideApexVariantFromMake = !apexInfo.IsForPlatform()
+
+ libName := proptools.String(module.properties.Lib_name)
+ module.selfValidate(ctx)
+ xmlContent := module.permissionsContents(ctx)
+
+ module.outputFilePath = android.PathForModuleOut(ctx, libName+".xml").OutputPath
+ android.WriteFileRuleVerbatim(ctx, module.outputFilePath, xmlContent)
+
+ module.installDirPath = android.PathForModuleInstall(ctx, "etc", module.SubDir())
+ ctx.PackageFile(module.installDirPath, libName+".xml", module.outputFilePath)
+
+ ctx.SetOutputFiles(android.OutputPaths{module.outputFilePath}.Paths(), "")
+}
+
+func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries {
+ if module.hideApexVariantFromMake {
+ return []android.AndroidMkEntries{{
+ Disabled: true,
+ }}
+ }
+
+ return []android.AndroidMkEntries{{
+ Class: "ETC",
+ OutputFile: android.OptionalPathForPath(module.outputFilePath),
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.SetString("LOCAL_MODULE_TAGS", "optional")
+ entries.SetString("LOCAL_MODULE_PATH", module.installDirPath.String())
+ entries.SetString("LOCAL_INSTALLED_MODULE_STEM", module.outputFilePath.Base())
+ },
+ },
+ }}
+}
+
+func (module *sdkLibraryXml) selfValidate(ctx android.ModuleContext) {
+ module.validateAtLeastTAttributes(ctx)
+ module.validateMinAndMaxDeviceSdk(ctx)
+ module.validateMinMaxDeviceSdkAndModuleMinSdk(ctx)
+ module.validateOnBootclasspathBeforeRequirements(ctx)
+}
+
+func (module *sdkLibraryXml) validateAtLeastTAttributes(ctx android.ModuleContext) {
+ t := android.ApiLevelOrPanic(ctx, "Tiramisu")
+ module.attrAtLeastT(ctx, t, module.properties.Min_device_sdk, "min_device_sdk")
+ module.attrAtLeastT(ctx, t, module.properties.Max_device_sdk, "max_device_sdk")
+ module.attrAtLeastT(ctx, t, module.properties.On_bootclasspath_before, "on_bootclasspath_before")
+ module.attrAtLeastT(ctx, t, module.properties.On_bootclasspath_since, "on_bootclasspath_since")
+}
+
+func (module *sdkLibraryXml) attrAtLeastT(ctx android.ModuleContext, t android.ApiLevel, attr *string, attrName string) {
+ if attr != nil {
+ if level, err := android.ApiLevelFromUser(ctx, *attr); err == nil {
+ // we will inform the user of invalid inputs when we try to write the
+ // permissions xml file so we don't need to do it here
+ if t.GreaterThan(level) {
+ ctx.PropertyErrorf(attrName, "Attribute value needs to be at least T")
+ }
+ }
+ }
+}
+
+func (module *sdkLibraryXml) validateMinAndMaxDeviceSdk(ctx android.ModuleContext) {
+ if module.properties.Min_device_sdk != nil && module.properties.Max_device_sdk != nil {
+ min, minErr := android.ApiLevelFromUser(ctx, *module.properties.Min_device_sdk)
+ max, maxErr := android.ApiLevelFromUser(ctx, *module.properties.Max_device_sdk)
+ if minErr == nil && maxErr == nil {
+ // we will inform the user of invalid inputs when we try to write the
+ // permissions xml file so we don't need to do it here
+ if min.GreaterThan(max) {
+ ctx.ModuleErrorf("min_device_sdk can't be greater than max_device_sdk")
+ }
+ }
+ }
+}
+
+func (module *sdkLibraryXml) validateMinMaxDeviceSdkAndModuleMinSdk(ctx android.ModuleContext) {
+ moduleMinApi := android.ApiLevelOrPanic(ctx, *module.properties.Sdk_library_min_api_level)
+ if module.properties.Min_device_sdk != nil {
+ api, err := android.ApiLevelFromUser(ctx, *module.properties.Min_device_sdk)
+ if err == nil {
+ if moduleMinApi.GreaterThan(api) {
+ ctx.PropertyErrorf("min_device_sdk", "Can't be less than module's min sdk (%s)", moduleMinApi)
+ }
+ }
+ }
+ if module.properties.Max_device_sdk != nil {
+ api, err := android.ApiLevelFromUser(ctx, *module.properties.Max_device_sdk)
+ if err == nil {
+ if moduleMinApi.GreaterThan(api) {
+ ctx.PropertyErrorf("max_device_sdk", "Can't be less than module's min sdk (%s)", moduleMinApi)
+ }
+ }
+ }
+}
+
+func (module *sdkLibraryXml) validateOnBootclasspathBeforeRequirements(ctx android.ModuleContext) {
+ moduleMinApi := android.ApiLevelOrPanic(ctx, *module.properties.Sdk_library_min_api_level)
+ if module.properties.On_bootclasspath_before != nil {
+ t := android.ApiLevelOrPanic(ctx, "Tiramisu")
+ // if we use the attribute, then we need to do this validation
+ if moduleMinApi.LessThan(t) {
+ // if minAPi is < T, then we need to have min_device_sdk (which only accepts T+)
+ if module.properties.Min_device_sdk == nil {
+ ctx.PropertyErrorf("on_bootclasspath_before", "Using this property requires that the module's min_sdk_version or the shared library's min_device_sdk is at least T")
+ }
+ }
+ }
+}
diff --git a/java/testing.go b/java/testing.go
index 0c79e9f..d5a19e9 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -388,7 +388,6 @@
RegisterStubsBuildComponents(ctx)
RegisterSystemModulesBuildComponents(ctx)
registerSystemserverClasspathBuildComponents(ctx)
- registerLintBuildComponents(ctx)
android.RegisterApexContributionsBuildComponents(ctx)
}
@@ -424,7 +423,9 @@
"kotlin-stdlib-jdk8",
"kotlin-annotations",
"stub-annotations",
+
"aconfig-annotations-lib",
+ "aconfig_storage_reader_java",
"unsupportedappusage",
}
diff --git a/rust/config/x86_64_device.go b/rust/config/x86_64_device.go
index fee1923..3c484d8 100644
--- a/rust/config/x86_64_device.go
+++ b/rust/config/x86_64_device.go
@@ -29,6 +29,7 @@
x86_64ArchVariantRustFlags = map[string][]string{
"": []string{},
+ "alderlake": []string{"-C target-cpu=alderlake"},
"broadwell": []string{"-C target-cpu=broadwell"},
"goldmont": []string{"-C target-cpu=goldmont"},
"goldmont-plus": []string{"-C target-cpu=goldmont-plus"},
diff --git a/rust/config/x86_device.go b/rust/config/x86_device.go
index 5d9d88a..3c597cc 100644
--- a/rust/config/x86_device.go
+++ b/rust/config/x86_device.go
@@ -27,6 +27,7 @@
x86ArchVariantRustFlags = map[string][]string{
"": []string{},
+ "alderlake": []string{"-C target-cpu=alderlake"},
"atom": []string{"-C target-cpu=atom"},
"broadwell": []string{"-C target-cpu=broadwell"},
"goldmont": []string{"-C target-cpu=goldmont"},
diff --git a/scripts/Android.bp b/scripts/Android.bp
index 3d81b83..00b3ca5 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -184,12 +184,21 @@
libs: ["ninja_rsp"],
}
-python_test_host {
- name: "lint_project_xml_test",
- main: "lint_project_xml_test.py",
+python_binary_host {
+ name: "lint_strict_updatability_checks",
+ main: "lint_strict_updatability_checks.py",
srcs: [
- "lint_project_xml_test.py",
- "lint_project_xml.py",
+ "lint_strict_updatability_checks.py",
+ ],
+ libs: ["ninja_rsp"],
+}
+
+python_test_host {
+ name: "lint_strict_updatability_checks_test",
+ main: "lint_strict_updatability_checks_test.py",
+ srcs: [
+ "lint_strict_updatability_checks_test.py",
+ "lint_strict_updatability_checks.py",
],
libs: ["ninja_rsp"],
test_suites: ["general-tests"],
diff --git a/scripts/lint_project_xml.py b/scripts/lint_project_xml.py
index c40b07d..ce6aa21 100755
--- a/scripts/lint_project_xml.py
+++ b/scripts/lint_project_xml.py
@@ -75,8 +75,6 @@
help='file containing the module\'s manifest.')
parser.add_argument('--merged_manifest', dest='merged_manifest',
help='file containing merged manifest for the module and its dependencies.')
- parser.add_argument('--baseline', dest='baseline_path',
- help='file containing baseline lint issues.')
parser.add_argument('--library', dest='library', action='store_true',
help='mark the module as a library.')
parser.add_argument('--test', dest='test', action='store_true',
@@ -94,8 +92,6 @@
help='treat a lint issue as a warning.')
group.add_argument('--disable_check', dest='checks', action=check_action('ignore'), default=[],
help='disable a lint issue.')
- group.add_argument('--disallowed_issues', dest='disallowed_issues', default=[],
- help='lint issues disallowed in the baseline file')
return parser.parse_args()
@@ -140,30 +136,10 @@
f.write("</lint>\n")
-def check_baseline_for_disallowed_issues(baseline, forced_checks):
- issues_element = baseline.documentElement
- if issues_element.tagName != 'issues':
- raise RuntimeError('expected issues tag at root')
- issues = issues_element.getElementsByTagName('issue')
- disallowed = set()
- for issue in issues:
- id = issue.getAttribute('id')
- if id in forced_checks:
- disallowed.add(id)
- return disallowed
-
-
def main():
"""Program entry point."""
args = parse_args()
- if args.baseline_path:
- baseline = minidom.parse(args.baseline_path)
- disallowed_issues = check_baseline_for_disallowed_issues(baseline, args.disallowed_issues)
- if disallowed_issues:
- sys.exit('disallowed issues %s found in lint baseline file %s for module %s'
- % (disallowed_issues, args.baseline_path, args.name))
-
if args.project_out:
with open(args.project_out, 'w') as f:
write_project_xml(f, args)
diff --git a/scripts/lint_strict_updatability_checks.py b/scripts/lint_strict_updatability_checks.py
new file mode 100755
index 0000000..5b5dfd8
--- /dev/null
+++ b/scripts/lint_strict_updatability_checks.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2018 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.
+#
+
+"""This file checks baselines passed to Android Lint for checks that must not be baselined."""
+
+import argparse
+import sys
+from xml.dom import minidom
+
+from ninja_rsp import NinjaRspFileReader
+
+
+def parse_args():
+ """Parse commandline arguments."""
+
+ def convert_arg_line_to_args(arg_line):
+ for arg in arg_line.split():
+ if arg.startswith('#'):
+ return
+ if not arg.strip():
+ continue
+ yield arg
+
+ parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
+ parser.convert_arg_line_to_args = convert_arg_line_to_args
+ parser.add_argument('--name', dest='name',
+ help='name of the module.')
+ parser.add_argument('--baselines', dest='baselines', action='append', default=[],
+ help='file containing whitespace separated list of baseline files.')
+ parser.add_argument('--disallowed_issues', dest='disallowed_issues', default=[],
+ help='lint issues disallowed in the baseline file')
+ return parser.parse_args()
+
+
+def check_baseline_for_disallowed_issues(baseline, forced_checks):
+ issues_element = baseline.documentElement
+ if issues_element.tagName != 'issues':
+ raise RuntimeError('expected issues tag at root')
+ issues = issues_element.getElementsByTagName('issue')
+ disallowed = set()
+ for issue in issues:
+ id = issue.getAttribute('id')
+ if id in forced_checks:
+ disallowed.add(id)
+ return disallowed
+
+
+def main():
+ """Program entry point."""
+ args = parse_args()
+
+ error = False
+ for baseline_rsp_file in args.baselines:
+ for baseline_path in NinjaRspFileReader(baseline_rsp_file):
+ baseline = minidom.parse(baseline_path)
+ disallowed_issues = check_baseline_for_disallowed_issues(baseline, args.disallowed_issues)
+ if disallowed_issues:
+ print('disallowed issues %s found in lint baseline file %s for module %s'
+ % (disallowed_issues, baseline_path, args.name))
+ error = True
+
+ if error:
+ sys.exit(1)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/lint_project_xml_test.py b/scripts/lint_strict_updatability_checks_test.py
old mode 100644
new mode 100755
similarity index 88%
rename from scripts/lint_project_xml_test.py
rename to scripts/lint_strict_updatability_checks_test.py
index 344691d..fd8610f
--- a/scripts/lint_project_xml_test.py
+++ b/scripts/lint_strict_updatability_checks_test.py
@@ -15,12 +15,12 @@
# limitations under the License.
#
-"""Unit tests for lint_project_xml.py."""
+"""Unit tests for lint_strict_updatability_checks.py."""
import unittest
from xml.dom import minidom
-import lint_project_xml
+import lint_strict_updatability_checks
class CheckBaselineForDisallowedIssuesTest(unittest.TestCase):
@@ -44,7 +44,7 @@
'</issues>\n')
def test_check_baseline_for_disallowed_issues(self):
- disallowed_issues = lint_project_xml.check_baseline_for_disallowed_issues(self.baseline_xml, ["foo", "bar", "qux"])
+ disallowed_issues = lint_strict_updatability_checks.check_baseline_for_disallowed_issues(self.baseline_xml, ["foo", "bar", "qux"])
self.assertEqual({"foo", "bar"}, disallowed_issues)
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 09a7c9e..15e13db 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -1360,10 +1360,9 @@
}
`),
snapshotTestChecker(checkSnapshotWithSourcePreferred, func(t *testing.T, result *android.TestResult) {
- ctx := android.ModuleInstallPathContextForTesting(result.Config)
dexJarBuildPath := func(name string, kind android.SdkKind) string {
- dep := result.Module(name, "android_common").(java.SdkLibraryDependency)
- path := dep.SdkApiExportableStubDexJar(ctx, kind).Path()
+ sdkLibInfo, _ := android.OtherModuleProvider(result.TestContext.OtherModuleProviderAdaptor(), result.Module(name, "android_common"), java.SdkLibraryInfoProvider)
+ path := sdkLibInfo.ExportableStubDexJarPaths[kind].Path()
return path.RelativeToTop().String()
}
diff --git a/soong_ui.bash b/soong_ui.bash
index 7737880..2f688ef 100755
--- a/soong_ui.bash
+++ b/soong_ui.bash
@@ -26,6 +26,7 @@
source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../make/shell_utils.sh
require_top
+setup_cog_env_if_needed
# Save the current PWD for use in soong_ui
export ORIGINAL_PWD=${PWD}
diff --git a/tradefed/autogen.go b/tradefed/autogen.go
index ddd0a80..e230795 100644
--- a/tradefed/autogen.go
+++ b/tradefed/autogen.go
@@ -196,16 +196,16 @@
}
var autogenInstrumentationTest = pctx.StaticRule("autogenInstrumentationTest", blueprint.RuleParams{
- Command: "${AutoGenTestConfigScript} $out $in ${EmptyTestConfig} $template ${extraConfigs}",
+ Command: "${AutoGenTestConfigScript} $out $in ${EmptyTestConfig} $template ${extraConfigs} ${extraTestRunnerConfigs}",
CommandDeps: []string{
"${AutoGenTestConfigScript}",
"${EmptyTestConfig}",
"$template",
},
-}, "name", "template", "extraConfigs")
+}, "name", "template", "extraConfigs", "extraTestRunnerConfigs")
func AutoGenInstrumentationTestConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, manifest android.Path, testSuites []string, autoGenConfig *bool, configs []Config) android.Path {
+ testConfigTemplateProp *string, manifest android.Path, testSuites []string, autoGenConfig *bool, configs []Config, testRunnerConfigs []Option) android.Path {
path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
var configStrings []string
if autogenPath != nil {
@@ -220,15 +220,26 @@
extraConfigs := strings.Join(configStrings, fmt.Sprintf("\\n%s", test_xml_indent))
extraConfigs = fmt.Sprintf("--extra-configs '%s'", extraConfigs)
+ var testRunnerConfigStrings []string
+ for _, config := range testRunnerConfigs {
+ testRunnerConfigStrings = append(testRunnerConfigStrings, config.Config())
+ }
+ extraTestRunnerConfigs := strings.Join(testRunnerConfigStrings, fmt.Sprintf("\\n%s%s", test_xml_indent, test_xml_indent))
+ if len(extraTestRunnerConfigs) > 0 {
+ extraTestRunnerConfigs += fmt.Sprintf("\\n%s%s", test_xml_indent, test_xml_indent)
+ }
+ extraTestRunnerConfigs = fmt.Sprintf("--extra-test-runner-configs '%s'", extraTestRunnerConfigs)
+
ctx.Build(pctx, android.BuildParams{
Rule: autogenInstrumentationTest,
Description: "test config",
Input: manifest,
Output: autogenPath,
Args: map[string]string{
- "name": ctx.ModuleName(),
- "template": template,
- "extraConfigs": extraConfigs,
+ "name": ctx.ModuleName(),
+ "template": template,
+ "extraConfigs": extraConfigs,
+ "extraTestRunnerConfigs": extraTestRunnerConfigs,
},
})
return autogenPath
diff --git a/ui/build/soong.go b/ui/build/soong.go
index eb51022..41425ac 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -27,6 +27,7 @@
"strings"
"sync"
"sync/atomic"
+ "syscall"
"time"
"android/soong/ui/tracer"
@@ -780,7 +781,7 @@
hasNewDep := false
for _, dep := range cachedGlob.Deps {
info, err := os.Stat(dep)
- if errors.Is(err, fs.ErrNotExist) {
+ if errors.Is(err, fs.ErrNotExist) || errors.Is(err, syscall.ENOTDIR) {
hasNewDep = true
break
} else if err != nil {