aboutsummaryrefslogtreecommitdiff
path: root/apex
diff options
context:
space:
mode:
authorGeorge Zacharia <george.zcharia@gmail.com>2024-06-30 21:31:39 +0530
committerGeorge Zacharia <george.zcharia@gmail.com>2024-06-30 21:31:39 +0530
commit5cf52b53bd3c1ffdf1f0b505b08cd9765ad1cc0d (patch)
tree612a855b839f086862ec76805da2547c94eef94c /apex
parente867a64ffb8fc36f0e39c3a4fe5b98104bffda2f (diff)
parent8bf89894cce3b5387e548a325febf7029828875c (diff)
Merge tag 'android-14.0.0_r50' of https://android.googlesource.com/platform/build/soong into u14.0
Android 14.0.0 Release 50 (AP2A.240605.024)
Diffstat (limited to 'apex')
-rw-r--r--apex/androidmk.go9
-rw-r--r--apex/apex.go226
-rw-r--r--apex/apex_singleton.go2
-rw-r--r--apex/apex_test.go1072
-rw-r--r--apex/bootclasspath_fragment_test.go52
-rw-r--r--apex/builder.go52
-rw-r--r--apex/classpath_element_test.go16
-rw-r--r--apex/deapexer.go10
-rw-r--r--apex/dexpreopt_bootjars_test.go163
-rw-r--r--apex/platform_bootclasspath_test.go42
-rw-r--r--apex/prebuilt.go179
-rw-r--r--apex/systemserver_classpath_fragment_test.go30
-rw-r--r--apex/vndk.go44
-rw-r--r--apex/vndk_test.go60
14 files changed, 1374 insertions, 583 deletions
diff --git a/apex/androidmk.go b/apex/androidmk.go
index bc68ad36b..619be8dc4 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -124,6 +124,10 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, moduleDir st
pathForSymbol := filepath.Join("$(PRODUCT_OUT)", "apex", apexBundleName, fi.installDir)
modulePath := pathForSymbol
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", modulePath)
+ // AconfigUpdateAndroidMkData may have added elements to Extra. Process them here.
+ for _, extra := range apexAndroidMkData.Extra {
+ extra(w, fi.builtFile)
+ }
// For non-flattend APEXes, the merged notice file is attached to the APEX itself.
// We don't need to have notice file for the individual modules in it. Otherwise,
@@ -229,6 +233,7 @@ func (a *apexBundle) writeRequiredModules(w io.Writer, moduleNames []string) {
func (a *apexBundle) androidMkForType() android.AndroidMkData {
return android.AndroidMkData{
+ // While we do not provide a value for `Extra`, AconfigUpdateAndroidMkData may add some, which we must honor.
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
moduleNames := []string{}
if a.installable() {
@@ -269,6 +274,10 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData {
android.AndroidMkEmitAssignList(w, "LOCAL_OVERRIDES_MODULES", a.overridableProperties.Overrides)
a.writeRequiredModules(w, moduleNames)
+ // AconfigUpdateAndroidMkData may have added elements to Extra. Process them here.
+ for _, extra := range data.Extra {
+ extra(w, a.outputFile)
+ }
fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).BUNDLE :=", a.bundleModuleFile.String())
diff --git a/apex/apex.go b/apex/apex.go
index 1be41c0f2..993c0f319 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -18,13 +18,11 @@ package apex
import (
"fmt"
- "log"
"path/filepath"
"regexp"
"sort"
"strings"
- "android/soong/aconfig"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -236,6 +234,9 @@ type ApexNativeDependencies struct {
// List of filesystem images that are embedded inside this APEX bundle.
Filesystems []string
+ // List of prebuilt_etcs that are embedded inside this APEX bundle.
+ Prebuilts []string
+
// List of native libraries to exclude from this APEX.
Exclude_native_shared_libs []string
@@ -253,6 +254,9 @@ type ApexNativeDependencies struct {
// List of filesystem images to exclude from this APEX bundle.
Exclude_filesystems []string
+
+ // List of prebuilt_etcs to exclude from this APEX bundle.
+ Exclude_prebuilts []string
}
// Merge combines another ApexNativeDependencies into this one
@@ -263,6 +267,7 @@ func (a *ApexNativeDependencies) Merge(b ApexNativeDependencies) {
a.Binaries = append(a.Binaries, b.Binaries...)
a.Tests = append(a.Tests, b.Tests...)
a.Filesystems = append(a.Filesystems, b.Filesystems...)
+ a.Prebuilts = append(a.Prebuilts, b.Prebuilts...)
a.Exclude_native_shared_libs = append(a.Exclude_native_shared_libs, b.Exclude_native_shared_libs...)
a.Exclude_jni_libs = append(a.Exclude_jni_libs, b.Exclude_jni_libs...)
@@ -270,6 +275,7 @@ func (a *ApexNativeDependencies) Merge(b ApexNativeDependencies) {
a.Exclude_binaries = append(a.Exclude_binaries, b.Exclude_binaries...)
a.Exclude_tests = append(a.Exclude_tests, b.Exclude_tests...)
a.Exclude_filesystems = append(a.Exclude_filesystems, b.Exclude_filesystems...)
+ a.Exclude_prebuilts = append(a.Exclude_prebuilts, b.Exclude_prebuilts...)
}
type apexMultilibProperties struct {
@@ -481,6 +487,9 @@ type apexBundle struct {
javaApisUsedByModuleFile android.ModuleOutPath
aconfigFiles []android.Path
+
+ // Single aconfig "cache file" merged from this module and all dependencies.
+ mergedAconfigFiles map[string]android.Paths
}
// apexFileClass represents a type of file that can be included in APEX.
@@ -712,6 +721,8 @@ func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeM
android.RemoveListFromList(nativeModules.Rust_dyn_libs, nativeModules.Exclude_rust_dyn_libs)...)
ctx.AddFarVariationDependencies(target.Variations(), fsTag,
android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
+ ctx.AddFarVariationDependencies(target.Variations(), prebuiltTag,
+ android.RemoveListFromList(nativeModules.Prebuilts, nativeModules.Exclude_prebuilts)...)
}
func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
@@ -720,7 +731,7 @@ func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
// getImageVariationPair returns a pair for the image variation name as its
// prefix and suffix. The prefix indicates whether it's core/vendor/product and the
-// suffix indicates the vndk version when it's vendor or product.
+// suffix indicates the vndk version for vendor/product if vndk is enabled.
// getImageVariation can simply join the result of this function to get the
// image variation name.
func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (string, string) {
@@ -728,8 +739,8 @@ func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (s
return cc.VendorVariationPrefix, a.vndkVersion(deviceConfig)
}
- var prefix string
- var vndkVersion string
+ prefix := android.CoreVariation
+ vndkVersion := ""
if deviceConfig.VndkVersion() != "" {
if a.SocSpecific() || a.DeviceSpecific() {
prefix = cc.VendorVariationPrefix
@@ -738,15 +749,18 @@ func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (s
prefix = cc.ProductVariationPrefix
vndkVersion = deviceConfig.PlatformVndkVersion()
}
+ } else {
+ if a.SocSpecific() || a.DeviceSpecific() {
+ prefix = cc.VendorVariation
+ } else if a.ProductSpecific() {
+ prefix = cc.ProductVariation
+ }
}
if vndkVersion == "current" {
vndkVersion = deviceConfig.PlatformVndkVersion()
}
- if vndkVersion != "" {
- return prefix, vndkVersion
- }
- return android.CoreVariation, "" // The usual case
+ return prefix, vndkVersion
}
// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
@@ -827,10 +841,12 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
}
addDependenciesForNativeModules(ctx, deps, target, imageVariation)
- ctx.AddFarVariationDependencies([]blueprint.Variation{
- {Mutator: "os", Variation: target.OsVariation()},
- {Mutator: "arch", Variation: target.ArchVariation()},
- }, shBinaryTag, a.properties.Sh_binaries...)
+ if isPrimaryAbi {
+ ctx.AddFarVariationDependencies([]blueprint.Variation{
+ {Mutator: "os", Variation: target.OsVariation()},
+ {Mutator: "arch", Variation: target.ArchVariation()},
+ }, shBinaryTag, a.properties.Sh_binaries...)
+ }
}
// Common-arch dependencies come next
@@ -912,13 +928,7 @@ type DCLAInfo struct {
ProvidedLibs []string
}
-var DCLAInfoProvider = blueprint.NewMutatorProvider(DCLAInfo{}, "apex_info")
-
-type ApexBundleInfo struct {
- Contents *android.ApexContents
-}
-
-var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_info")
+var DCLAInfoProvider = blueprint.NewMutatorProvider[DCLAInfo]("apex_info")
var _ ApexInfoMutator = (*apexBundle)(nil)
@@ -993,10 +1003,8 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
}
}
- //TODO: b/296491928 Vendor APEX should use libbinder.ndk instead of libbinder once VNDK is fully deprecated.
if useVndk && mctx.Config().IsVndkDeprecated() && child.Name() == "libbinder" {
- log.Print("Libbinder is linked from Vendor APEX ", a.Name(), " with module ", parent.Name())
- return false
+ mctx.ModuleErrorf("Module %s in the vendor APEX %s should not use libbinder. Use libbinder_ndk instead.", parent.Name(), a.Name())
}
// By default, all the transitive dependencies are collected, unless filtered out
@@ -1020,7 +1028,7 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
// The membership information is saved for later access
apexContents := android.NewApexContents(contents)
- mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
+ android.SetProvider(mctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{
Contents: apexContents,
})
@@ -1058,7 +1066,7 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
})
if a.dynamic_common_lib_apex() {
- mctx.SetProvider(DCLAInfoProvider, DCLAInfo{
+ android.SetProvider(mctx, DCLAInfoProvider, DCLAInfo{
ProvidedLibs: a.properties.Native_shared_libs,
})
}
@@ -1137,15 +1145,43 @@ func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
// Skip these mainline modules for now
var (
skipStrictUpdatabilityLintAllowlist = []string{
+ // go/keep-sorted start
+ "PackageManagerTestApex",
+ "com.android.adservices",
+ "com.android.appsearch",
"com.android.art",
"com.android.art.debug",
+ "com.android.btservices",
+ "com.android.cellbroadcast",
+ "com.android.configinfrastructure",
"com.android.conscrypt",
+ "com.android.extservices",
+ "com.android.extservices_tplus",
+ "com.android.healthfitness",
+ "com.android.ipsec",
"com.android.media",
- // test apexes
+ "com.android.mediaprovider",
+ "com.android.ondevicepersonalization",
+ "com.android.os.statsd",
+ "com.android.permission",
+ "com.android.profiling",
+ "com.android.rkpd",
+ "com.android.scheduling",
+ "com.android.tethering",
+ "com.android.uwb",
+ "com.android.wifi",
"test_com.android.art",
+ "test_com.android.cellbroadcast",
"test_com.android.conscrypt",
+ "test_com.android.extservices",
+ "test_com.android.ipsec",
"test_com.android.media",
+ "test_com.android.mediaprovider",
+ "test_com.android.os.statsd",
+ "test_com.android.permission",
+ "test_com.android.wifi",
"test_jitzygote_com.android.art",
+ // go/keep-sorted end
}
// TODO: b/215736885 Remove this list
@@ -1201,10 +1237,10 @@ func apexTestForMutator(mctx android.BottomUpMutatorContext) {
if _, ok := mctx.Module().(android.ApexModule); ok {
var contents []*android.ApexContents
for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
- abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
+ abInfo, _ := android.OtherModuleProvider(mctx, testFor, android.ApexBundleInfoProvider)
contents = append(contents, abInfo.Contents)
}
- mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
+ android.SetProvider(mctx, android.ApexTestForInfoProvider, android.ApexTestForInfo{
ApexContents: contents,
})
}
@@ -1376,7 +1412,7 @@ func (a *apexBundle) TaggedOutputs() map[string]android.Paths {
var _ cc.Coverage = (*apexBundle)(nil)
// Implements cc.Coverage
-func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
+func (a *apexBundle) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool {
return ctx.DeviceConfig().NativeCoverageEnabled()
}
@@ -1465,7 +1501,7 @@ func (a *apexBundle) libs_to_trim(ctx android.ModuleContext) []string {
panic(fmt.Errorf("expected exactly at most one dcla dependency, got %d", len(dclaModules)))
}
if len(dclaModules) > 0 {
- DCLAInfo := ctx.OtherModuleProvider(dclaModules[0], DCLAInfoProvider).(DCLAInfo)
+ DCLAInfo, _ := android.OtherModuleProvider(ctx, dclaModules[0], DCLAInfoProvider)
return DCLAInfo.ProvidedLibs
}
return []string{}
@@ -1625,7 +1661,7 @@ func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.Platform
type javaModule interface {
android.Module
BaseModuleName() string
- DexJarBuildPath() java.OptionalDexJarPath
+ DexJarBuildPath(ctx android.ModuleErrorfContext) java.OptionalDexJarPath
JacocoReportClassesFile() android.Path
LintDepSets() java.LintDepSets
Stem() string
@@ -1639,7 +1675,7 @@ var _ javaModule = (*java.SdkLibraryImport)(nil)
// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
- return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath().PathOrNil())
+ return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath(ctx).PathOrNil())
}
// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
@@ -1782,7 +1818,7 @@ func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.Paylo
return false
}
- ai := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
+ ai, _ := android.OtherModuleProvider(ctx, child, android.ApexInfoProvider)
externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
// Visit actually
@@ -2035,8 +2071,10 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
return true // track transitive dependencies
case *java.AndroidAppImport:
vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
+ addAconfigFiles(vctx, ctx, child)
case *java.AndroidTestHelperApp:
vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
+ addAconfigFiles(vctx, ctx, child)
case *java.AndroidAppSet:
appDir := "app"
if ap.Privileged() {
@@ -2050,6 +2088,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
af.certificate = java.PresignedCertificate
vctx.filesInfo = append(vctx.filesInfo, af)
+ addAconfigFiles(vctx, ctx, child)
default:
ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
}
@@ -2081,6 +2120,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
for _, etcFile := range filesToCopy {
vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, etcFile))
}
+ addAconfigFiles(vctx, ctx, child)
} else {
ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
}
@@ -2104,6 +2144,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
af := apexFileForExecutable(ctx, ccTest)
af.class = nativeTest
vctx.filesInfo = append(vctx.filesInfo, af)
+ addAconfigFiles(vctx, ctx, child)
}
return true // track transitive dependencies
} else {
@@ -2145,14 +2186,10 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
return false
}
- //TODO: b/296491928 Vendor APEX should use libbinder.ndk instead of libbinder once VNDK is fully deprecated.
- if ch.UseVndk() && ctx.Config().IsVndkDeprecated() && child.Name() == "libbinder" {
- return false
- }
af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
af.transitiveDep = true
- abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
+ abInfo, _ := android.ModuleProvider(ctx, android.ApexBundleInfoProvider)
if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
// If the dependency is a stubs lib, don't include it in this APEX,
// but make sure that the lib is installed on the device.
@@ -2193,11 +2230,13 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
}
vctx.filesInfo = append(vctx.filesInfo, af)
+ addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
} else if rm, ok := child.(*rust.Module); ok {
af := apexFileForRustLibrary(ctx, rm)
af.transitiveDep = true
vctx.filesInfo = append(vctx.filesInfo, af)
+ addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
}
} else if cc.IsTestPerSrcDepTag(depTag) {
@@ -2229,6 +2268,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
af := apexFileForRustLibrary(ctx, rustm)
af.transitiveDep = true
vctx.filesInfo = append(vctx.filesInfo, af)
+ addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
}
} else if rust.IsRlibDepTag(depTag) {
@@ -2247,6 +2287,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
return false
}
vctx.filesInfo = append(vctx.filesInfo, af)
+ addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
default:
ctx.PropertyErrorf("bootclasspath_fragments",
@@ -2261,6 +2302,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
if profileAf := apexFileForJavaModuleProfile(ctx, child.(javaModule)); profileAf != nil {
vctx.filesInfo = append(vctx.filesInfo, *profileAf)
}
+ addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
default:
ctx.PropertyErrorf("systemserverclasspath_fragments",
@@ -2277,7 +2319,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
}
func addAconfigFiles(vctx *visitorContext, ctx android.ModuleContext, module blueprint.Module) {
- dep := ctx.OtherModuleProvider(module, aconfig.TransitiveDeclarationsInfoProvider).(aconfig.TransitiveDeclarationsInfo)
+ dep, _ := android.OtherModuleProvider(ctx, module, android.AconfigTransitiveDeclarationsInfoProvider)
if len(dep.AconfigFiles) > 0 && dep.AconfigFiles[ctx.ModuleName()] != nil {
vctx.aconfigFiles = append(vctx.aconfigFiles, dep.AconfigFiles[ctx.ModuleName()]...)
}
@@ -2359,6 +2401,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
return
}
}
+ android.CollectDependencyAconfigFiles(ctx, &a.mergedAconfigFiles)
////////////////////////////////////////////////////////////////////////////////////////////
// 3) some fields in apexBundle struct are configured
@@ -2376,12 +2419,31 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.buildApex(ctx)
a.buildApexDependencyInfo(ctx)
a.buildLintReports(ctx)
+
+ // Set a provider for dexpreopt of bootjars
+ a.provideApexExportsInfo(ctx)
+}
+
+// Set a provider containing information about the jars and .prof provided by the apex
+// Apexes built from source retrieve this information by visiting `bootclasspath_fragments`
+// Used by dex_bootjars to generate the boot image
+func (a *apexBundle) provideApexExportsInfo(ctx android.ModuleContext) {
+ ctx.VisitDirectDepsWithTag(bcpfTag, func(child android.Module) {
+ if info, ok := android.OtherModuleProvider(ctx, child, java.BootclasspathFragmentApexContentInfoProvider); ok {
+ exports := android.ApexExportsInfo{
+ ApexName: a.ApexVariationName(),
+ ProfilePathOnHost: info.ProfilePathOnHost(),
+ LibraryNameToDexJarPathOnHost: info.DexBootJarPathMap(),
+ }
+ android.SetProvider(ctx, android.ApexExportsInfoProvider, exports)
+ }
+ })
}
// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
// the bootclasspath_fragment contributes to the apex.
func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
- bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
+ bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, module, java.BootclasspathFragmentApexContentInfoProvider)
var filesToAdd []apexFile
// Add classpaths.proto config.
@@ -2430,7 +2492,7 @@ func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.
// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
// the module contributes to the apex; or nil if the proto config was not generated.
func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
- info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
+ info, _ := android.OtherModuleProvider(ctx, module, java.ClasspathFragmentProtoContentInfoProvider)
if !info.ClasspathFragmentProtoGenerated {
return nil
}
@@ -2442,7 +2504,7 @@ func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.
// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
// content module, i.e. a library that is part of the bootclasspath.
func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
- bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
+ bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, fragmentModule, java.BootclasspathFragmentApexContentInfoProvider)
// Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
// hidden API encpding.
@@ -2499,6 +2561,9 @@ func BundleFactory() android.Module {
type Defaults struct {
android.ModuleBase
android.DefaultsModuleBase
+
+ // Single aconfig "cache file" merged from this module and all dependencies.
+ mergedAconfigFiles map[string]android.Paths
}
// apex_defaults provides defaultable properties to other apex modules.
@@ -2521,6 +2586,10 @@ type OverrideApex struct {
android.OverrideModuleBase
}
+func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ android.CollectDependencyAconfigFiles(ctx, &d.mergedAconfigFiles)
+}
+
func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
// All the overrides happen in the base module.
}
@@ -2594,7 +2663,7 @@ func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext
return
}
- abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
+ abInfo, _ := android.ModuleProvider(ctx, android.ApexBundleInfoProvider)
a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
if ccm, ok := to.(*cc.Module); ok {
@@ -2655,7 +2724,7 @@ func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
ctx.VisitDirectDeps(func(module android.Module) {
if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
- info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
+ info, _ := android.OtherModuleProvider(ctx, module, java.ClasspathFragmentProtoContentInfoProvider)
if !info.ClasspathFragmentProtoGenerated {
ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
}
@@ -2840,77 +2909,8 @@ func makeApexAvailableBaseline() map[string][]string {
//
// Module separator
//
- m["com.android.mediaprovider"] = []string{
- "MediaProvider",
- "MediaProviderGoogle",
- "fmtlib_ndk",
- "libbase_ndk",
- "libfuse",
- "libfuse_jni",
- }
- //
- // Module separator
- //
m["com.android.runtime"] = []string{
- "libdebuggerd",
- "libdebuggerd_common_headers",
- "libdebuggerd_handler_core",
- "libdl_static",
- "libjemalloc5",
- "liblinker_main",
- "liblinker_malloc",
- "liblzma",
- "libprocinfo",
- "libpropertyinfoparser",
- "libscudo",
- "libsystemproperties",
- "libtombstoned_client_static",
- "libunwindstack",
"libz",
- "libziparchive",
- }
- //
- // Module separator
- //
- m["com.android.tethering"] = []string{
- "android.hardware.tetheroffload.config-V1.0-java",
- "android.hardware.tetheroffload.control-V1.0-java",
- "net-utils-framework-common",
- }
- //
- // Module separator
- //
- m["com.android.wifi"] = []string{
- "PlatformProperties",
- "android.hardware.wifi-V1.0-java",
- "android.hardware.wifi-V1.0-java-constants",
- "android.hardware.wifi-V1.1-java",
- "android.hardware.wifi-V1.2-java",
- "android.hardware.wifi-V1.3-java",
- "android.hardware.wifi-V1.4-java",
- "android.hardware.wifi.hostapd-V1.0-java",
- "android.hardware.wifi.hostapd-V1.1-java",
- "android.hardware.wifi.hostapd-V1.2-java",
- "android.hardware.wifi.supplicant-V1.0-java",
- "android.hardware.wifi.supplicant-V1.1-java",
- "android.hardware.wifi.supplicant-V1.2-java",
- "android.hardware.wifi.supplicant-V1.3-java",
- "bouncycastle-unbundled",
- "framework-wifi-util-lib",
- "ksoap2",
- "libnanohttpd",
- "wifi-lite-protos",
- "wifi-nano-protos",
- "wifi-service-pre-jarjar",
- }
- //
- // Module separator
- //
- m[android.AvailableToAnyApex] = []string{
- "libprofile-clang-extras",
- "libprofile-clang-extras_ndk",
- "libprofile-extras",
- "libprofile-extras_ndk",
}
return m
}
diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go
index a63344fc1..25c0cc444 100644
--- a/apex/apex_singleton.go
+++ b/apex/apex_singleton.go
@@ -83,7 +83,7 @@ func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContex
updatableFlatLists := android.Paths{}
ctx.VisitAllModules(func(module android.Module) {
if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok {
- apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
+ apexInfo, _ := android.SingletonModuleProvider(ctx, module, android.ApexInfoProvider)
if path := binaryInfo.FlatListPath(); path != nil {
if binaryInfo.Updatable() || apexInfo.Updatable {
updatableFlatLists = append(updatableFlatLists, path)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index abf6b1534..9dc77c28d 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -790,6 +790,79 @@ func TestApexManifestMinSdkVersion(t *testing.T) {
}
}
+func TestApexWithDessertSha(t *testing.T) {
+ ctx := testApex(t, `
+ apex_defaults {
+ name: "my_defaults",
+ key: "myapex.key",
+ product_specific: true,
+ file_contexts: ":my-file-contexts",
+ updatable: false,
+ }
+ apex {
+ name: "myapex_30",
+ min_sdk_version: "30",
+ defaults: ["my_defaults"],
+ }
+
+ apex {
+ name: "myapex_current",
+ min_sdk_version: "current",
+ defaults: ["my_defaults"],
+ }
+
+ apex {
+ name: "myapex_none",
+ defaults: ["my_defaults"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ filegroup {
+ name: "my-file-contexts",
+ srcs: ["product_specific_file_contexts"],
+ }
+ `, withFiles(map[string][]byte{
+ "product_specific_file_contexts": nil,
+ }), android.FixtureModifyProductVariables(
+ func(variables android.FixtureProductVariables) {
+ variables.Unbundled_build = proptools.BoolPtr(true)
+ variables.Always_use_prebuilt_sdks = proptools.BoolPtr(false)
+ }), android.FixtureMergeEnv(map[string]string{
+ "UNBUNDLED_BUILD_TARGET_SDK_WITH_DESSERT_SHA": "UpsideDownCake.abcdefghijklmnopqrstuvwxyz123456",
+ }))
+
+ testCases := []struct {
+ module string
+ minSdkVersion string
+ }{
+ {
+ module: "myapex_30",
+ minSdkVersion: "30",
+ },
+ {
+ module: "myapex_current",
+ minSdkVersion: "UpsideDownCake.abcdefghijklmnopqrstuvwxyz123456",
+ },
+ {
+ module: "myapex_none",
+ minSdkVersion: "UpsideDownCake.abcdefghijklmnopqrstuvwxyz123456",
+ },
+ }
+ for _, tc := range testCases {
+ module := ctx.ModuleForTests(tc.module, "android_common_"+tc.module)
+ args := module.Rule("apexRule").Args
+ optFlags := args["opt_flags"]
+ if !strings.Contains(optFlags, "--min_sdk_version "+tc.minSdkVersion) {
+ t.Errorf("%s: Expected min_sdk_version=%s, got: %s", tc.module, tc.minSdkVersion, optFlags)
+ }
+ }
+}
+
func TestFileContexts(t *testing.T) {
for _, vendor := range []bool{true, false} {
prop := ""
@@ -1455,6 +1528,7 @@ func TestRuntimeApexShouldInstallHwasanIfLibcDependsOnIt(t *testing.T) {
name: "libc",
no_libcrt: true,
nocrt: true,
+ no_crt_pad_segment: true,
stl: "none",
system_shared_libs: [],
stubs: { versions: ["1"] },
@@ -1469,6 +1543,7 @@ func TestRuntimeApexShouldInstallHwasanIfLibcDependsOnIt(t *testing.T) {
name: "libclang_rt.hwasan",
no_libcrt: true,
nocrt: true,
+ no_crt_pad_segment: true,
stl: "none",
system_shared_libs: [],
srcs: [""],
@@ -1511,6 +1586,7 @@ func TestRuntimeApexShouldInstallHwasanIfHwaddressSanitized(t *testing.T) {
name: "libc",
no_libcrt: true,
nocrt: true,
+ no_crt_pad_segment: true,
stl: "none",
system_shared_libs: [],
stubs: { versions: ["1"] },
@@ -1521,6 +1597,7 @@ func TestRuntimeApexShouldInstallHwasanIfHwaddressSanitized(t *testing.T) {
name: "libclang_rt.hwasan",
no_libcrt: true,
nocrt: true,
+ no_crt_pad_segment: true,
stl: "none",
system_shared_libs: [],
srcs: [""],
@@ -3725,7 +3802,7 @@ func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName, var
}
func ensureExactDeapexedContents(t *testing.T, ctx *android.TestContext, moduleName string, variant string, files []string) {
- deapexer := ctx.ModuleForTests(moduleName+".deapexer", variant).Rule("deapexer")
+ deapexer := ctx.ModuleForTests(moduleName+".deapexer", variant).Description("deapex")
outputs := make([]string, 0, len(deapexer.ImplicitOutputs)+1)
if deapexer.Output != nil {
outputs = append(outputs, deapexer.Output.String())
@@ -3768,13 +3845,6 @@ func TestVndkApexCurrent(t *testing.T) {
"lib64/libvndk.so",
"lib64/libvndksp.so"),
},
- {
- vndkVersion: "",
- expectedFiles: append(commonFiles,
- // Legacy VNDK APEX contains only VNDK-SP files (of core variant)
- "lib/libvndksp.so",
- "lib64/libvndksp.so"),
- },
}
for _, tc := range testCases {
t.Run("VNDK.current with DeviceVndkVersion="+tc.vndkVersion, func(t *testing.T) {
@@ -4976,6 +5046,7 @@ func TestApexWithShBinary(t *testing.T) {
key: "myapex.key",
sh_binaries: ["myscript"],
updatable: false,
+ compile_multilib: "both",
}
apex_key {
@@ -5355,6 +5426,13 @@ func TestPrebuiltApexNameWithPlatformBootclasspath(t *testing.T) {
).RunTest(t)
}
+// A minimal context object for use with DexJarBuildPath
+type moduleErrorfTestCtx struct {
+}
+
+func (ctx moduleErrorfTestCtx) ModuleErrorf(format string, args ...interface{}) {
+}
+
// These tests verify that the prebuilt_apex/deapexer to java_import wiring allows for the
// propagation of paths to dex implementation jars from the former to the latter.
func TestPrebuiltExportDexImplementationJars(t *testing.T) {
@@ -5364,10 +5442,10 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) {
t.Helper()
// Make sure the import has been given the correct path to the dex jar.
p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
- dexJarBuildPath := p.DexJarBuildPath().PathOrNil()
+ dexJarBuildPath := p.DexJarBuildPath(moduleErrorfTestCtx{}).PathOrNil()
stem := android.RemoveOptionalPrebuiltPrefix(name)
android.AssertStringEquals(t, "DexJarBuildPath should be apex-related path.",
- ".intermediates/myapex.deapexer/android_common/deapexer/javalib/"+stem+".jar",
+ ".intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/"+stem+".jar",
android.NormalizePathForTesting(dexJarBuildPath))
}
@@ -5421,8 +5499,8 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) {
// Make sure that dexpreopt can access dex implementation files from the prebuilt.
ctx := testDexpreoptWithApexes(t, bp, "", transform)
- deapexerName := deapexerModuleName("myapex")
- android.AssertStringEquals(t, "APEX module name from deapexer name", "myapex", apexModuleName(deapexerName))
+ deapexerName := deapexerModuleName("prebuilt_myapex")
+ android.AssertStringEquals(t, "APEX module name from deapexer name", "prebuilt_myapex", apexModuleName(deapexerName))
// Make sure that the deapexer has the correct input APEX.
deapexer := ctx.ModuleForTests(deapexerName, "android_common")
@@ -5645,8 +5723,8 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
`
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
- checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
+ checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
+ checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Verify the correct module jars contribute to the hiddenapi index file.
checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
@@ -5723,8 +5801,8 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
`
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
- checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
+ checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
+ checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Verify the correct module jars contribute to the hiddenapi index file.
checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
@@ -5737,7 +5815,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
myApex := ctx.ModuleForTests("myapex", "android_common_myapex").Module()
overrideNames := []string{
- "",
+ "myapex",
"myjavalib.myapex",
"libfoo.myapex",
"libbar.myapex",
@@ -5912,8 +5990,8 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
`
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
- checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
+ checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
+ checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Verify the correct module jars contribute to the hiddenapi index file.
checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
@@ -6109,8 +6187,8 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
`
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
- checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
+ checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
+ checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Verify the correct module jars contribute to the hiddenapi index file.
checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
@@ -6120,6 +6198,84 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_apex10000/modular-hiddenapi/index.csv
`)
})
+
+ t.Run("Co-existing unflagged apexes should create a duplicate module error", func(t *testing.T) {
+ bp := `
+ // Source
+ apex {
+ name: "myapex",
+ enabled: false,
+ key: "myapex.key",
+ bootclasspath_fragments: ["my-bootclasspath-fragment"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ // Prebuilt
+ prebuilt_apex {
+ name: "myapex.v1",
+ source_apex_name: "myapex",
+ arch: {
+ arm64: {
+ src: "myapex-arm64.apex",
+ },
+ arm: {
+ src: "myapex-arm.apex",
+ },
+ },
+ exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
+ prefer: true,
+ }
+ prebuilt_apex {
+ name: "myapex.v2",
+ source_apex_name: "myapex",
+ arch: {
+ arm64: {
+ src: "myapex-arm64.apex",
+ },
+ arm: {
+ src: "myapex-arm.apex",
+ },
+ },
+ exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
+ prefer: true,
+ }
+
+ prebuilt_bootclasspath_fragment {
+ name: "my-bootclasspath-fragment",
+ contents: ["libfoo", "libbar"],
+ apex_available: ["myapex"],
+ hidden_api: {
+ annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
+ metadata: "my-bootclasspath-fragment/metadata.csv",
+ index: "my-bootclasspath-fragment/index.csv",
+ stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
+ all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ },
+ prefer: true,
+ }
+
+ java_import {
+ name: "libfoo",
+ jars: ["libfoo.jar"],
+ apex_available: ["myapex"],
+ prefer: true,
+ }
+ java_import {
+ name: "libbar",
+ jars: ["libbar.jar"],
+ apex_available: ["myapex"],
+ prefer: true,
+ }
+ `
+
+ testDexpreoptWithApexes(t, bp, "Multiple prebuilt modules prebuilt_myapex.v1 and prebuilt_myapex.v2 have been marked as preferred for this source module", preparer, fragment)
+ })
+
}
func TestApexWithTests(t *testing.T) {
@@ -8313,9 +8469,9 @@ func TestAppSetBundlePrebuilt(t *testing.T) {
ctx := testApex(t, bp, prepareForTestWithSantitizeHwaddress)
// Check that the extractor produces the correct output file from the correct input file.
- extractorOutput := "out/soong/.intermediates/myapex.apex.extractor/android_common/extracted/myapex.hwasan.apks"
+ extractorOutput := "out/soong/.intermediates/prebuilt_myapex.apex.extractor/android_common/extracted/myapex.hwasan.apks"
- m := ctx.ModuleForTests("myapex.apex.extractor", "android_common")
+ m := ctx.ModuleForTests("prebuilt_myapex.apex.extractor", "android_common")
extractedApex := m.Output(extractorOutput)
android.AssertArrayString(t, "extractor input", []string{"myapex.hwasan.apks"}, extractedApex.Inputs.Strings())
@@ -8340,10 +8496,10 @@ func TestApexSetApksModuleAssignment(t *testing.T) {
}
`)
- m := ctx.ModuleForTests("myapex.apex.extractor", "android_common")
+ m := ctx.ModuleForTests("prebuilt_myapex.apex.extractor", "android_common")
// Check that the extractor produces the correct apks file from the input module
- extractorOutput := "out/soong/.intermediates/myapex.apex.extractor/android_common/extracted/myapex.apks"
+ extractorOutput := "out/soong/.intermediates/prebuilt_myapex.apex.extractor/android_common/extracted/myapex.apks"
extractedApex := m.Output(extractorOutput)
android.AssertArrayString(t, "extractor input", []string{"myapex.apks"}, extractedApex.Inputs.Strings())
@@ -8408,30 +8564,39 @@ func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, preparer android.F
func TestDuplicateDeapexersFromPrebuiltApexes(t *testing.T) {
preparers := android.GroupFixturePreparers(
java.PrepareForTestWithJavaDefaultModules,
+ prepareForTestWithBootclasspathFragment,
+ dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:libfoo"),
PrepareForTestWithApexBuildComponents,
).
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
- "Multiple installable prebuilt APEXes provide ambiguous deapexers: com.android.myapex and com.mycompany.android.myapex"))
+ "Multiple installable prebuilt APEXes provide ambiguous deapexers: prebuilt_com.android.art and prebuilt_com.mycompany.android.art"))
bpBase := `
apex_set {
- name: "com.android.myapex",
+ name: "com.android.art",
installable: true,
- exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
+ exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
set: "myapex.apks",
}
apex_set {
- name: "com.mycompany.android.myapex",
- apex_name: "com.android.myapex",
+ name: "com.mycompany.android.art",
+ apex_name: "com.android.art",
installable: true,
- exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
+ exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
set: "company-myapex.apks",
}
prebuilt_bootclasspath_fragment {
- name: "my-bootclasspath-fragment",
- apex_available: ["com.android.myapex"],
+ name: "art-bootclasspath-fragment",
+ apex_available: ["com.android.art"],
+ hidden_api: {
+ annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
+ metadata: "my-bootclasspath-fragment/metadata.csv",
+ index: "my-bootclasspath-fragment/index.csv",
+ stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
+ all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ },
%s
}
`
@@ -8441,7 +8606,7 @@ func TestDuplicateDeapexersFromPrebuiltApexes(t *testing.T) {
java_import {
name: "libfoo",
jars: ["libfoo.jar"],
- apex_available: ["com.android.myapex"],
+ apex_available: ["com.android.art"],
}
`)
})
@@ -8453,7 +8618,8 @@ func TestDuplicateDeapexersFromPrebuiltApexes(t *testing.T) {
public: {
jars: ["libbar.jar"],
},
- apex_available: ["com.android.myapex"],
+ shared_library: false,
+ apex_available: ["com.android.art"],
}
`)
})
@@ -8468,7 +8634,8 @@ func TestDuplicateDeapexersFromPrebuiltApexes(t *testing.T) {
public: {
jars: ["libbar.jar"],
},
- apex_available: ["com.android.myapex"],
+ shared_library: false,
+ apex_available: ["com.android.art"],
}
`)
})
@@ -8480,6 +8647,8 @@ func TestDuplicateButEquivalentDeapexersFromPrebuiltApexes(t *testing.T) {
PrepareForTestWithApexBuildComponents,
)
+ errCtx := moduleErrorfTestCtx{}
+
bpBase := `
apex_set {
name: "com.android.myapex",
@@ -8528,8 +8697,8 @@ func TestDuplicateButEquivalentDeapexersFromPrebuiltApexes(t *testing.T) {
module := result.Module("libfoo", "android_common_com.android.myapex")
usesLibraryDep := module.(java.UsesLibraryDependency)
android.AssertPathRelativeToTopEquals(t, "dex jar path",
- "out/soong/.intermediates/com.android.myapex.deapexer/android_common/deapexer/javalib/libfoo.jar",
- usesLibraryDep.DexJarBuildPath().Path())
+ "out/soong/.intermediates/prebuilt_com.android.myapex.deapexer/android_common/deapexer/javalib/libfoo.jar",
+ usesLibraryDep.DexJarBuildPath(errCtx).Path())
})
t.Run("java_sdk_library_import", func(t *testing.T) {
@@ -8551,8 +8720,8 @@ func TestDuplicateButEquivalentDeapexersFromPrebuiltApexes(t *testing.T) {
module := result.Module("libfoo", "android_common_com.android.myapex")
usesLibraryDep := module.(java.UsesLibraryDependency)
android.AssertPathRelativeToTopEquals(t, "dex jar path",
- "out/soong/.intermediates/com.android.myapex.deapexer/android_common/deapexer/javalib/libfoo.jar",
- usesLibraryDep.DexJarBuildPath().Path())
+ "out/soong/.intermediates/prebuilt_com.android.myapex.deapexer/android_common/deapexer/javalib/libfoo.jar",
+ usesLibraryDep.DexJarBuildPath(errCtx).Path())
})
t.Run("prebuilt_bootclasspath_fragment", func(t *testing.T) {
@@ -9124,7 +9293,7 @@ func TestApexSet(t *testing.T) {
}),
)
- m := ctx.ModuleForTests("myapex.apex.extractor", "android_common")
+ m := ctx.ModuleForTests("prebuilt_myapex.apex.extractor", "android_common")
// Check extract_apks tool parameters.
extractedApex := m.Output("extracted/myapex.apks")
@@ -9165,7 +9334,7 @@ func TestApexSet_NativeBridge(t *testing.T) {
}),
)
- m := ctx.ModuleForTests("myapex.apex.extractor", "android_common")
+ m := ctx.ModuleForTests("prebuilt_myapex.apex.extractor", "android_common")
// Check extract_apks tool parameters. No native bridge arch expected
extractedApex := m.Output("extracted/myapex.apks")
@@ -10175,188 +10344,196 @@ func ensureDoesNotContainRequiredDeps(t *testing.T, ctx *android.TestContext, mo
}
}
-// TODO(b/193460475): Re-enable this test
-//func TestApexStrictUpdtabilityLint(t *testing.T) {
-// bpTemplate := `
-// apex {
-// name: "myapex",
-// key: "myapex.key",
-// java_libs: ["myjavalib"],
-// updatable: %v,
-// min_sdk_version: "29",
-// }
-// apex_key {
-// name: "myapex.key",
-// }
-// java_library {
-// name: "myjavalib",
-// srcs: ["MyClass.java"],
-// apex_available: [ "myapex" ],
-// lint: {
-// strict_updatability_linting: %v,
-// },
-// sdk_version: "current",
-// min_sdk_version: "29",
-// }
-// `
-// fs := android.MockFS{
-// "lint-baseline.xml": nil,
-// }
-//
-// testCases := []struct {
-// testCaseName string
-// apexUpdatable bool
-// javaStrictUpdtabilityLint bool
-// lintFileExists bool
-// disallowedFlagExpected bool
-// }{
-// {
-// testCaseName: "lint-baseline.xml does not exist, no disallowed flag necessary in lint cmd",
-// apexUpdatable: true,
-// javaStrictUpdtabilityLint: true,
-// lintFileExists: false,
-// disallowedFlagExpected: 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: true,
-// lintFileExists: true,
-// disallowedFlagExpected: 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,
-// },
-// }
-//
-// for _, testCase := range testCases {
-// bp := fmt.Sprintf(bpTemplate, testCase.apexUpdatable, testCase.javaStrictUpdtabilityLint)
-// fixtures := []android.FixturePreparer{}
-// if testCase.lintFileExists {
-// fixtures = append(fixtures, fs.AddToFixture())
-// }
-//
-// result := testApex(t, bp, fixtures...)
-// myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29")
-// sboxProto := android.RuleBuilderSboxProtoForTests(t, 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",
-// }
-// `
-//
-// 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,
-// },
-// }
-//
-// 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, 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)
-//
-// if disallowedFlagActual != testCase.disallowedFlagExpected {
-// t.Errorf("Failed testcase: %v \nActual lint cmd: %v", testCase.testCaseName, *sboxProto.Commands[0].Command)
-// }
-// }
-//}
-//
-//// checks transtive deps of an apex coming from bootclasspath_fragment
-//func TestApexStrictUpdtabilityLintBcpFragmentDeps(t *testing.T) {
-// bp := `
-// apex {
-// name: "myapex",
-// key: "myapex.key",
-// bootclasspath_fragments: ["mybootclasspathfragment"],
-// updatable: true,
-// min_sdk_version: "29",
-// }
-// apex_key {
-// name: "myapex.key",
-// }
-// bootclasspath_fragment {
-// name: "mybootclasspathfragment",
-// contents: ["myjavalib"],
-// apex_available: ["myapex"],
-// hidden_api: {
-// split_packages: ["*"],
-// },
-// }
-// java_library {
-// name: "myjavalib",
-// srcs: ["MyClass.java"],
-// apex_available: [ "myapex" ],
-// sdk_version: "current",
-// min_sdk_version: "29",
-// compile_dex: true,
-// }
-// `
-// fs := android.MockFS{
-// "lint-baseline.xml": nil,
-// }
-//
-// result := testApex(t, bp, dexpreopt.FixtureSetApexBootJars("myapex:myjavalib"), fs.AddToFixture())
-// myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29")
-// sboxProto := android.RuleBuilderSboxProtoForTests(t, 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)
-// }
-//}
+func TestApexStrictUpdtabilityLint(t *testing.T) {
+ bpTemplate := `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ java_libs: ["myjavalib"],
+ updatable: %v,
+ min_sdk_version: "29",
+ }
+ apex_key {
+ name: "myapex.key",
+ }
+ java_library {
+ name: "myjavalib",
+ srcs: ["MyClass.java"],
+ apex_available: [ "myapex" ],
+ lint: {
+ strict_updatability_linting: %v,
+ %s
+ },
+ sdk_version: "current",
+ min_sdk_version: "29",
+ }
+ `
+ fs := android.MockFS{
+ "lint-baseline.xml": nil,
+ }
+
+ testCases := []struct {
+ testCaseName string
+ apexUpdatable bool
+ javaStrictUpdtabilityLint bool
+ lintFileExists bool
+ disallowedFlagExpected bool
+ }{
+ {
+ testCaseName: "lint-baseline.xml does not exist, no disallowed flag necessary in lint cmd",
+ apexUpdatable: true,
+ javaStrictUpdtabilityLint: true,
+ lintFileExists: false,
+ disallowedFlagExpected: 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: true,
+ lintFileExists: true,
+ disallowedFlagExpected: 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,
+ },
+ }
+
+ 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",
+ }
+ }
+ `
+
+ 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,
+ },
+ }
+
+ 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)
+
+ if disallowedFlagActual != testCase.disallowedFlagExpected {
+ t.Errorf("Failed testcase: %v \nActual lint cmd: %v", testCase.testCaseName, *sboxProto.Commands[0].Command)
+ }
+ }
+}
+
+// checks transtive deps of an apex coming from bootclasspath_fragment
+func TestApexStrictUpdtabilityLintBcpFragmentDeps(t *testing.T) {
+ bp := `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ bootclasspath_fragments: ["mybootclasspathfragment"],
+ updatable: true,
+ min_sdk_version: "29",
+ }
+ apex_key {
+ name: "myapex.key",
+ }
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ contents: ["myjavalib"],
+ apex_available: ["myapex"],
+ hidden_api: {
+ split_packages: ["*"],
+ },
+ }
+ java_library {
+ name: "myjavalib",
+ srcs: ["MyClass.java"],
+ apex_available: [ "myapex" ],
+ sdk_version: "current",
+ min_sdk_version: "29",
+ compile_dex: true,
+ lint: {
+ baseline_filename: "lint-baseline.xml",
+ }
+ }
+ `
+ fs := android.MockFS{
+ "lint-baseline.xml": nil,
+ }
+
+ 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)
+ }
+}
// updatable apexes should propagate updatable=true to its apps
func TestUpdatableApexEnforcesAppUpdatability(t *testing.T) {
@@ -10947,25 +11124,23 @@ func TestAconfigFilesJavaDeps(t *testing.T) {
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 5 {
+ if len(copyCmds) != 8 {
t.Fatalf("Expected 5 commands, got %d in:\n%s", len(copyCmds), s)
}
- ensureMatches(t, copyCmds[4], "^cp -f .*/aconfig_flags.pb .*/image.apex$")
+ ensureMatches(t, copyCmds[4], "^cp -f .*/aconfig_flags.pb .*/image.apex/etc$")
+ ensureMatches(t, copyCmds[5], "^cp -f .*/package.map .*/image.apex/etc$")
+ ensureMatches(t, copyCmds[6], "^cp -f .*/flag.map .*/image.apex/etc$")
+ ensureMatches(t, copyCmds[7], "^cp -f .*/flag.val .*/image.apex/etc$")
- combineAconfigRule := mod.Rule("All_aconfig_declarations_dump")
- s = " " + combineAconfigRule.Args["cache_files"]
- aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:]
- if len(aconfigArgs) != 2 {
- t.Fatalf("Expected 2 commands, got %d in:\n%s", len(aconfigArgs), s)
+ inputs := []string{
+ "my_aconfig_declarations_foo/intermediate.pb",
+ "my_aconfig_declarations_bar/intermediate.pb",
}
- android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb")
- android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_bar/intermediate.pb")
-
- buildParams := combineAconfigRule.BuildParams
- android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb")
- android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_bar/intermediate.pb")
- ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb")
+ VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "")
+ 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")
}
func TestAconfigFilesJavaAndCcDeps(t *testing.T) {
@@ -11073,30 +11248,24 @@ func TestAconfigFilesJavaAndCcDeps(t *testing.T) {
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 9 {
- t.Fatalf("Expected 9 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 12 {
+ t.Fatalf("Expected 12 commands, got %d in:\n%s", len(copyCmds), s)
}
- ensureMatches(t, copyCmds[8], "^cp -f .*/aconfig_flags.pb .*/image.apex$")
-
- combineAconfigRule := mod.Rule("All_aconfig_declarations_dump")
- s = " " + combineAconfigRule.Args["cache_files"]
- aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:]
- if len(aconfigArgs) != 3 {
- t.Fatalf("Expected 3 commands, got %d in:\n%s", len(aconfigArgs), s)
- }
- android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb")
- android.EnsureListContainsSuffix(t, aconfigArgs, "my_cc_library_bar/android_arm64_armv8-a_shared_apex10000/aconfig_merged.pb")
- android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_baz/intermediate.pb")
+ ensureMatches(t, copyCmds[8], "^cp -f .*/aconfig_flags.pb .*/image.apex/etc$")
+ ensureMatches(t, copyCmds[9], "^cp -f .*/package.map .*/image.apex/etc$")
+ ensureMatches(t, copyCmds[10], "^cp -f .*/flag.map .*/image.apex/etc$")
+ ensureMatches(t, copyCmds[11], "^cp -f .*/flag.val .*/image.apex/etc$")
- buildParams := combineAconfigRule.BuildParams
- if len(buildParams.Inputs) != 3 {
- t.Fatalf("Expected 3 input, got %d", len(buildParams.Inputs))
+ inputs := []string{
+ "my_aconfig_declarations_foo/intermediate.pb",
+ "my_cc_library_bar/android_arm64_armv8-a_shared_apex10000/myapex/aconfig_merged.pb",
+ "my_aconfig_declarations_baz/intermediate.pb",
}
- android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb")
- android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_cc_library_bar/android_arm64_armv8-a_shared_apex10000/aconfig_merged.pb")
- android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_baz/intermediate.pb")
- ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb")
+ VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "")
+ 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")
}
func TestAconfigFilesRustDeps(t *testing.T) {
@@ -11220,28 +11389,45 @@ func TestAconfigFilesRustDeps(t *testing.T) {
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 23 {
- t.Fatalf("Expected 23 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 26 {
+ t.Fatalf("Expected 26 commands, got %d in:\n%s", len(copyCmds), s)
}
- ensureMatches(t, copyCmds[22], "^cp -f .*/aconfig_flags.pb .*/image.apex$")
+ ensureMatches(t, copyCmds[22], "^cp -f .*/aconfig_flags.pb .*/image.apex/etc$")
+ ensureMatches(t, copyCmds[23], "^cp -f .*/package.map .*/image.apex/etc$")
+ ensureMatches(t, copyCmds[24], "^cp -f .*/flag.map .*/image.apex/etc$")
+ ensureMatches(t, copyCmds[25], "^cp -f .*/flag.val .*/image.apex/etc$")
- combineAconfigRule := mod.Rule("All_aconfig_declarations_dump")
- s = " " + combineAconfigRule.Args["cache_files"]
+ inputs := []string{
+ "my_aconfig_declarations_foo/intermediate.pb",
+ "my_aconfig_declarations_bar/intermediate.pb",
+ "my_aconfig_declarations_baz/intermediate.pb",
+ "my_rust_binary/android_arm64_armv8-a_apex10000/myapex/aconfig_merged.pb",
+ }
+ VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "")
+ 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")
+}
+
+func VerifyAconfigRule(t *testing.T, mod *android.TestingModule, desc string, inputs []string, output string, container string, file_type string) {
+ aconfigRule := mod.Description(desc)
+ s := " " + aconfigRule.Args["cache_files"]
aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:]
- if len(aconfigArgs) != 2 {
- t.Fatalf("Expected 2 commands, got %d in:\n%s", len(aconfigArgs), s)
+ if len(aconfigArgs) != len(inputs) {
+ t.Fatalf("Expected %d commands, got %d in:\n%s", len(inputs), len(aconfigArgs), s)
}
- android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb")
- android.EnsureListContainsSuffix(t, aconfigArgs, "my_rust_binary/android_arm64_armv8-a_apex10000/aconfig_merged.pb")
- buildParams := combineAconfigRule.BuildParams
- if len(buildParams.Inputs) != 2 {
- t.Fatalf("Expected 3 input, got %d", len(buildParams.Inputs))
+ ensureEquals(t, container, aconfigRule.Args["container"])
+ ensureEquals(t, file_type, aconfigRule.Args["file_type"])
+
+ buildParams := aconfigRule.BuildParams
+ for _, input := range inputs {
+ android.EnsureListContainsSuffix(t, aconfigArgs, input)
+ android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), input)
}
- android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb")
- android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_rust_binary/android_arm64_armv8-a_apex10000/aconfig_merged.pb")
- ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb")
+
+ ensureContains(t, buildParams.Output.String(), output)
}
func TestAconfigFilesOnlyMatchCurrentApex(t *testing.T) {
@@ -11404,3 +11590,343 @@ func TestAconfigFilesRemoveDuplicates(t *testing.T) {
android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb")
ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb")
}
+
+// Test that the boot jars come from the _selected_ apex prebuilt
+// RELEASE_APEX_CONTIRBUTIONS_* build flags will be used to select the correct prebuilt for a specific release config
+func TestBootDexJarsMultipleApexPrebuilts(t *testing.T) {
+ checkBootDexJarPath := func(t *testing.T, ctx *android.TestContext, stem string, bootDexJarPath string) {
+ t.Helper()
+ s := ctx.ModuleForTests("dex_bootjars", "android_common")
+ foundLibfooJar := false
+ base := stem + ".jar"
+ for _, output := range s.AllOutputs() {
+ if filepath.Base(output) == base {
+ foundLibfooJar = true
+ buildRule := s.Output(output)
+ android.AssertStringEquals(t, "boot dex jar path", bootDexJarPath, buildRule.Input.String())
+ }
+ }
+ if !foundLibfooJar {
+ t.Errorf("Rule for libfoo.jar missing in dex_bootjars singleton outputs %q", android.StringPathsRelativeToTop(ctx.Config().SoongOutDir(), s.AllOutputs()))
+ }
+ }
+
+ // Check that the boot jars of the selected apex are run through boot_jars_package_check
+ // This validates that the jars on the bootclasspath do not contain packages outside an allowlist
+ checkBootJarsPackageCheck := func(t *testing.T, ctx *android.TestContext, expectedBootJar string) {
+ platformBcp := ctx.ModuleForTests("platform-bootclasspath", "android_common")
+ bootJarsCheckRule := platformBcp.Rule("boot_jars_package_check")
+ android.AssertStringMatches(t, "Could not find the correct boot dex jar in package check rule", bootJarsCheckRule.RuleParams.Command, "build/soong/scripts/check_boot_jars/package_allowed_list.txt.*"+expectedBootJar)
+ }
+
+ // Check that the boot jars used to generate the monolithic hiddenapi flags come from the selected apex
+ checkBootJarsForMonolithicHiddenapi := func(t *testing.T, ctx *android.TestContext, expectedBootJar string) {
+ monolithicHiddenapiFlagsCmd := ctx.ModuleForTests("platform-bootclasspath", "android_common").Output("out/soong/hiddenapi/hiddenapi-stub-flags.txt").RuleParams.Command
+ android.AssertStringMatches(t, "Could not find the correct boot dex jar in monolithic hiddenapi flags generation command", monolithicHiddenapiFlagsCmd, "--boot-dex="+expectedBootJar)
+ }
+
+ bp := `
+ // Source APEX.
+
+ java_library {
+ name: "framework-foo",
+ srcs: ["foo.java"],
+ installable: true,
+ apex_available: [
+ "com.android.foo",
+ ],
+ }
+
+ bootclasspath_fragment {
+ name: "foo-bootclasspath-fragment",
+ contents: ["framework-foo"],
+ apex_available: [
+ "com.android.foo",
+ ],
+ hidden_api: {
+ split_packages: ["*"],
+ },
+ }
+
+ apex_key {
+ name: "com.android.foo.key",
+ public_key: "com.android.foo.avbpubkey",
+ private_key: "com.android.foo.pem",
+ }
+
+ apex {
+ name: "com.android.foo",
+ key: "com.android.foo.key",
+ bootclasspath_fragments: ["foo-bootclasspath-fragment"],
+ updatable: false,
+ }
+
+ // Prebuilt APEX.
+
+ java_sdk_library_import {
+ name: "framework-foo",
+ public: {
+ jars: ["foo.jar"],
+ },
+ apex_available: ["com.android.foo"],
+ shared_library: false,
+ }
+
+ prebuilt_bootclasspath_fragment {
+ name: "foo-bootclasspath-fragment",
+ contents: ["framework-foo"],
+ hidden_api: {
+ annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
+ metadata: "my-bootclasspath-fragment/metadata.csv",
+ index: "my-bootclasspath-fragment/index.csv",
+ stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
+ all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ },
+ apex_available: [
+ "com.android.foo",
+ ],
+ }
+
+ prebuilt_apex {
+ name: "com.android.foo",
+ apex_name: "com.android.foo",
+ src: "com.android.foo-arm.apex",
+ exported_bootclasspath_fragments: ["foo-bootclasspath-fragment"],
+ }
+
+ // Another Prebuilt ART APEX
+ prebuilt_apex {
+ name: "com.android.foo.v2",
+ apex_name: "com.android.foo", // Used to determine the API domain
+ src: "com.android.foo-arm.apex",
+ exported_bootclasspath_fragments: ["foo-bootclasspath-fragment"],
+ }
+
+ // APEX contribution modules
+
+ apex_contributions {
+ name: "foo.source.contributions",
+ api_domain: "com.android.foo",
+ contents: ["com.android.foo"],
+ }
+
+ apex_contributions {
+ name: "foo.prebuilt.contributions",
+ api_domain: "com.android.foo",
+ contents: ["prebuilt_com.android.foo"],
+ }
+
+ apex_contributions {
+ name: "foo.prebuilt.v2.contributions",
+ api_domain: "com.android.foo",
+ contents: ["com.android.foo.v2"], // prebuilt_ prefix is missing because of prebuilt_rename mutator
+ }
+ `
+
+ testCases := []struct {
+ desc string
+ selectedApexContributions string
+ expectedBootJar string
+ }{
+ {
+ desc: "Source apex com.android.foo is selected, bootjar should come from source java library",
+ selectedApexContributions: "foo.source.contributions",
+ expectedBootJar: "out/soong/.intermediates/foo-bootclasspath-fragment/android_common_apex10000/hiddenapi-modular/encoded/framework-foo.jar",
+ },
+ {
+ desc: "Prebuilt apex prebuilt_com.android.foo is selected, profile should come from .prof deapexed from the prebuilt",
+ selectedApexContributions: "foo.prebuilt.contributions",
+ expectedBootJar: "out/soong/.intermediates/prebuilt_com.android.foo.deapexer/android_common/deapexer/javalib/framework-foo.jar",
+ },
+ {
+ desc: "Prebuilt apex prebuilt_com.android.foo.v2 is selected, profile should come from .prof deapexed from the prebuilt",
+ selectedApexContributions: "foo.prebuilt.v2.contributions",
+ expectedBootJar: "out/soong/.intermediates/prebuilt_com.android.foo.v2.deapexer/android_common/deapexer/javalib/framework-foo.jar",
+ },
+ }
+
+ fragment := java.ApexVariantReference{
+ Apex: proptools.StringPtr("com.android.foo"),
+ Module: proptools.StringPtr("foo-bootclasspath-fragment"),
+ }
+
+ for _, tc := range testCases {
+ preparer := android.GroupFixturePreparers(
+ java.FixtureConfigureApexBootJars("com.android.foo:framework-foo"),
+ android.FixtureMergeMockFs(map[string][]byte{
+ "system/sepolicy/apex/com.android.foo-file_contexts": nil,
+ }),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": tc.selectedApexContributions,
+ }
+ }),
+ )
+ ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
+ checkBootDexJarPath(t, ctx, "framework-foo", tc.expectedBootJar)
+ checkBootJarsPackageCheck(t, ctx, tc.expectedBootJar)
+ checkBootJarsForMonolithicHiddenapi(t, ctx, tc.expectedBootJar)
+ }
+}
+
+// Test that product packaging installs the selected mainline module (either source or a specific prebuilt)
+// RELEASE_APEX_CONTIRBUTIONS_* build flags will be used to select the correct prebuilt for a specific release config
+func TestInstallationRulesForMultipleApexPrebuilts(t *testing.T) {
+ // check that the LOCAL_MODULE in the generated mk file matches the name used in PRODUCT_PACKAGES
+ // Since the name used in PRODUCT_PACKAGES does not contain prebuilt_ prefix, LOCAL_MODULE should not contain any prefix either
+ checkLocalModuleName := func(t *testing.T, ctx *android.TestContext, soongApexModuleName string, expectedLocalModuleName string) {
+ // Variations are created based on apex_name
+ entries := android.AndroidMkEntriesForTest(t, ctx, ctx.ModuleForTests(soongApexModuleName, "android_common_com.android.foo").Module())
+ android.AssertStringEquals(t, "LOCAL_MODULE of the prebuilt apex must match the name listed in PRODUCT_PACKAGES", expectedLocalModuleName, entries[0].EntryMap["LOCAL_MODULE"][0])
+ }
+ // for a mainline module family, check that only the flagged soong module is visible to make
+ checkHideFromMake := func(t *testing.T, ctx *android.TestContext, visibleModuleName string, hiddenModuleNames []string) {
+ variation := func(moduleName string) string {
+ ret := "android_common_com.android.foo"
+ if moduleName == "com.google.android.foo" {
+ ret = "android_common_com.google.android.foo_com.android.foo"
+ }
+ return ret
+ }
+
+ visibleModule := ctx.ModuleForTests(visibleModuleName, variation(visibleModuleName)).Module()
+ android.AssertBoolEquals(t, "Apex "+visibleModuleName+" selected using apex_contributions should be visible to make", false, visibleModule.IsHideFromMake())
+
+ for _, hiddenModuleName := range hiddenModuleNames {
+ hiddenModule := ctx.ModuleForTests(hiddenModuleName, variation(hiddenModuleName)).Module()
+ android.AssertBoolEquals(t, "Apex "+hiddenModuleName+" not selected using apex_contributions should be hidden from make", true, hiddenModule.IsHideFromMake())
+
+ }
+ }
+
+ bp := `
+ apex_key {
+ name: "com.android.foo.key",
+ public_key: "com.android.foo.avbpubkey",
+ private_key: "com.android.foo.pem",
+ }
+
+ // AOSP source apex
+ apex {
+ name: "com.android.foo",
+ key: "com.android.foo.key",
+ updatable: false,
+ }
+
+ // Google source apex
+ override_apex {
+ name: "com.google.android.foo",
+ base: "com.android.foo",
+ key: "com.android.foo.key",
+ }
+
+ // Prebuilt Google APEX.
+
+ prebuilt_apex {
+ name: "com.google.android.foo",
+ apex_name: "com.android.foo",
+ src: "com.android.foo-arm.apex",
+ prefer: true, // prefer is set to true on both the prebuilts to induce an error if flagging is not present
+ }
+
+ // Another Prebuilt Google APEX
+ prebuilt_apex {
+ name: "com.google.android.foo.v2",
+ apex_name: "com.android.foo",
+ source_apex_name: "com.google.android.foo", // source_apex_name becomes LOCAL_MODULE in the generated mk file
+ src: "com.android.foo-arm.apex",
+ prefer: true, // prefer is set to true on both the prebuilts to induce an error if flagging is not present
+ }
+
+ // APEX contribution modules
+
+ apex_contributions {
+ name: "foo.source.contributions",
+ api_domain: "com.android.foo",
+ contents: ["com.google.android.foo"],
+ }
+
+ apex_contributions {
+ name: "foo.prebuilt.contributions",
+ api_domain: "com.android.foo",
+ contents: ["prebuilt_com.google.android.foo"],
+ }
+
+ apex_contributions {
+ name: "foo.prebuilt.v2.contributions",
+ api_domain: "com.android.foo",
+ contents: ["prebuilt_com.google.android.foo.v2"],
+ }
+
+ // This is an incompatible module because it selects multiple versions of the same mainline module
+ apex_contributions {
+ name: "foo.prebuilt.duplicate.contributions",
+ api_domain: "com.android.foo",
+ contents: [
+ "prebuilt_com.google.android.foo",
+ "prebuilt_com.google.android.foo.v2",
+ ],
+ }
+ `
+
+ testCases := []struct {
+ desc string
+ selectedApexContributions string
+ expectedVisibleModuleName string
+ expectedHiddenModuleNames []string
+ expectedError string
+ }{
+ {
+ desc: "Source apex is selected, prebuilts should be hidden from make",
+ selectedApexContributions: "foo.source.contributions",
+ expectedVisibleModuleName: "com.google.android.foo",
+ expectedHiddenModuleNames: []string{"prebuilt_com.google.android.foo", "prebuilt_com.google.android.foo.v2"},
+ },
+ {
+ desc: "Prebuilt apex prebuilt_com.android.foo is selected, source and the other prebuilt should be hidden from make",
+ selectedApexContributions: "foo.prebuilt.contributions",
+ expectedVisibleModuleName: "prebuilt_com.google.android.foo",
+ expectedHiddenModuleNames: []string{"com.google.android.foo", "prebuilt_com.google.android.foo.v2"},
+ },
+ {
+ desc: "Prebuilt apex prebuilt_com.android.fooi.v2 is selected, source and the other prebuilt should be hidden from make",
+ selectedApexContributions: "foo.prebuilt.v2.contributions",
+ expectedVisibleModuleName: "prebuilt_com.google.android.foo.v2",
+ expectedHiddenModuleNames: []string{"com.google.android.foo", "prebuilt_com.google.android.foo"},
+ },
+ {
+ desc: "Multiple versions of a prebuilt apex is selected in the same release config",
+ selectedApexContributions: "foo.prebuilt.duplicate.contributions",
+ expectedError: "Found duplicate variations of the same module in apex_contributions: prebuilt_com.google.android.foo and prebuilt_com.google.android.foo.v2",
+ },
+ }
+
+ for _, tc := range testCases {
+ preparer := android.GroupFixturePreparers(
+ android.FixtureMergeMockFs(map[string][]byte{
+ "system/sepolicy/apex/com.android.foo-file_contexts": nil,
+ }),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": tc.selectedApexContributions,
+ }
+ }),
+ )
+ if tc.expectedError != "" {
+ preparer = preparer.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(tc.expectedError))
+ testApex(t, bp, preparer)
+ return
+ }
+ ctx := testApex(t, bp, preparer)
+
+ // Check that the LOCAL_MODULE of the two prebuilts is com.android.foo
+ // This ensures that product packaging can pick them for installation if it has been flagged by apex_contributions
+ checkLocalModuleName(t, ctx, "prebuilt_com.google.android.foo", "com.google.android.foo")
+ checkLocalModuleName(t, ctx, "prebuilt_com.google.android.foo.v2", "com.google.android.foo")
+
+ // Check that
+ // 1. The contents of the selected apex_contributions are visible to make
+ // 2. The rest of the apexes in the mainline module family (source or other prebuilt) is hidden from make
+ checkHideFromMake(t, ctx, tc.expectedVisibleModuleName, tc.expectedHiddenModuleNames)
+ }
+}
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index 43be310bb..778c20a56 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -53,7 +53,11 @@ func TestBootclasspathFragments_FragmentDependency(t *testing.T) {
java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
java.FixtureConfigureApexBootJars("someapex:foo", "someapex:bar"),
prepareForTestWithArtApex,
-
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+ }
+ }),
java.PrepareForTestWithJavaSdkLibraryFiles,
java.FixtureWithLastReleaseApis("foo", "baz"),
).RunTestWithBp(t, `
@@ -152,11 +156,11 @@ func TestBootclasspathFragments_FragmentDependency(t *testing.T) {
// Check stub dex paths exported by art.
artFragment := result.Module("art-bootclasspath-fragment", "android_common")
- artInfo := result.ModuleProvider(artFragment, java.HiddenAPIInfoProvider).(java.HiddenAPIInfo)
+ artInfo, _ := android.SingletonModuleProvider(result, artFragment, java.HiddenAPIInfoProvider)
- bazPublicStubs := "out/soong/.intermediates/baz.stubs/android_common/dex/baz.stubs.jar"
- bazSystemStubs := "out/soong/.intermediates/baz.stubs.system/android_common/dex/baz.stubs.system.jar"
- bazTestStubs := "out/soong/.intermediates/baz.stubs.test/android_common/dex/baz.stubs.test.jar"
+ bazPublicStubs := "out/soong/.intermediates/baz.stubs.exportable/android_common/dex/baz.stubs.exportable.jar"
+ bazSystemStubs := "out/soong/.intermediates/baz.stubs.exportable.system/android_common/dex/baz.stubs.exportable.system.jar"
+ bazTestStubs := "out/soong/.intermediates/baz.stubs.exportable.test/android_common/dex/baz.stubs.exportable.test.jar"
checkAPIScopeStubs("art", artInfo, java.PublicHiddenAPIScope, bazPublicStubs)
checkAPIScopeStubs("art", artInfo, java.SystemHiddenAPIScope, bazSystemStubs)
@@ -165,10 +169,10 @@ func TestBootclasspathFragments_FragmentDependency(t *testing.T) {
// Check stub dex paths exported by other.
otherFragment := result.Module("other-bootclasspath-fragment", "android_common")
- otherInfo := result.ModuleProvider(otherFragment, java.HiddenAPIInfoProvider).(java.HiddenAPIInfo)
+ otherInfo, _ := android.SingletonModuleProvider(result, otherFragment, java.HiddenAPIInfoProvider)
- fooPublicStubs := "out/soong/.intermediates/foo.stubs/android_common/dex/foo.stubs.jar"
- fooSystemStubs := "out/soong/.intermediates/foo.stubs.system/android_common/dex/foo.stubs.system.jar"
+ fooPublicStubs := "out/soong/.intermediates/foo.stubs.exportable/android_common/dex/foo.stubs.exportable.jar"
+ fooSystemStubs := "out/soong/.intermediates/foo.stubs.exportable.system/android_common/dex/foo.stubs.exportable.system.jar"
checkAPIScopeStubs("other", otherInfo, java.PublicHiddenAPIScope, bazPublicStubs, fooPublicStubs)
checkAPIScopeStubs("other", otherInfo, java.SystemHiddenAPIScope, bazSystemStubs, fooSystemStubs)
@@ -312,6 +316,7 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) {
java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
`art-bootclasspath-fragment`,
`com.android.art.key`,
+ `dex2oatd`,
})
// Make sure that the source bootclasspath_fragment copies its dex files to the predefined
@@ -374,7 +379,7 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) {
java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
).RunTest(t)
- ensureExactDeapexedContents(t, result.TestContext, "com.android.art", "android_common", []string{
+ ensureExactDeapexedContents(t, result.TestContext, "prebuilt_com.android.art", "android_common", []string{
"etc/boot-image.prof",
"javalib/bar.jar",
"javalib/foo.jar",
@@ -383,6 +388,7 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) {
java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
`art-bootclasspath-fragment`,
`com.android.art.key`,
+ `dex2oatd`,
`prebuilt_com.android.art`,
})
@@ -529,14 +535,16 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
result := preparers.RunTestWithBp(t, fmt.Sprintf(bp, "enabled: false,"))
java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
- `com.android.art.apex.selector`,
+ `dex2oatd`,
`prebuilt_art-bootclasspath-fragment`,
+ `prebuilt_com.android.art.apex.selector`,
+ `prebuilt_com.android.art.deapexer`,
})
java.CheckModuleDependencies(t, result.TestContext, "art-bootclasspath-fragment", "android_common_com.android.art", []string{
- `com.android.art.deapexer`,
`dex2oatd`,
`prebuilt_bar`,
+ `prebuilt_com.android.art.deapexer`,
`prebuilt_foo`,
})
@@ -546,7 +554,7 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
t.Run("enabled alternative APEX", func(t *testing.T) {
preparers.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
- "Multiple installable prebuilt APEXes provide ambiguous deapexers: com.android.art and com.mycompany.android.art")).
+ "Multiple installable prebuilt APEXes provide ambiguous deapexers: prebuilt_com.android.art and prebuilt_com.mycompany.android.art")).
RunTestWithBp(t, fmt.Sprintf(bp, ""))
})
}
@@ -644,6 +652,7 @@ func TestBootclasspathFragmentContentsNoName(t *testing.T) {
})
java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{
+ `dex2oatd`,
`myapex.key`,
`mybootclasspathfragment`,
})
@@ -655,7 +664,7 @@ func TestBootclasspathFragmentContentsNoName(t *testing.T) {
// Make sure that the fragment provides the hidden API encoded dex jars to the APEX.
fragment := result.Module("mybootclasspathfragment", "android_common_apex10000")
- info := result.ModuleProvider(fragment, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
+ info, _ := android.SingletonModuleProvider(result, fragment, java.BootclasspathFragmentApexContentInfoProvider)
checkFragmentExportedDexJar := func(name string, expectedDexJar string) {
module := result.Module(name, "android_common_apex10000")
@@ -675,7 +684,7 @@ func TestBootclasspathFragmentContentsNoName(t *testing.T) {
func getDexJarPath(result *android.TestResult, name string) string {
module := result.Module(name, "android_common")
- return module.(java.UsesLibraryDependency).DexJarBuildPath().Path().RelativeToTop().String()
+ return module.(java.UsesLibraryDependency).DexJarBuildPath(moduleErrorfTestCtx{}).Path().RelativeToTop().String()
}
// TestBootclasspathFragment_HiddenAPIList checks to make sure that the correct parameters are
@@ -694,6 +703,11 @@ func TestBootclasspathFragment_HiddenAPIList(t *testing.T) {
java.PrepareForTestWithJavaSdkLibraryFiles,
java.FixtureWithLastReleaseApis("foo", "quuz"),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+ }
+ }),
).RunTestWithBp(t, `
apex {
name: "com.android.art",
@@ -805,11 +819,11 @@ func TestBootclasspathFragment_HiddenAPIList(t *testing.T) {
"foo",
})
- fooStubs := getDexJarPath(result, "foo.stubs")
- quuzPublicStubs := getDexJarPath(result, "quuz.stubs")
- quuzSystemStubs := getDexJarPath(result, "quuz.stubs.system")
- quuzTestStubs := getDexJarPath(result, "quuz.stubs.test")
- quuzModuleLibStubs := getDexJarPath(result, "quuz.stubs.module_lib")
+ fooStubs := getDexJarPath(result, "foo.stubs.exportable")
+ quuzPublicStubs := getDexJarPath(result, "quuz.stubs.exportable")
+ quuzSystemStubs := getDexJarPath(result, "quuz.stubs.exportable.system")
+ quuzTestStubs := getDexJarPath(result, "quuz.stubs.exportable.test")
+ quuzModuleLibStubs := getDexJarPath(result, "quuz.stubs.exportable.module_lib")
// Make sure that the fragment uses the quuz stub dex jars when generating the hidden API flags.
fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
diff --git a/apex/builder.go b/apex/builder.go
index 30788630b..6ad282ab6 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -85,6 +85,18 @@ func init() {
pctx.HostBinToolVariable("aconfig", "aconfig")
}
+type createStorageStruct struct {
+ Output_file string
+ Desc string
+ File_type string
+}
+
+var createStorageInfo = []createStorageStruct{
+ {"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"},
+}
+
var (
apexManifestRule = pctx.StaticRule("apexManifestRule", blueprint.RuleParams{
Command: `rm -f $out && ${jsonmodify} $in ` +
@@ -633,6 +645,7 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) {
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
defaultReadOnlyFiles := []string{"apex_manifest.json", "apex_manifest.pb"}
+ aconfigDest := imageDir.Join(ctx, "etc").String()
if len(a.aconfigFiles) > 0 {
apexAconfigFile := android.PathForModuleOut(ctx, "aconfig_flags.pb")
ctx.Build(pctx, android.BuildParams{
@@ -645,9 +658,28 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) {
},
})
- copyCommands = append(copyCommands, "cp -f "+apexAconfigFile.String()+" "+imageDir.String())
+ copyCommands = append(copyCommands, "cp -f "+apexAconfigFile.String()+" "+aconfigDest)
implicitInputs = append(implicitInputs, apexAconfigFile)
- defaultReadOnlyFiles = append(defaultReadOnlyFiles, apexAconfigFile.Base())
+ defaultReadOnlyFiles = append(defaultReadOnlyFiles, "etc/"+apexAconfigFile.Base())
+
+ for _, info := range createStorageInfo {
+ outputFile := android.PathForModuleOut(ctx, info.Output_file)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: aconfig.CreateStorageRule,
+ Inputs: a.aconfigFiles,
+ Output: outputFile,
+ Description: info.Desc,
+ Args: map[string]string{
+ "container": ctx.ModuleName(),
+ "file_type": info.File_type,
+ "cache_files": android.JoinPathsWithPrefix(a.aconfigFiles, "--cache "),
+ },
+ })
+
+ copyCommands = append(copyCommands, "cp -f "+outputFile.String()+" "+aconfigDest)
+ implicitInputs = append(implicitInputs, outputFile)
+ defaultReadOnlyFiles = append(defaultReadOnlyFiles, "etc/"+outputFile.Base())
+ }
}
////////////////////////////////////////////////////////////////////////////////////
@@ -695,18 +727,20 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) {
if moduleMinSdkVersion.IsCurrent() || moduleMinSdkVersion.IsNone() {
minSdkVersion = ctx.Config().DefaultAppTargetSdk(ctx).String()
- if java.UseApiFingerprint(ctx) {
- minSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String())
- implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx))
+ if useApiFingerprint, fingerprintMinSdkVersion, fingerprintDeps :=
+ java.UseApiFingerprint(ctx); useApiFingerprint {
+ minSdkVersion = fingerprintMinSdkVersion
+ implicitInputs = append(implicitInputs, fingerprintDeps)
}
}
// apex module doesn't have a concept of target_sdk_version, hence for the time
// being targetSdkVersion == default targetSdkVersion of the branch.
targetSdkVersion := strconv.Itoa(ctx.Config().DefaultAppTargetSdk(ctx).FinalOrFutureInt())
- if java.UseApiFingerprint(ctx) {
- targetSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String())
- implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx))
+ if useApiFingerprint, fingerprintTargetSdkVersion, fingerprintDeps :=
+ java.UseApiFingerprint(ctx); useApiFingerprint {
+ targetSdkVersion = fingerprintTargetSdkVersion
+ implicitInputs = append(implicitInputs, fingerprintDeps)
}
optFlags = append(optFlags, "--target_sdk_version "+targetSdkVersion)
optFlags = append(optFlags, "--min_sdk_version "+minSdkVersion)
@@ -910,7 +944,7 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) {
var validations android.Paths
validations = append(validations, runApexLinkerconfigValidation(ctx, unsignedOutputFile.OutputPath, imageDir.OutputPath))
// TODO(b/279688635) deapexer supports [ext4]
- if suffix == imageApexSuffix && ext4 == a.payloadFsType {
+ if !a.testApex && suffix == imageApexSuffix && ext4 == a.payloadFsType {
validations = append(validations, runApexSepolicyTests(ctx, unsignedOutputFile.OutputPath))
}
if !a.testApex && len(a.properties.Unwanted_transitive_deps) > 0 {
diff --git a/apex/classpath_element_test.go b/apex/classpath_element_test.go
index 9142eed99..b9a91982a 100644
--- a/apex/classpath_element_test.go
+++ b/apex/classpath_element_test.go
@@ -20,7 +20,6 @@ import (
"android/soong/android"
"android/soong/java"
- "github.com/google/blueprint"
)
// Contains tests for java.CreateClasspathElements logic from java/classpath_element.go that
@@ -28,19 +27,12 @@ import (
// testClasspathElementContext is a ClasspathElementContext suitable for use in tests.
type testClasspathElementContext struct {
+ android.OtherModuleProviderContext
testContext *android.TestContext
module android.Module
errs []error
}
-func (t *testClasspathElementContext) OtherModuleHasProvider(module blueprint.Module, provider blueprint.ProviderKey) bool {
- return t.testContext.ModuleHasProvider(module, provider)
-}
-
-func (t *testClasspathElementContext) OtherModuleProvider(module blueprint.Module, provider blueprint.ProviderKey) interface{} {
- return t.testContext.ModuleProvider(module, provider)
-}
-
func (t *testClasspathElementContext) ModuleErrorf(fmt string, args ...interface{}) {
t.errs = append(t.errs, t.testContext.ModuleErrorf(t.module, fmt, args...))
}
@@ -238,7 +230,11 @@ func TestCreateClasspathElements(t *testing.T) {
}
newCtx := func() *testClasspathElementContext {
- return &testClasspathElementContext{testContext: result.TestContext, module: bootclasspath}
+ return &testClasspathElementContext{
+ OtherModuleProviderContext: result.TestContext.OtherModuleProviderAdaptor(),
+ testContext: result.TestContext,
+ module: bootclasspath,
+ }
}
// Verify that CreateClasspathElements works when given valid input.
diff --git a/apex/deapexer.go b/apex/deapexer.go
index 3b7c77dc9..a6731080c 100644
--- a/apex/deapexer.go
+++ b/apex/deapexer.go
@@ -53,6 +53,10 @@ type DeapexerProperties struct {
// all architectures, e.g. java.
CommonModules []string
+ // List of modules that use an embedded .prof to guide optimization of the equivalent dexpreopt artifact
+ // This is a subset of CommonModules
+ DexpreoptProfileGuidedModules []string
+
// List of files exported from the .apex file by this module
//
// Each entry is a path from the apex root, e.g. javalib/core-libart.jar.
@@ -98,6 +102,7 @@ func privateDeapexerFactory() android.Module {
func (p *Deapexer) DepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependencies from the java modules to which this exports files from the `.apex` file onto
// this module so that they can access the `DeapexerInfo` object that this provides.
+ // TODO: b/308174306 - Once all the mainline modules have been flagged, drop this dependency edge
for _, lib := range p.properties.CommonModules {
dep := prebuiltApexExportedModuleName(ctx, lib)
ctx.AddReverseDependency(ctx.Module(), android.DeapexerTag, dep)
@@ -126,8 +131,9 @@ func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// apex relative path to extracted file path available for other modules.
if len(exports) > 0 {
// Make the information available for other modules.
- di := android.NewDeapexerInfo(apexModuleName(ctx.ModuleName()), exports)
- ctx.SetProvider(android.DeapexerProvider, di)
+ di := android.NewDeapexerInfo(apexModuleName(ctx.ModuleName()), exports, p.properties.CommonModules)
+ di.AddDexpreoptProfileGuidedExportedModuleNames(p.properties.DexpreoptProfileGuidedModules...)
+ android.SetProvider(ctx, android.DeapexerProvider, di)
// Create a sorted list of the files that this exports.
exportedPaths = android.SortedUniquePaths(exportedPaths)
diff --git a/apex/dexpreopt_bootjars_test.go b/apex/dexpreopt_bootjars_test.go
index 2e828cade..7a17f501c 100644
--- a/apex/dexpreopt_bootjars_test.go
+++ b/apex/dexpreopt_bootjars_test.go
@@ -164,6 +164,7 @@ func TestDexpreoptBootJarsWithSourceArtApex(t *testing.T) {
"out/soong/dexpreopt_arm64/dex_bootjars_input/baz.jar",
"out/soong/.intermediates/art-bootclasspath-fragment/android_common_apex10000/art-bootclasspath-fragment/boot.prof",
"out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof",
+ "out/soong/dexpreopt/uffd_gc_flag.txt",
}
expectedOutputs := []string{
@@ -199,8 +200,9 @@ func TestDexpreoptBootJarsWithPrebuiltArtApex(t *testing.T) {
"out/soong/dexpreopt_arm64/dex_bootjars_input/foo.jar",
"out/soong/dexpreopt_arm64/dex_bootjars_input/bar.jar",
"out/soong/dexpreopt_arm64/dex_bootjars_input/baz.jar",
- "out/soong/.intermediates/com.android.art.deapexer/android_common/deapexer/etc/boot-image.prof",
+ "out/soong/.intermediates/prebuilt_com.android.art.deapexer/android_common/deapexer/etc/boot-image.prof",
"out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof",
+ "out/soong/dexpreopt/uffd_gc_flag.txt",
}
expectedOutputs := []string{
@@ -252,3 +254,162 @@ func TestDexpreoptBootZip(t *testing.T) {
testDexpreoptBoot(t, ruleFile, expectedInputs, expectedOutputs, false)
}
+
+// Multiple ART apexes might exist in the tree.
+// The profile should correspond to the apex selected using release build flags
+func TestDexpreoptProfileWithMultiplePrebuiltArtApexes(t *testing.T) {
+ ruleFile := "out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.art"
+ bp := `
+ // Platform.
+
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ fragments: [
+ {
+ apex: "com.android.art",
+ module: "art-bootclasspath-fragment",
+ },
+ ],
+ }
+
+ // Source ART APEX.
+
+ java_library {
+ name: "core-oj",
+ srcs: ["core-oj.java"],
+ installable: true,
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ bootclasspath_fragment {
+ name: "art-bootclasspath-fragment",
+ image_name: "art",
+ contents: ["core-oj"],
+ apex_available: [
+ "com.android.art",
+ ],
+ hidden_api: {
+ split_packages: ["*"],
+ },
+ }
+
+ apex_key {
+ name: "com.android.art.key",
+ public_key: "com.android.art.avbpubkey",
+ private_key: "com.android.art.pem",
+ }
+
+ apex {
+ name: "com.android.art",
+ key: "com.android.art.key",
+ bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ updatable: false,
+ }
+
+ // Prebuilt ART APEX.
+
+ java_import {
+ name: "core-oj",
+ jars: ["core-oj.jar"],
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ prebuilt_bootclasspath_fragment {
+ name: "art-bootclasspath-fragment",
+ image_name: "art",
+ contents: ["core-oj"],
+ hidden_api: {
+ annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
+ metadata: "my-bootclasspath-fragment/metadata.csv",
+ index: "my-bootclasspath-fragment/index.csv",
+ stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
+ all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ },
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ prebuilt_apex {
+ name: "com.android.art",
+ apex_name: "com.android.art",
+ src: "com.android.art-arm.apex",
+ exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ }
+
+ // Another Prebuilt ART APEX
+ prebuilt_apex {
+ name: "com.android.art.v2",
+ apex_name: "com.android.art", // Used to determine the API domain
+ src: "com.android.art-arm.apex",
+ exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ }
+
+ // APEX contribution modules
+
+ apex_contributions {
+ name: "art.source.contributions",
+ api_domain: "com.android.art",
+ contents: ["com.android.art"],
+ }
+
+ apex_contributions {
+ name: "art.prebuilt.contributions",
+ api_domain: "com.android.art",
+ contents: ["prebuilt_com.android.art"],
+ }
+
+ apex_contributions {
+ name: "art.prebuilt.v2.contributions",
+ api_domain: "com.android.art",
+ contents: ["com.android.art.v2"], // prebuilt_ prefix is missing because of prebuilt_rename mutator
+ }
+
+ `
+
+ testCases := []struct {
+ desc string
+ selectedArtApexContributions string
+ expectedProfile string
+ }{
+ {
+ desc: "Source apex com.android.art is selected, profile should come from source java library",
+ selectedArtApexContributions: "art.source.contributions",
+ expectedProfile: "out/soong/.intermediates/art-bootclasspath-fragment/android_common_apex10000/art-bootclasspath-fragment/boot.prof",
+ },
+ {
+ desc: "Prebuilt apex prebuilt_com.android.art is selected, profile should come from .prof deapexed from the prebuilt",
+ selectedArtApexContributions: "art.prebuilt.contributions",
+ expectedProfile: "out/soong/.intermediates/prebuilt_com.android.art.deapexer/android_common/deapexer/etc/boot-image.prof",
+ },
+ {
+ desc: "Prebuilt apex prebuilt_com.android.art.v2 is selected, profile should come from .prof deapexed from the prebuilt",
+ selectedArtApexContributions: "art.prebuilt.v2.contributions",
+ expectedProfile: "out/soong/.intermediates/prebuilt_com.android.art.v2.deapexer/android_common/deapexer/etc/boot-image.prof",
+ },
+ }
+ for _, tc := range testCases {
+ result := android.GroupFixturePreparers(
+ java.PrepareForTestWithDexpreopt,
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureConfigureBootJars("com.android.art:core-oj"),
+ PrepareForTestWithApexBuildComponents,
+ prepareForTestWithArtApex,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_APEX_CONTRIBUTIONS_ART": tc.selectedArtApexContributions,
+ }
+ }),
+ ).RunTestWithBp(t, bp)
+
+ dexBootJars := result.ModuleForTests("dex_bootjars", "android_common")
+ rule := dexBootJars.Output(ruleFile)
+
+ inputs := rule.Implicits.Strings()
+ android.AssertStringListContains(t, tc.desc, inputs, tc.expectedProfile)
+ }
+}
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index 05bb13689..2be9c10e1 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -86,6 +86,7 @@ func TestPlatformBootclasspath_Fragments(t *testing.T) {
"bar-fragment",
],
updatable: false,
+ min_sdk_version: "30", // R
}
apex_key {
@@ -138,6 +139,7 @@ func TestPlatformBootclasspath_Fragments(t *testing.T) {
sdk_version: "none",
compile_dex: true,
permitted_packages: ["bar"],
+ min_sdk_version: "30", // R
}
java_sdk_library {
@@ -152,22 +154,22 @@ func TestPlatformBootclasspath_Fragments(t *testing.T) {
).RunTest(t)
pbcp := result.Module("platform-bootclasspath", "android_common")
- info := result.ModuleProvider(pbcp, java.MonolithicHiddenAPIInfoProvider).(java.MonolithicHiddenAPIInfo)
+ info, _ := android.SingletonModuleProvider(result, pbcp, java.MonolithicHiddenAPIInfoProvider)
for _, category := range java.HiddenAPIFlagFileCategories {
- name := category.PropertyName
+ name := category.PropertyName()
message := fmt.Sprintf("category %s", name)
filename := strings.ReplaceAll(name, "_", "-")
expected := []string{fmt.Sprintf("%s.txt", filename), fmt.Sprintf("bar-%s.txt", filename)}
android.AssertPathsRelativeToTopEquals(t, message, expected, info.FlagsFilesByCategory[category])
}
- android.AssertPathsRelativeToTopEquals(t, "annotation flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/annotation-flags.csv"}, info.AnnotationFlagsPaths)
- android.AssertPathsRelativeToTopEquals(t, "metadata flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/metadata.csv"}, info.MetadataPaths)
- android.AssertPathsRelativeToTopEquals(t, "index flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/index.csv"}, info.IndexPaths)
+ android.AssertPathsRelativeToTopEquals(t, "annotation flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/annotation-flags.csv"}, info.AnnotationFlagsPaths)
+ android.AssertPathsRelativeToTopEquals(t, "metadata flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/metadata.csv"}, info.MetadataPaths)
+ android.AssertPathsRelativeToTopEquals(t, "index flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/index.csv"}, info.IndexPaths)
- android.AssertArrayString(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/filtered-stub-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop())
- android.AssertArrayString(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/filtered-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop())
+ android.AssertArrayString(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/filtered-stub-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop())
+ android.AssertArrayString(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/filtered-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop())
}
// TestPlatformBootclasspath_LegacyPrebuiltFragment verifies that the
@@ -234,7 +236,7 @@ func TestPlatformBootclasspath_LegacyPrebuiltFragment(t *testing.T) {
)
pbcp := result.Module("myplatform-bootclasspath", "android_common")
- info := result.ModuleProvider(pbcp, java.MonolithicHiddenAPIInfoProvider).(java.MonolithicHiddenAPIInfo)
+ info, _ := android.SingletonModuleProvider(result, pbcp, java.MonolithicHiddenAPIInfoProvider)
android.AssertArrayString(t, "stub flags", []string{"prebuilt-stub-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop())
android.AssertArrayString(t, "all flags", []string{"prebuilt-all-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop())
@@ -252,6 +254,11 @@ func TestPlatformBootclasspathDependencies(t *testing.T) {
java.FixtureWithLastReleaseApis("foo"),
java.PrepareForTestWithDexpreopt,
dexpreopt.FixtureDisableDexpreoptBootImages(false),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+ }
+ }),
).RunTestWithBp(t, `
apex {
name: "com.android.art",
@@ -382,11 +389,14 @@ func TestPlatformBootclasspathDependencies(t *testing.T) {
// Make sure that the myplatform-bootclasspath has the correct dependencies.
CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
+ // source vs prebuilt selection metadata module
+ `platform:all_apex_contributions`,
+
// The following are stubs.
- `platform:android_stubs_current`,
- `platform:android_system_stubs_current`,
- `platform:android_test_stubs_current`,
- `platform:legacy.core.platform.api.stubs`,
+ `platform:android_stubs_current_exportable`,
+ `platform:android_system_stubs_current_exportable`,
+ `platform:android_test_stubs_current_exportable`,
+ `platform:legacy.core.platform.api.stubs.exportable`,
// Needed for generating the boot image.
`platform:dex2oatd`,
@@ -419,6 +429,9 @@ func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) {
java.PrepareForTestWithJavaSdkLibraryFiles,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
+ variables.BuildFlags = map[string]string{
+ "RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+ }
}),
java.FixtureWithPrebuiltApis(map[string][]string{
"current": {},
@@ -534,13 +547,16 @@ func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) {
// Make sure that the myplatform-bootclasspath has the correct dependencies.
CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
+ // source vs prebuilt selection metadata module
+ `platform:all_apex_contributions`,
+
// The following are stubs.
"platform:prebuilt_sdk_public_current_android",
"platform:prebuilt_sdk_system_current_android",
"platform:prebuilt_sdk_test_current_android",
// Not a prebuilt as no prebuilt existed when it was added.
- "platform:legacy.core.platform.api.stubs",
+ "platform:legacy.core.platform.api.stubs.exportable",
// The platform_bootclasspath intentionally adds dependencies on both source and prebuilt
// modules when available as it does not know which one will be preferred.
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 7d339d54e..cebbae9a6 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -22,6 +22,7 @@ import (
"strings"
"android/soong/android"
+ "android/soong/dexpreopt"
"android/soong/java"
"android/soong/provenance"
@@ -50,6 +51,7 @@ type prebuilt interface {
type prebuiltCommon struct {
android.ModuleBase
+ java.Dexpreopter
prebuilt android.Prebuilt
// Properties common to both prebuilt_apex and apex_set.
@@ -85,6 +87,12 @@ type PrebuiltCommonProperties struct {
// device (/apex/<apex_name>). If unspecified, follows the name property.
Apex_name *string
+ // Name of the source APEX that gets shadowed by this prebuilt
+ // e.g. com.mycompany.android.myapex
+ // If unspecified, follows the naming convention that the source apex of
+ // the prebuilt is Name() without "prebuilt_" prefix
+ Source_apex_name *string
+
ForceDisable bool `blueprint:"mutated"`
// whether the extracted apex file is installable.
@@ -124,7 +132,11 @@ func (p *prebuiltCommon) initPrebuiltCommon(module android.Module, properties *P
}
func (p *prebuiltCommon) ApexVariationName() string {
- return proptools.StringDefault(p.prebuiltCommonProperties.Apex_name, p.ModuleBase.BaseModuleName())
+ return proptools.StringDefault(p.prebuiltCommonProperties.Apex_name, p.BaseModuleName())
+}
+
+func (p *prebuiltCommon) BaseModuleName() string {
+ return proptools.StringDefault(p.prebuiltCommonProperties.Source_apex_name, p.ModuleBase.BaseModuleName())
}
func (p *prebuiltCommon) Prebuilt() *android.Prebuilt {
@@ -170,50 +182,46 @@ func (p *prebuiltCommon) installable() bool {
return proptools.BoolDefault(p.prebuiltCommonProperties.Installable, true)
}
-// initApexFilesForAndroidMk initializes the prebuiltCommon.apexFilesForAndroidMk field from the
-// modules that this depends upon.
+// To satisfy java.DexpreopterInterface
+func (p *prebuiltCommon) IsInstallable() bool {
+ return p.installable()
+}
+
+// initApexFilesForAndroidMk initializes the prebuiltCommon.requiredModuleNames field with the install only deps of the prebuilt apex
func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) {
- // Walk the dependencies of this module looking for the java modules that it exports.
- ctx.WalkDeps(func(child, parent android.Module) bool {
- tag := ctx.OtherModuleDependencyTag(child)
+ // If this apex contains a system server jar, then the dexpreopt artifacts should be added as required
+ for _, install := range p.Dexpreopter.DexpreoptBuiltInstalledForApex() {
+ p.requiredModuleNames = append(p.requiredModuleNames, install.FullModuleName())
+ }
+}
- name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child))
- if java.IsBootclasspathFragmentContentDepTag(tag) ||
- java.IsSystemServerClasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag {
- // If the exported java module provides a dex jar path then add it to the list of apexFiles.
- path := child.(interface {
- DexJarBuildPath() java.OptionalDexJarPath
- }).DexJarBuildPath()
- if path.IsSet() {
- af := apexFile{
- module: child,
- moduleDir: ctx.OtherModuleDir(child),
- androidMkModuleName: name,
- builtFile: path.Path(),
- class: javaSharedLib,
- }
- if module, ok := child.(java.DexpreopterInterface); ok {
- for _, install := range module.DexpreoptBuiltInstalledForApex() {
- af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
- }
- }
- p.apexFilesForAndroidMk = append(p.apexFilesForAndroidMk, af)
- }
- } else if tag == exportedBootclasspathFragmentTag {
- _, ok := child.(*java.PrebuiltBootclasspathFragmentModule)
- if !ok {
- ctx.PropertyErrorf("exported_bootclasspath_fragments", "%q is not a prebuilt_bootclasspath_fragment module", name)
- return false
- }
- // Visit the children of the bootclasspath_fragment.
- return true
- } else if tag == exportedSystemserverclasspathFragmentTag {
- // Visit the children of the systemserver_fragment.
- return true
+// If this prebuilt has system server jar, create the rules to dexpreopt it and install it alongside the prebuilt apex
+func (p *prebuiltCommon) dexpreoptSystemServerJars(ctx android.ModuleContext) {
+ // If this apex does not export anything, return
+ if !p.hasExportedDeps() {
+ return
+ }
+ // If this prebuilt apex has not been selected, return
+ if p.IsHideFromMake() {
+ return
+ }
+ // Use apex_name to determine the api domain of this prebuilt apex
+ apexName := p.ApexVariationName()
+ di, err := android.FindDeapexerProviderForModule(ctx)
+ if err != nil {
+ ctx.ModuleErrorf(err.Error())
+ }
+ dc := dexpreopt.GetGlobalConfig(ctx)
+ systemServerJarList := dc.AllApexSystemServerJars(ctx)
+
+ for i := 0; i < systemServerJarList.Len(); i++ {
+ sscpApex := systemServerJarList.Apex(i)
+ sscpJar := systemServerJarList.Jar(i)
+ if apexName != sscpApex {
+ continue
}
-
- return false
- })
+ p.Dexpreopter.DexpreoptPrebuiltApexSystemServerJars(ctx, sscpJar, di)
+ }
}
func (p *prebuiltCommon) addRequiredModules(entries *android.AndroidMkEntries) {
@@ -232,6 +240,7 @@ func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries {
OutputFile: android.OptionalPathForPath(p.outputApex),
Include: "$(BUILD_PREBUILT)",
Host_required: p.hostRequired,
+ OverrideName: p.BaseModuleName(),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetString("LOCAL_MODULE_PATH", p.installDir.String())
@@ -248,6 +257,11 @@ func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries {
},
}
+ // Add the dexpreopt artifacts to androidmk
+ for _, install := range p.Dexpreopter.DexpreoptBuiltInstalledForApex() {
+ entriesList = append(entriesList, install.ToMakeEntries())
+ }
+
// Iterate over the apexFilesForAndroidMk list and create an AndroidMkEntries struct for each
// file. This provides similar behavior to that provided in apexBundle.AndroidMk() as it makes the
// apex specific variants of the exported java modules available for use from within make.
@@ -428,7 +442,7 @@ func (p *prebuiltCommon) apexInfoMutator(mctx android.TopDownMutatorContext) {
// Create contents for the prebuilt_apex and store it away for later use.
apexContents := android.NewApexContents(contents)
- mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
+ android.SetProvider(mctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{
Contents: apexContents,
})
@@ -437,7 +451,7 @@ func (p *prebuiltCommon) apexInfoMutator(mctx android.TopDownMutatorContext) {
apexInfo := android.ApexInfo{
ApexVariationName: apexVariationName,
InApexVariants: []string{apexVariationName},
- InApexModules: []string{p.ModuleBase.BaseModuleName()}, // BaseModuleName() to avoid the prebuilt_ prefix.
+ InApexModules: []string{p.BaseModuleName()}, // BaseModuleName() to avoid the prebuilt_ prefix.
ApexContents: []*android.ApexContents{apexContents},
ForPrebuiltApex: true,
}
@@ -484,6 +498,9 @@ type Prebuilt struct {
inputApex android.Path
provenanceMetaDataFile android.OutputPath
+
+ // Single aconfig "cache file" merged from this module and all dependencies.
+ mergedAconfigFiles map[string]android.Paths
}
type ApexFileProperties struct {
@@ -612,6 +629,7 @@ func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.TopDownMutator
// Compute the deapexer properties from the transitive dependencies of this module.
commonModules := []string{}
+ dexpreoptProfileGuidedModules := []string{}
exportedFiles := []string{}
ctx.WalkDeps(func(child, parent android.Module) bool {
tag := ctx.OtherModuleDependencyTag(child)
@@ -621,13 +639,18 @@ func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.TopDownMutator
return false
}
- name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child))
+ name := java.ModuleStemForDeapexing(child)
if _, ok := tag.(android.RequiresFilesFromPrebuiltApexTag); ok {
commonModules = append(commonModules, name)
- requiredFiles := child.(android.RequiredFilesFromPrebuiltApex).RequiredFilesFromPrebuiltApex(ctx)
+ extract := child.(android.RequiredFilesFromPrebuiltApex)
+ requiredFiles := extract.RequiredFilesFromPrebuiltApex(ctx)
exportedFiles = append(exportedFiles, requiredFiles...)
+ if extract.UseProfileGuidedDexpreopt() {
+ dexpreoptProfileGuidedModules = append(dexpreoptProfileGuidedModules, name)
+ }
+
// Visit the dependencies of this module just in case they also require files from the
// prebuilt apex.
return true
@@ -640,7 +663,8 @@ func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.TopDownMutator
deapexerProperties := &DeapexerProperties{
// Remove any duplicates from the common modules lists as a module may be included via a direct
// dependency as well as transitive ones.
- CommonModules: android.SortedUniqueStrings(commonModules),
+ CommonModules: android.SortedUniqueStrings(commonModules),
+ DexpreoptProfileGuidedModules: android.SortedUniqueStrings(dexpreoptProfileGuidedModules),
}
// Populate the exported files property in a fixed order.
@@ -740,13 +764,11 @@ var _ prebuiltApexModuleCreator = (*Prebuilt)(nil)
// V V V
// selector <--- deapexer <--- exported java lib
func (p *Prebuilt) createPrebuiltApexModules(ctx android.TopDownMutatorContext) {
- baseModuleName := p.BaseModuleName()
-
- apexSelectorModuleName := apexSelectorModuleName(baseModuleName)
+ apexSelectorModuleName := apexSelectorModuleName(p.Name())
createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties)
apexFileSource := ":" + apexSelectorModuleName
- p.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource)
+ p.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(p.Name()), apexFileSource)
// Add a source reference to retrieve the selected apex from the selector module.
p.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource)
@@ -756,12 +778,47 @@ func (p *Prebuilt) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
p.prebuiltApexContentsDeps(ctx)
}
+func (p *prebuiltCommon) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if p.hasExportedDeps() {
+ // Create a dependency from the prebuilt apex (prebuilt_apex/apex_set) to the internal deapexer module
+ // The deapexer will return a provider that will be bubbled up to the rdeps of apexes (e.g. dex_bootjars)
+ ctx.AddDependency(ctx.Module(), android.DeapexerTag, deapexerModuleName(p.Name()))
+ }
+}
+
var _ ApexInfoMutator = (*Prebuilt)(nil)
func (p *Prebuilt) ApexInfoMutator(mctx android.TopDownMutatorContext) {
p.apexInfoMutator(mctx)
}
+// Set a provider containing information about the jars and .prof provided by the apex
+// Apexes built from prebuilts retrieve this information by visiting its internal deapexer module
+// Used by dex_bootjars to generate the boot image
+func (p *prebuiltCommon) provideApexExportsInfo(ctx android.ModuleContext) {
+ if !p.hasExportedDeps() {
+ // nothing to do
+ return
+ }
+ if di, err := android.FindDeapexerProviderForModule(ctx); err == nil {
+ javaModuleToDexPath := map[string]android.Path{}
+ for _, commonModule := range di.GetExportedModuleNames() {
+ if dex := di.PrebuiltExportPath(java.ApexRootRelativePathToJavaLib(commonModule)); dex != nil {
+ javaModuleToDexPath[commonModule] = dex
+ }
+ }
+
+ exports := android.ApexExportsInfo{
+ ApexName: p.ApexVariationName(),
+ ProfilePathOnHost: di.PrebuiltExportPath(java.ProfileInstallPathInApex),
+ LibraryNameToDexJarPathOnHost: javaModuleToDexPath,
+ }
+ android.SetProvider(ctx, android.ApexExportsInfoProvider, exports)
+ } else {
+ ctx.ModuleErrorf(err.Error())
+ }
+}
+
func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
p.apexKeysPath = writeApexKeys(ctx, p)
// TODO(jungjw): Check the key validity.
@@ -783,6 +840,12 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
return
}
+ // dexpreopt any system server jars if present
+ p.dexpreoptSystemServerJars(ctx)
+
+ // provide info used for generating the boot image
+ p.provideApexExportsInfo(ctx)
+
// Save the files that need to be made available to Make.
p.initApexFilesForAndroidMk(ctx)
@@ -797,6 +860,8 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
p.installedFile = ctx.InstallFile(p.installDir, p.installFilename, p.inputApex, p.compatSymlinks...)
p.provenanceMetaDataFile = provenance.GenerateArtifactProvenanceMetaData(ctx, p.inputApex, p.installedFile)
}
+
+ android.CollectDependencyAconfigFiles(ctx, &p.mergedAconfigFiles)
}
func (p *Prebuilt) ProvenanceMetaDataFile() android.OutputPath {
@@ -957,13 +1022,11 @@ var _ prebuiltApexModuleCreator = (*ApexSet)(nil)
// from those provided this creates an extractor module which extracts the appropriate .apex file
// from the zip file containing them.
func (a *ApexSet) createPrebuiltApexModules(ctx android.TopDownMutatorContext) {
- baseModuleName := a.BaseModuleName()
-
- apexExtractorModuleName := apexExtractorModuleName(baseModuleName)
+ apexExtractorModuleName := apexExtractorModuleName(a.Name())
createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties)
apexFileSource := ":" + apexExtractorModuleName
- a.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource)
+ a.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(a.Name()), apexFileSource)
// After passing the arch specific src properties to the creating the apex selector module
a.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource)
@@ -999,6 +1062,12 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
return
}
+ // dexpreopt any system server jars if present
+ a.dexpreoptSystemServerJars(ctx)
+
+ // provide info used for generating the boot image
+ a.provideApexExportsInfo(ctx)
+
// Save the files that need to be made available to Make.
a.initApexFilesForAndroidMk(ctx)
diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go
index 40d05814e..f6c53b270 100644
--- a/apex/systemserver_classpath_fragment_test.go
+++ b/apex/systemserver_classpath_fragment_test.go
@@ -106,6 +106,7 @@ func TestSystemserverclasspathFragmentContents(t *testing.T) {
})
java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex", []string{
+ `dex2oatd`,
`myapex.key`,
`mysystemserverclasspathfragment`,
})
@@ -162,6 +163,7 @@ func TestSystemserverclasspathFragmentNoGeneratedProto(t *testing.T) {
})
java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{
+ `dex2oatd`,
`myapex.key`,
`mysystemserverclasspathfragment`,
})
@@ -272,24 +274,26 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
ctx := result.TestContext
java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex", []string{
- `myapex.apex.selector`,
+ `dex2oatd`,
+ `prebuilt_myapex.apex.selector`,
+ `prebuilt_myapex.deapexer`,
`prebuilt_mysystemserverclasspathfragment`,
})
java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_myapex", []string{
- `myapex.deapexer`,
`prebuilt_bar`,
`prebuilt_foo`,
+ `prebuilt_myapex.deapexer`,
})
- ensureExactDeapexedContents(t, ctx, "myapex", "android_common", []string{
+ ensureExactDeapexedContents(t, ctx, "prebuilt_myapex", "android_common", []string{
"javalib/foo.jar",
"javalib/bar.jar",
"javalib/bar.jar.prof",
})
- assertProfileGuided(t, ctx, "foo", "android_common_myapex", false)
- assertProfileGuided(t, ctx, "bar", "android_common_myapex", true)
+ assertProfileGuidedPrebuilt(t, ctx, "myapex", "foo", false)
+ assertProfileGuidedPrebuilt(t, ctx, "myapex", "bar", true)
}
func TestSystemserverclasspathFragmentStandaloneContents(t *testing.T) {
@@ -428,19 +432,19 @@ func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) {
ctx := result.TestContext
java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_myapex", []string{
- `myapex.deapexer`,
`prebuilt_bar`,
`prebuilt_foo`,
+ `prebuilt_myapex.deapexer`,
})
- ensureExactDeapexedContents(t, ctx, "myapex", "android_common", []string{
+ ensureExactDeapexedContents(t, ctx, "prebuilt_myapex", "android_common", []string{
"javalib/foo.jar",
"javalib/bar.jar",
"javalib/bar.jar.prof",
})
- assertProfileGuided(t, ctx, "foo", "android_common_myapex", false)
- assertProfileGuided(t, ctx, "bar", "android_common_myapex", true)
+ assertProfileGuidedPrebuilt(t, ctx, "myapex", "foo", false)
+ assertProfileGuidedPrebuilt(t, ctx, "myapex", "bar", true)
}
func assertProfileGuided(t *testing.T, ctx *android.TestContext, moduleName string, variant string, expected bool) {
@@ -450,3 +454,11 @@ func assertProfileGuided(t *testing.T, ctx *android.TestContext, moduleName stri
t.Fatalf("Expected profile-guided to be %v, got %v", expected, actual)
}
}
+
+func assertProfileGuidedPrebuilt(t *testing.T, ctx *android.TestContext, apexName string, moduleName string, expected bool) {
+ dexpreopt := ctx.ModuleForTests(apexName, "android_common_"+apexName).Rule("dexpreopt." + moduleName)
+ actual := strings.Contains(dexpreopt.RuleParams.Command, "--profile-file=")
+ if expected != actual {
+ t.Fatalf("Expected profile-guided to be %v, got %v", expected, actual)
+ }
+}
diff --git a/apex/vndk.go b/apex/vndk.go
index 26c60edc8..377c1c014 100644
--- a/apex/vndk.go
+++ b/apex/vndk.go
@@ -65,24 +65,27 @@ func apexVndkMutator(mctx android.TopDownMutatorContext) {
}
vndkVersion := ab.vndkVersion(mctx.DeviceConfig())
- apiLevel, err := android.ApiLevelFromUser(mctx, vndkVersion)
- if err != nil {
- mctx.PropertyErrorf("vndk_version", "%s", err.Error())
- return
- }
-
- targets := mctx.MultiTargets()
- if len(targets) > 0 && apiLevel.LessThan(cc.MinApiForArch(mctx, targets[0].Arch.ArchType)) &&
- vndkVersion != mctx.DeviceConfig().PlatformVndkVersion() {
- // Disable VNDK APEXes for VNDK versions less than the minimum supported API
- // level for the primary architecture. This validation is skipped if the VNDK
- // version matches the platform VNDK version, which can occur when the device
- // config targets the 'current' VNDK (see `vndkVersion`).
- ab.Disable()
- }
- if proptools.String(ab.vndkProperties.Vndk_version) != "" &&
- apiLevel.GreaterThanOrEqualTo(android.ApiLevelOrPanic(mctx, mctx.DeviceConfig().PlatformVndkVersion())) {
- ab.Disable()
+ if vndkVersion != "" {
+ apiLevel, err := android.ApiLevelFromUser(mctx, vndkVersion)
+ if err != nil {
+ mctx.PropertyErrorf("vndk_version", "%s", err.Error())
+ return
+ }
+
+ targets := mctx.MultiTargets()
+ if len(targets) > 0 && apiLevel.LessThan(cc.MinApiForArch(mctx, targets[0].Arch.ArchType)) &&
+ vndkVersion != mctx.DeviceConfig().PlatformVndkVersion() {
+ // Disable VNDK APEXes for VNDK versions less than the minimum supported API
+ // level for the primary architecture. This validation is skipped if the VNDK
+ // version matches the platform VNDK version, which can occur when the device
+ // config targets the 'current' VNDK (see `vndkVersion`).
+ ab.Disable()
+ }
+ if proptools.String(ab.vndkProperties.Vndk_version) != "" &&
+ mctx.DeviceConfig().PlatformVndkVersion() != "" &&
+ apiLevel.GreaterThanOrEqualTo(android.ApiLevelOrPanic(mctx, mctx.DeviceConfig().PlatformVndkVersion())) {
+ ab.Disable()
+ }
}
}
}
@@ -94,6 +97,11 @@ func apexVndkDepsMutator(mctx android.BottomUpMutatorContext) {
if vndkVersion == "" {
vndkVersion = mctx.DeviceConfig().PlatformVndkVersion()
}
+
+ if vndkVersion == "" {
+ return
+ }
+
if vndkVersion == mctx.DeviceConfig().PlatformVndkVersion() {
vndkVersion = "current"
} else {
diff --git a/apex/vndk_test.go b/apex/vndk_test.go
index e2aee96e7..894aece9d 100644
--- a/apex/vndk_test.go
+++ b/apex/vndk_test.go
@@ -8,66 +8,6 @@ import (
"android/soong/android"
)
-func TestVndkApexForVndkLite(t *testing.T) {
- ctx := testApex(t, `
- apex_vndk {
- name: "com.android.vndk.current",
- key: "com.android.vndk.current.key",
- updatable: false,
- }
-
- apex_key {
- name: "com.android.vndk.current.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "libvndk",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
-
- cc_library {
- name: "libvndksp",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
- `+vndkLibrariesTxtFiles("current"),
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.DeviceVndkVersion = proptools.StringPtr("")
- variables.KeepVndk = proptools.BoolPtr(true)
- }),
- )
- // VNDK-Lite contains only core variants of VNDK-Sp libraries
- ensureExactContents(t, ctx, "com.android.vndk.current", "android_common", []string{
- "lib/libvndksp.so",
- "lib/libc++.so",
- "lib64/libvndksp.so",
- "lib64/libc++.so",
- "etc/llndk.libraries.29.txt",
- "etc/vndkcore.libraries.29.txt",
- "etc/vndksp.libraries.29.txt",
- "etc/vndkprivate.libraries.29.txt",
- "etc/vndkproduct.libraries.29.txt",
- })
-}
-
func TestVndkApexUsesVendorVariant(t *testing.T) {
bp := `
apex_vndk {