summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/Android.bp3
-rw-r--r--java/aapt2.go12
-rw-r--r--java/aar.go25
-rw-r--r--java/android_manifest.go45
-rw-r--r--java/androidmk.go15
-rw-r--r--java/androidmk_test.go149
-rwxr-xr-xjava/app.go93
-rw-r--r--java/app_builder.go11
-rw-r--r--java/app_import.go6
-rw-r--r--java/app_import_test.go20
-rw-r--r--java/app_set.go9
-rw-r--r--java/app_test.go173
-rw-r--r--java/base.go81
-rw-r--r--java/bootclasspath_fragment.go159
-rw-r--r--java/bootclasspath_fragment_test.go41
-rw-r--r--java/config/config.go12
-rw-r--r--java/dex.go12
-rw-r--r--java/dex_test.go26
-rw-r--r--java/dexpreopt_bootjars.go80
-rw-r--r--java/dexpreopt_config_test.go35
-rw-r--r--java/dexpreopt_config_testing.go768
-rw-r--r--java/droiddoc.go7
-rw-r--r--java/droidstubs.go32
-rw-r--r--java/droidstubs_test.go47
-rw-r--r--java/fuzz.go129
-rw-r--r--java/hiddenapi_modular.go109
-rw-r--r--java/jacoco.go28
-rw-r--r--java/java.go14
-rw-r--r--java/java_test.go4
-rw-r--r--java/lint.go19
-rw-r--r--java/lint_defaults.txt2
-rw-r--r--java/lint_test.go2
-rw-r--r--java/platform_bootclasspath.go4
-rw-r--r--java/prebuilt_apis.go9
-rw-r--r--java/prebuilt_apis_test.go29
-rw-r--r--java/resourceshrinker.go43
-rw-r--r--java/robolectric.go14
-rw-r--r--java/rro.go12
-rw-r--r--java/rro_test.go4
-rw-r--r--java/sdk_library.go86
-rw-r--r--java/sdk_library_test.go145
-rw-r--r--java/testing.go43
42 files changed, 2169 insertions, 388 deletions
diff --git a/java/Android.bp b/java/Android.bp
index 9df4ab4de..0bf7a0b26 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -43,6 +43,7 @@ bootstrap_go_package {
"dexpreopt_bootjars.go",
"dexpreopt_check.go",
"dexpreopt_config.go",
+ "dexpreopt_config_testing.go",
"droiddoc.go",
"droidstubs.go",
"fuzz.go",
@@ -64,6 +65,7 @@ bootstrap_go_package {
"plugin.go",
"prebuilt_apis.go",
"proto.go",
+ "resourceshrinker.go",
"robolectric.go",
"rro.go",
"sdk.go",
@@ -86,6 +88,7 @@ bootstrap_go_package {
"dex_test.go",
"dexpreopt_test.go",
"dexpreopt_bootjars_test.go",
+ "dexpreopt_config_test.go",
"droiddoc_test.go",
"droidstubs_test.go",
"genrule_test.go",
diff --git a/java/aapt2.go b/java/aapt2.go
index 5346ddf89..7845a0b23 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -256,17 +256,21 @@ func aapt2Link(ctx android.ModuleContext,
var aapt2ConvertRule = pctx.AndroidStaticRule("aapt2Convert",
blueprint.RuleParams{
- Command: `${config.Aapt2Cmd} convert --output-format proto $in -o $out`,
+ Command: `${config.Aapt2Cmd} convert --output-format $format $in -o $out`,
CommandDeps: []string{"${config.Aapt2Cmd}"},
- })
+ }, "format",
+)
// Converts xml files and resource tables (resources.arsc) in the given jar/apk file to a proto
// format. The proto definition is available at frameworks/base/tools/aapt2/Resources.proto.
-func aapt2Convert(ctx android.ModuleContext, out android.WritablePath, in android.Path) {
+func aapt2Convert(ctx android.ModuleContext, out android.WritablePath, in android.Path, format string) {
ctx.Build(pctx, android.BuildParams{
Rule: aapt2ConvertRule,
Input: in,
Output: out,
- Description: "convert to proto",
+ Description: "convert to " + format,
+ Args: map[string]string{
+ "format": format,
+ },
})
}
diff --git a/java/aar.go b/java/aar.go
index d5996ba02..6261f2974 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -270,7 +270,7 @@ var extractAssetsRule = pctx.AndroidStaticRule("extractAssets",
func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkContext,
classLoaderContexts dexpreopt.ClassLoaderContextMap, excludedLibs []string,
- extraLinkFlags ...string) {
+ enforceDefaultTargetSdkVersion bool, extraLinkFlags ...string) {
transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags :=
aaptLibs(ctx, sdkContext, classLoaderContexts)
@@ -283,15 +283,16 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
manifestPath := ManifestFixer(ctx, manifestSrcPath, ManifestFixerParams{
- SdkContext: sdkContext,
- ClassLoaderContexts: classLoaderContexts,
- IsLibrary: a.isLibrary,
- DefaultManifestVersion: a.defaultManifestVersion,
- UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs,
- UsesNonSdkApis: a.usesNonSdkApis,
- UseEmbeddedDex: a.useEmbeddedDex,
- HasNoCode: a.hasNoCode,
- LoggingParent: a.LoggingParent,
+ SdkContext: sdkContext,
+ ClassLoaderContexts: classLoaderContexts,
+ IsLibrary: a.isLibrary,
+ DefaultManifestVersion: a.defaultManifestVersion,
+ UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs,
+ UsesNonSdkApis: a.usesNonSdkApis,
+ UseEmbeddedDex: a.useEmbeddedDex,
+ HasNoCode: a.hasNoCode,
+ LoggingParent: a.LoggingParent,
+ EnforceDefaultTargetSdkVersion: enforceDefaultTargetSdkVersion,
})
// Add additional manifest files to transitive manifests.
@@ -439,7 +440,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoa
switch depTag {
case instrumentationForTag:
// Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
- case libTag:
+ case sdkLibTag, libTag:
if exportPackage != nil {
sharedLibs = append(sharedLibs, exportPackage)
}
@@ -535,7 +536,7 @@ func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.aapt.isLibrary = true
a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
- a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, nil)
+ a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, nil, false)
a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 522b6647a..c7853103f 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -43,13 +43,12 @@ var manifestMergerRule = pctx.AndroidStaticRule("manifestMerger",
// targetSdkVersion for manifest_fixer
// When TARGET_BUILD_APPS is not empty, this method returns 10000 for modules targeting an unreleased SDK
// This enables release builds (that run with TARGET_BUILD_APPS=[val...]) to target APIs that have not yet been finalized as part of an SDK
-func targetSdkVersionForManifestFixer(ctx android.ModuleContext, sdkContext android.SdkContext) string {
- targetSdkVersionSpec := sdkContext.TargetSdkVersion(ctx)
- // Return 10000 for modules targeting "current" if either
- // 1. The module is built in unbundled mode (TARGET_BUILD_APPS not empty)
- // 2. The module is run as part of MTS, and should be testable on stable branches
+func targetSdkVersionForManifestFixer(ctx android.ModuleContext, params ManifestFixerParams) string {
+ targetSdkVersionSpec := params.SdkContext.TargetSdkVersion(ctx)
+
+ // Check if we want to return 10000
// TODO(b/240294501): Determine the rules for handling test apexes
- if targetSdkVersionSpec.ApiLevel.IsPreview() && (ctx.Config().UnbundledBuildApps() || includedInMts(ctx.Module())) {
+ if shouldReturnFinalOrFutureInt(ctx, targetSdkVersionSpec, params.EnforceDefaultTargetSdkVersion) {
return strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt())
}
targetSdkVersion, err := targetSdkVersionSpec.EffectiveVersionString(ctx)
@@ -59,6 +58,17 @@ func targetSdkVersionForManifestFixer(ctx android.ModuleContext, sdkContext andr
return targetSdkVersion
}
+// Return true for modules targeting "current" if either
+// 1. The module is built in unbundled mode (TARGET_BUILD_APPS not empty)
+// 2. The module is run as part of MTS, and should be testable on stable branches
+// Do not return 10000 if we are enforcing default targetSdkVersion and sdk has been finalised
+func shouldReturnFinalOrFutureInt(ctx android.ModuleContext, targetSdkVersionSpec android.SdkSpec, enforceDefaultTargetSdkVersion bool) bool {
+ if enforceDefaultTargetSdkVersion && ctx.Config().PlatformSdkFinal() {
+ return false
+ }
+ return targetSdkVersionSpec.ApiLevel.IsPreview() && (ctx.Config().UnbundledBuildApps() || includedInMts(ctx.Module()))
+}
+
// Helper function that casts android.Module to java.androidTestApp
// If this type conversion is possible, it queries whether the test app is included in an MTS suite
func includedInMts(module android.Module) bool {
@@ -69,16 +79,17 @@ func includedInMts(module android.Module) bool {
}
type ManifestFixerParams struct {
- SdkContext android.SdkContext
- ClassLoaderContexts dexpreopt.ClassLoaderContextMap
- IsLibrary bool
- DefaultManifestVersion string
- UseEmbeddedNativeLibs bool
- UsesNonSdkApis bool
- UseEmbeddedDex bool
- HasNoCode bool
- TestOnly bool
- LoggingParent string
+ SdkContext android.SdkContext
+ ClassLoaderContexts dexpreopt.ClassLoaderContextMap
+ IsLibrary bool
+ DefaultManifestVersion string
+ UseEmbeddedNativeLibs bool
+ UsesNonSdkApis bool
+ UseEmbeddedDex bool
+ HasNoCode bool
+ TestOnly bool
+ LoggingParent string
+ EnforceDefaultTargetSdkVersion bool
}
// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
@@ -137,7 +148,7 @@ func ManifestFixer(ctx android.ModuleContext, manifest android.Path,
var argsMapper = make(map[string]string)
if params.SdkContext != nil {
- targetSdkVersion := targetSdkVersionForManifestFixer(ctx, params.SdkContext)
+ targetSdkVersion := targetSdkVersionForManifestFixer(ctx, params)
args = append(args, "--targetSdkVersion ", targetSdkVersion)
if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
diff --git a/java/androidmk.go b/java/androidmk.go
index 75ac0e72d..42b4ef1b2 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -17,6 +17,7 @@ package java
import (
"fmt"
"io"
+ "strings"
"android/soong/android"
)
@@ -138,6 +139,7 @@ func (j *JavaFuzzLibrary) AndroidMkEntries() []android.AndroidMkEntries {
entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", "null-suite")
androidMkWriteTestData(j.jniFilePaths, entries)
+ androidMkWriteTestData(android.Paths{j.implementationJarFile}, entries)
})
return entriesList
}
@@ -398,6 +400,19 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
} else {
for _, jniLib := range app.jniLibs {
entries.AddStrings("LOCAL_SOONG_JNI_LIBS_"+jniLib.target.Arch.ArchType.String(), jniLib.name)
+ var partitionTag string
+
+ // Mimic the creation of partition_tag in build/make,
+ // which defaults to an empty string when the partition is system.
+ // Otherwise, capitalize with a leading _
+ if jniLib.partition == "system" {
+ partitionTag = ""
+ } else {
+ split := strings.Split(jniLib.partition, "/")
+ partitionTag = "_" + strings.ToUpper(split[len(split)-1])
+ }
+ entries.AddStrings("LOCAL_SOONG_JNI_LIBS_PARTITION_"+jniLib.target.Arch.ArchType.String(),
+ jniLib.name+":"+partitionTag)
}
}
diff --git a/java/androidmk_test.go b/java/androidmk_test.go
index 197da4f38..1232cd1ee 100644
--- a/java/androidmk_test.go
+++ b/java/androidmk_test.go
@@ -19,6 +19,9 @@ import (
"testing"
"android/soong/android"
+ "android/soong/cc"
+
+ "github.com/google/blueprint/proptools"
)
func TestRequired(t *testing.T) {
@@ -252,3 +255,149 @@ func TestGetOverriddenPackages(t *testing.T) {
android.AssertDeepEquals(t, "overrides property", expected.overrides, actual)
}
}
+
+func TestJniPartition(t *testing.T) {
+ bp := `
+ cc_library {
+ name: "libjni_system",
+ system_shared_libs: [],
+ sdk_version: "current",
+ stl: "none",
+ }
+
+ cc_library {
+ name: "libjni_system_ext",
+ system_shared_libs: [],
+ sdk_version: "current",
+ stl: "none",
+ system_ext_specific: true,
+ }
+
+ cc_library {
+ name: "libjni_odm",
+ system_shared_libs: [],
+ sdk_version: "current",
+ stl: "none",
+ device_specific: true,
+ }
+
+ cc_library {
+ name: "libjni_product",
+ system_shared_libs: [],
+ sdk_version: "current",
+ stl: "none",
+ product_specific: true,
+ }
+
+ cc_library {
+ name: "libjni_vendor",
+ system_shared_libs: [],
+ sdk_version: "current",
+ stl: "none",
+ soc_specific: true,
+ }
+
+ android_app {
+ name: "test_app_system_jni_system",
+ privileged: true,
+ platform_apis: true,
+ certificate: "platform",
+ jni_libs: ["libjni_system"],
+ }
+
+ android_app {
+ name: "test_app_system_jni_system_ext",
+ privileged: true,
+ platform_apis: true,
+ certificate: "platform",
+ jni_libs: ["libjni_system_ext"],
+ }
+
+ android_app {
+ name: "test_app_system_ext_jni_system",
+ privileged: true,
+ platform_apis: true,
+ certificate: "platform",
+ jni_libs: ["libjni_system"],
+ system_ext_specific: true
+ }
+
+ android_app {
+ name: "test_app_system_ext_jni_system_ext",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni_system_ext"],
+ system_ext_specific: true
+ }
+
+ android_app {
+ name: "test_app_product_jni_product",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni_product"],
+ product_specific: true
+ }
+
+ android_app {
+ name: "test_app_vendor_jni_odm",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni_odm"],
+ soc_specific: true
+ }
+
+ android_app {
+ name: "test_app_odm_jni_vendor",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni_vendor"],
+ device_specific: true
+ }
+ android_app {
+ name: "test_app_system_jni_multiple",
+ privileged: true,
+ platform_apis: true,
+ certificate: "platform",
+ jni_libs: ["libjni_system", "libjni_system_ext"],
+ }
+ android_app {
+ name: "test_app_vendor_jni_multiple",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni_odm", "libjni_vendor"],
+ soc_specific: true
+ }
+ `
+ arch := "arm64"
+ ctx := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ cc.PrepareForTestWithCcDefaultModules,
+ android.PrepareForTestWithAndroidMk,
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.TestProductVariables.DeviceArch = proptools.StringPtr(arch)
+ }),
+ ).
+ RunTestWithBp(t, bp)
+ testCases := []struct {
+ name string
+ partitionNames []string
+ partitionTags []string
+ }{
+ {"test_app_system_jni_system", []string{"libjni_system"}, []string{""}},
+ {"test_app_system_jni_system_ext", []string{"libjni_system_ext"}, []string{"_SYSTEM_EXT"}},
+ {"test_app_system_ext_jni_system", []string{"libjni_system"}, []string{""}},
+ {"test_app_system_ext_jni_system_ext", []string{"libjni_system_ext"}, []string{"_SYSTEM_EXT"}},
+ {"test_app_product_jni_product", []string{"libjni_product"}, []string{"_PRODUCT"}},
+ {"test_app_vendor_jni_odm", []string{"libjni_odm"}, []string{"_ODM"}},
+ {"test_app_odm_jni_vendor", []string{"libjni_vendor"}, []string{"_VENDOR"}},
+ {"test_app_system_jni_multiple", []string{"libjni_system", "libjni_system_ext"}, []string{"", "_SYSTEM_EXT"}},
+ {"test_app_vendor_jni_multiple", []string{"libjni_odm", "libjni_vendor"}, []string{"_ODM", "_VENDOR"}},
+ }
+
+ for _, test := range testCases {
+ t.Run(test.name, func(t *testing.T) {
+ mod := ctx.ModuleForTests(test.name, "android_common").Module()
+ entry := android.AndroidMkEntriesForTest(t, ctx.TestContext, mod)[0]
+ for i := range test.partitionNames {
+ actual := entry.EntryMap["LOCAL_SOONG_JNI_LIBS_PARTITION_"+arch][i]
+ expected := test.partitionNames[i] + ":" + test.partitionTags[i]
+ android.AssertStringEquals(t, "Expected and actual differ", expected, actual)
+ }
+ })
+ }
+}
diff --git a/java/app.go b/java/app.go
index bccd37fa0..2a51e10df 100755
--- a/java/app.go
+++ b/java/app.go
@@ -101,6 +101,15 @@ type appProperties struct {
PreventInstall bool `blueprint:"mutated"`
IsCoverageVariant bool `blueprint:"mutated"`
+ // It can be set to test the behaviour of default target sdk version.
+ // Only required when updatable: false. It is an error if updatable: true and this is false.
+ Enforce_default_target_sdk_version *bool
+
+ // If set, the targetSdkVersion for the target is set to the latest default API level.
+ // This would be by default false, unless updatable: true or
+ // enforce_default_target_sdk_version: true in which case this defaults to true.
+ EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
+
// Whether this app is considered mainline updatable or not. When set to true, this will enforce
// additional rules to make sure an app can safely be updated. Default is false.
// Prefer using other specific properties if build behaviour must be changed; avoid using this
@@ -296,6 +305,18 @@ func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
} else {
ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
}
+
+ if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
+ ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
+ }
+ // TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
+ if a.deviceProperties.Target_sdk_version == nil {
+ a.SetEnforceDefaultTargetSdkVersion(true)
+ }
+ }
+
+ if Bool(a.appProperties.Enforce_default_target_sdk_version) {
+ a.SetEnforceDefaultTargetSdkVersion(true)
}
a.checkPlatformAPI(ctx)
@@ -427,7 +448,7 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion
}
a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts,
- a.usesLibraryProperties.Exclude_uses_libs, aaptLinkFlags...)
+ a.usesLibraryProperties.Exclude_uses_libs, a.enforceDefaultTargetSdkVersion(), aaptLinkFlags...)
// apps manifests are handled by aapt, don't let Module see them
a.properties.Manifest = nil
@@ -526,7 +547,8 @@ func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderI
// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
-func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate, ctx android.ModuleContext) []Certificate {
+func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
+ ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
if android.SrcIsModule(certPropValue) == "" {
var mainCert Certificate
if certPropValue != "" {
@@ -558,7 +580,22 @@ func processMainCert(m android.ModuleBase, certPropValue string, certificates []
}
}
- return certificates
+ if len(certificates) > 0 {
+ mainCertificate = certificates[0]
+ } else {
+ // This can be reached with an empty certificate list if AllowMissingDependencies is set
+ // and the certificate property for this module is a module reference to a missing module.
+ if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
+ panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
+ }
+ // Set a certificate to avoid panics later when accessing it.
+ mainCertificate = Certificate{
+ Key: android.PathForModuleOut(ctx, "missing.pk8"),
+ Pem: android.PathForModuleOut(ctx, "missing.pem"),
+ }
+ }
+
+ return mainCertificate, certificates
}
func (a *AndroidApp) InstallApkName() string {
@@ -632,29 +669,14 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
dexJarFile := a.dexBuildActions(ctx)
- jniLibs, prebuiltJniPackages, certificateDeps := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
+ jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
if ctx.Failed() {
return
}
- certificates := processMainCert(a.ModuleBase, a.getCertString(ctx), certificateDeps, ctx)
-
- // This can be reached with an empty certificate list if AllowMissingDependencies is set
- // and the certificate property for this module is a module reference to a missing module.
- if len(certificates) > 0 {
- a.certificate = certificates[0]
- } else {
- if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
- panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
- }
- // Set a certificate to avoid panics later when accessing it.
- a.certificate = Certificate{
- Key: android.PathForModuleOut(ctx, "missing.pk8"),
- Pem: android.PathForModuleOut(ctx, "missing.pem"),
- }
- }
+ a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
// Build a final signed app package.
packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
@@ -667,10 +689,9 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
lineageFile = android.PathForModuleSrc(ctx, lineage)
}
-
rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
- CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
+ CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion, Bool(a.dexProperties.Optimize.Shrink_resources))
a.outputFile = packageFile
if v4SigningRequested {
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
@@ -699,7 +720,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
if v4SigningRequested {
v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
}
- CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
+ CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion, false)
a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
if v4SigningRequested {
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
@@ -777,6 +798,7 @@ func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
target: module.Target(),
coverageFile: dep.CoverageOutputFile(),
unstrippedFile: dep.UnstrippedOutputFile(),
+ partition: dep.Partition(),
})
} else {
ctx.ModuleErrorf("dependency %q missing output file", otherName)
@@ -865,6 +887,14 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
}
+func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
+ return a.appProperties.EnforceDefaultTargetSdkVersion
+}
+
+func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
+ a.appProperties.EnforceDefaultTargetSdkVersion = val
+}
+
func (a *AndroidApp) Updatable() bool {
return Bool(a.appProperties.Updatable)
}
@@ -1456,8 +1486,8 @@ type bazelAndroidAppAttributes struct {
*bazelAapt
Deps bazel.LabelListAttribute
Custom_package *string
- Certificate *bazel.Label
- Certificate_name *string
+ Certificate bazel.LabelAttribute
+ Certificate_name bazel.StringAttribute
}
// ConvertWithBp2build is used to convert android_app to Bazel.
@@ -1469,15 +1499,8 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
aapt := a.convertAaptAttrsWithBp2Build(ctx)
- var certificate *bazel.Label
- certificateNamePtr := a.overridableAppProperties.Certificate
- certificateName := proptools.StringDefault(certificateNamePtr, "")
- certModule := android.SrcIsModule(certificateName)
- if certModule != "" {
- c := android.BazelLabelForModuleDepSingle(ctx, certificateName)
- certificate = &c
- certificateNamePtr = nil
- }
+ certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableAppProperties.Certificate)
+
attrs := &bazelAndroidAppAttributes{
commonAttrs,
aapt,
@@ -1485,7 +1508,7 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
// TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES
a.overridableAppProperties.Package_name,
certificate,
- certificateNamePtr,
+ certificateName,
}
props := bazel.BazelTargetModuleProperties{
diff --git a/java/app_builder.go b/java/app_builder.go
index 18a975181..d20a6bfe4 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -52,7 +52,7 @@ var combineApk = pctx.AndroidStaticRule("combineApk",
})
func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
- packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, v4SignatureFile android.WritablePath, lineageFile android.Path, rotationMinSdkVersion string) {
+ packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, v4SignatureFile android.WritablePath, lineageFile android.Path, rotationMinSdkVersion string, shrinkResources bool) {
unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk"
unsignedApk := android.PathForModuleOut(ctx, unsignedApkName)
@@ -65,7 +65,6 @@ func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.Writa
if jniJarFile != nil {
inputs = append(inputs, jniJarFile)
}
-
ctx.Build(pctx, android.BuildParams{
Rule: combineApk,
Inputs: inputs,
@@ -73,6 +72,11 @@ func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.Writa
Implicits: deps,
})
+ if shrinkResources {
+ shrunkenApk := android.PathForModuleOut(ctx, "resource-shrunken", unsignedApk.Base())
+ ShrinkResources(ctx, unsignedApk, shrunkenApk)
+ unsignedApk = shrunkenApk
+ }
SignAppPackage(ctx, outputFile, unsignedApk, certificates, v4SignatureFile, lineageFile, rotationMinSdkVersion)
}
@@ -84,7 +88,6 @@ func SignAppPackage(ctx android.ModuleContext, signedApk android.WritablePath, u
certificateArgs = append(certificateArgs, c.Pem.String(), c.Key.String())
deps = append(deps, c.Pem, c.Key)
}
-
outputFiles := android.WritablePaths{signedApk}
var flags []string
if v4SignatureFile != nil {
@@ -182,7 +185,7 @@ func BuildBundleModule(ctx android.ModuleContext, outputFile android.WritablePat
packageFile, jniJarFile, dexJarFile android.Path) {
protoResJarFile := android.PathForModuleOut(ctx, "package-res.pb.apk")
- aapt2Convert(ctx, protoResJarFile, packageFile)
+ aapt2Convert(ctx, protoResJarFile, packageFile, "proto")
var zips android.Paths
diff --git a/java/app_import.go b/java/app_import.go
index d6dca3836..6e603c912 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -318,19 +318,17 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
if a.isPrebuiltFrameworkRes() {
a.outputFile = srcApk
- certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
+ a.certificate, certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
if len(certificates) != 1 {
ctx.ModuleErrorf("Unexpected number of certificates were extracted: %q", certificates)
}
- a.certificate = certificates[0]
} else if a.preprocessed {
a.outputFile = srcApk
a.certificate = PresignedCertificate
} else if !Bool(a.properties.Presigned) {
// If the certificate property is empty at this point, default_dev_cert must be set to true.
// Which makes processMainCert's behavior for the empty cert string WAI.
- certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
- a.certificate = certificates[0]
+ a.certificate, certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
signed := android.PathForModuleOut(ctx, "signed", apkFilename)
var lineageFile android.Path
if lineage := String(a.properties.Lineage); lineage != "" {
diff --git a/java/app_import_test.go b/java/app_import_test.go
index 41be092e2..ad27e3ae7 100644
--- a/java/app_import_test.go
+++ b/java/app_import_test.go
@@ -807,3 +807,23 @@ func TestAndroidTestImport_UncompressDex(t *testing.T) {
}
}
}
+
+func TestAppImportMissingCertificateAllowMissingDependencies(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithAllowMissingDependencies,
+ android.PrepareForTestWithAndroidMk,
+ ).RunTestWithBp(t, `
+ android_app_import {
+ name: "foo",
+ apk: "a.apk",
+ certificate: ":missing_certificate",
+ }`)
+
+ foo := result.ModuleForTests("foo", "android_common")
+ fooApk := foo.Output("signed/foo.apk")
+ if fooApk.Rule != android.ErrorRule {
+ t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String())
+ }
+ android.AssertStringDoesContain(t, "expected error rule message", fooApk.Args["error"], "missing dependencies: missing_certificate\n")
+}
diff --git a/java/app_set.go b/java/app_set.go
index 694b1670e..d99fadb34 100644
--- a/java/app_set.go
+++ b/java/app_set.go
@@ -90,10 +90,11 @@ func (as *AndroidAppSet) APKCertsFile() android.Path {
}
var TargetCpuAbi = map[string]string{
- "arm": "ARMEABI_V7A",
- "arm64": "ARM64_V8A",
- "x86": "X86",
- "x86_64": "X86_64",
+ "arm": "ARMEABI_V7A",
+ "arm64": "ARM64_V8A",
+ "riscv64": "RISCV64",
+ "x86": "X86",
+ "x86_64": "X86_64",
}
func SupportedAbis(ctx android.ModuleContext) []string {
diff --git a/java/app_test.go b/java/app_test.go
index 23635b960..e216c630b 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -3057,6 +3057,179 @@ func TestTargetSdkVersionManifestFixer(t *testing.T) {
}
}
+func TestDefaultAppTargetSdkVersionForUpdatableModules(t *testing.T) {
+ platform_sdk_codename := "Tiramisu"
+ platform_sdk_version := 33
+ testCases := []struct {
+ name string
+ platform_sdk_final bool
+ targetSdkVersionInBp *string
+ targetSdkVersionExpected *string
+ updatable bool
+ }{
+ {
+ name: "Non-Updatable Module: Android.bp has older targetSdkVersion",
+ targetSdkVersionInBp: proptools.StringPtr("29"),
+ targetSdkVersionExpected: proptools.StringPtr("29"),
+ updatable: false,
+ },
+ {
+ name: "Updatable Module: Android.bp has older targetSdkVersion",
+ targetSdkVersionInBp: proptools.StringPtr("30"),
+ targetSdkVersionExpected: proptools.StringPtr("30"),
+ updatable: true,
+ },
+ {
+ name: "Updatable Module: Android.bp has no targetSdkVersion",
+ targetSdkVersionExpected: proptools.StringPtr("10000"),
+ updatable: true,
+ },
+ {
+ name: "[SDK finalised] Non-Updatable Module: Android.bp has older targetSdkVersion",
+ platform_sdk_final: true,
+ targetSdkVersionInBp: proptools.StringPtr("30"),
+ targetSdkVersionExpected: proptools.StringPtr("30"),
+ updatable: false,
+ },
+ {
+ name: "[SDK finalised] Updatable Module: Android.bp has older targetSdkVersion",
+ platform_sdk_final: true,
+ targetSdkVersionInBp: proptools.StringPtr("30"),
+ targetSdkVersionExpected: proptools.StringPtr("30"),
+ updatable: true,
+ },
+ {
+ name: "[SDK finalised] Updatable Module: Android.bp has targetSdkVersion as platform sdk codename",
+ platform_sdk_final: true,
+ targetSdkVersionInBp: proptools.StringPtr(platform_sdk_codename),
+ targetSdkVersionExpected: proptools.StringPtr("33"),
+ updatable: true,
+ },
+ {
+ name: "[SDK finalised] Updatable Module: Android.bp has no targetSdkVersion",
+ platform_sdk_final: true,
+ targetSdkVersionExpected: proptools.StringPtr("33"),
+ updatable: true,
+ },
+ }
+ for _, testCase := range testCases {
+ bp := fmt.Sprintf(`
+ android_app {
+ name: "foo",
+ sdk_version: "current",
+ min_sdk_version: "29",
+ target_sdk_version: "%v",
+ updatable: %t,
+ enforce_default_target_sdk_version: %t
+ }
+ `, proptools.String(testCase.targetSdkVersionInBp), testCase.updatable, testCase.updatable) // enforce default target sdk version if app is updatable
+
+ fixture := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithAllowMissingDependencies,
+ android.PrepareForTestWithAndroidMk,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ // explicitly set following platform variables to make the test deterministic
+ variables.Platform_sdk_final = &testCase.platform_sdk_final
+ variables.Platform_sdk_version = &platform_sdk_version
+ variables.Platform_sdk_codename = &platform_sdk_codename
+ variables.Platform_version_active_codenames = []string{platform_sdk_codename}
+ variables.Unbundled_build_apps = []string{"sampleModule"}
+ }),
+ )
+
+ result := fixture.RunTestWithBp(t, bp)
+ foo := result.ModuleForTests("foo", "android_common")
+
+ manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
+ android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+*testCase.targetSdkVersionExpected)
+ }
+}
+
+func TestEnforceDefaultAppTargetSdkVersionFlag(t *testing.T) {
+ platform_sdk_codename := "Tiramisu"
+ platform_sdk_version := 33
+ testCases := []struct {
+ name string
+ enforceDefaultTargetSdkVersion bool
+ expectedError string
+ platform_sdk_final bool
+ targetSdkVersionInBp string
+ targetSdkVersionExpected string
+ updatable bool
+ }{
+ {
+ name: "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion",
+ enforceDefaultTargetSdkVersion: false,
+ targetSdkVersionInBp: "29",
+ targetSdkVersionExpected: "29",
+ updatable: false,
+ },
+ {
+ name: "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
+ enforceDefaultTargetSdkVersion: true,
+ platform_sdk_final: true,
+ targetSdkVersionInBp: "current",
+ targetSdkVersionExpected: "33",
+ updatable: true,
+ },
+ {
+ name: "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
+ enforceDefaultTargetSdkVersion: true,
+ platform_sdk_final: false,
+ targetSdkVersionInBp: "current",
+ targetSdkVersionExpected: "10000",
+ updatable: false,
+ },
+ {
+ name: "Not enforcing Target SDK Version for Updatable app",
+ enforceDefaultTargetSdkVersion: false,
+ expectedError: "Updatable apps must enforce default target sdk version",
+ targetSdkVersionInBp: "29",
+ targetSdkVersionExpected: "29",
+ updatable: true,
+ },
+ }
+ for _, testCase := range testCases {
+ errExpected := testCase.expectedError != ""
+ bp := fmt.Sprintf(`
+ android_app {
+ name: "foo",
+ enforce_default_target_sdk_version: %t,
+ sdk_version: "current",
+ min_sdk_version: "29",
+ target_sdk_version: "%v",
+ updatable: %t
+ }
+ `, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp, testCase.updatable)
+
+ fixture := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithAllowMissingDependencies,
+ android.PrepareForTestWithAndroidMk,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ // explicitly set following platform variables to make the test deterministic
+ variables.Platform_sdk_final = &testCase.platform_sdk_final
+ variables.Platform_sdk_version = &platform_sdk_version
+ variables.Platform_sdk_codename = &platform_sdk_codename
+ variables.Unbundled_build_apps = []string{"sampleModule"}
+ }),
+ )
+
+ errorHandler := android.FixtureExpectsNoErrors
+ if errExpected {
+ errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
+ }
+ result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
+
+ if !errExpected {
+ foo := result.ModuleForTests("foo", "android_common")
+ manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
+ android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
+ }
+ }
+}
+
func TestAppMissingCertificateAllowMissingDependencies(t *testing.T) {
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
diff --git a/java/base.go b/java/base.go
index 53f0f52c2..96f36e87e 100644
--- a/java/base.go
+++ b/java/base.go
@@ -190,7 +190,7 @@ type CommonProperties struct {
// constructing a new module.
type DeviceProperties struct {
// If not blank, set to the version of the sdk to compile against.
- // Defaults to private.
+ // Defaults to an empty string, which compiles the module against the private platform APIs.
// Values are of one of the following forms:
// 1) numerical API level, "current", "none", or "core_platform"
// 2) An SDK kind with an API level: "<sdk kind>_<API level>"
@@ -447,9 +447,11 @@ type Module struct {
// installed file for hostdex copy
hostdexInstallFile android.InstallPath
- // list of .java files and srcjars that was passed to javac
- compiledJavaSrcs android.Paths
- compiledSrcJars android.Paths
+ // list of unique .java and .kt source files
+ uniqueSrcFiles android.Paths
+
+ // list of srcjars that was passed to javac
+ compiledSrcJars android.Paths
// manifest file to use instead of properties.Manifest
overrideManifest android.OptionalPath
@@ -530,7 +532,7 @@ func (j *Module) checkSdkVersions(ctx android.ModuleContext) {
// TODO(satayev): cover other types as well, e.g. imports
case *Library, *AndroidLibrary:
switch tag {
- case bootClasspathTag, libTag, staticLibTag, java9LibTag:
+ case bootClasspathTag, sdkLibTag, libTag, staticLibTag, java9LibTag:
j.checkSdkLinkType(ctx, module.(moduleWithSdkDep), tag.(dependencyTag))
}
}
@@ -650,6 +652,10 @@ func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool {
return false
}
+func (j *Module) setInstrument(value bool) {
+ j.properties.Instrument = value
+}
+
func (j *Module) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
return android.SdkSpecFrom(ctx, String(j.deviceProperties.Sdk_version))
}
@@ -789,9 +795,6 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {
} else if j.shouldInstrumentStatic(ctx) {
ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
}
- if j.shouldInstrument(ctx) {
- ctx.AddVariationDependencies(nil, libTag, "jacocoagent")
- }
if j.useCompose() {
ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), kotlinPluginTag,
@@ -862,7 +865,9 @@ func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.Opt
// add flags for dirs containing AIDL srcs that haven't been specified yet
flags = append(flags, genAidlIncludeFlags(ctx, aidlSrcs, includeDirs))
- if Bool(j.deviceProperties.Aidl.Generate_traces) {
+ sdkVersion := (j.SdkVersion(ctx)).Kind
+ defaultTrace := ((sdkVersion == android.SdkSystemServer) || (sdkVersion == android.SdkCore) || (sdkVersion == android.SdkCorePlatform))
+ if proptools.BoolDefault(j.deviceProperties.Aidl.Generate_traces, defaultTrace) {
flags = append(flags, "-t")
}
@@ -890,7 +895,7 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
epEnabled := j.properties.Errorprone.Enabled
if (ctx.Config().RunErrorProne() && epEnabled == nil) || Bool(epEnabled) {
- if config.ErrorProneClasspath == nil && ctx.Config().TestProductVariables == nil {
+ if config.ErrorProneClasspath == nil && !ctx.Config().RunningInsideUnitTest() {
ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
}
@@ -1075,15 +1080,26 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
jarName := ctx.ModuleName() + ".jar"
- javaSrcFiles := srcFiles.FilterByExt(".java")
- var uniqueSrcFiles android.Paths
+ var uniqueJavaFiles android.Paths
set := make(map[string]bool)
- for _, v := range javaSrcFiles {
+ for _, v := range srcFiles.FilterByExt(".java") {
if _, found := set[v.String()]; !found {
set[v.String()] = true
- uniqueSrcFiles = append(uniqueSrcFiles, v)
+ uniqueJavaFiles = append(uniqueJavaFiles, v)
}
}
+ var uniqueKtFiles android.Paths
+ for _, v := range srcFiles.FilterByExt(".kt") {
+ if _, found := set[v.String()]; !found {
+ set[v.String()] = true
+ uniqueKtFiles = append(uniqueKtFiles, v)
+ }
+ }
+
+ var uniqueSrcFiles android.Paths
+ uniqueSrcFiles = append(uniqueSrcFiles, uniqueJavaFiles...)
+ uniqueSrcFiles = append(uniqueSrcFiles, uniqueKtFiles...)
+ j.uniqueSrcFiles = uniqueSrcFiles
// We don't currently run annotation processors in turbine, which means we can't use turbine
// generated header jars when an annotation processor that generates API is enabled. One
@@ -1091,7 +1107,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
// is used to run all of the annotation processors.
disableTurbine := deps.disableTurbine
- // Collect .java files for AIDEGen
+ // Collect .java and .kt files for AIDEGen
j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...)
var kotlinJars android.Paths
@@ -1129,12 +1145,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
flags.kotlincFlags += "$kotlincFlags"
}
- var kotlinSrcFiles android.Paths
- kotlinSrcFiles = append(kotlinSrcFiles, uniqueSrcFiles...)
- kotlinSrcFiles = append(kotlinSrcFiles, srcFiles.FilterByExt(".kt")...)
-
- // Collect .kt files for AIDEGen
- j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.FilterByExt(".kt").Strings()...)
+ // Collect common .kt files for AIDEGen
j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...)
flags.classpath = append(flags.classpath, deps.kotlinStdlib...)
@@ -1147,7 +1158,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
// Use kapt for annotation processing
kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar")
kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar")
- kotlinKapt(ctx, kaptSrcJar, kaptResJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
+ kotlinKapt(ctx, kaptSrcJar, kaptResJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
srcJars = append(srcJars, kaptSrcJar)
kotlinJars = append(kotlinJars, kaptResJar)
// Disable annotation processing in javac, it's already been handled by kapt
@@ -1157,7 +1168,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName)
- kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
+ kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
if ctx.Failed() {
return
}
@@ -1182,8 +1193,6 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
jars := append(android.Paths(nil), kotlinJars...)
- // Store the list of .java files that was passed to javac
- j.compiledJavaSrcs = uniqueSrcFiles
j.compiledSrcJars = srcJars
enableSharding := false
@@ -1198,12 +1207,12 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
// with sharding enabled. See: b/77284273.
}
headerJarFileWithoutDepsOrJarjar, j.headerJarFile =
- j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinHeaderJars)
+ j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, kotlinHeaderJars)
if ctx.Failed() {
return
}
}
- if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 {
+ if len(uniqueJavaFiles) > 0 || len(srcJars) > 0 {
hasErrorproneableFiles := false
for _, ext := range j.sourceExtensions {
if ext != ".proto" && ext != ".aidl" {
@@ -1228,7 +1237,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
errorproneFlags := enableErrorproneFlags(flags)
errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
- transformJavaToClasses(ctx, errorprone, -1, uniqueSrcFiles, srcJars, errorproneFlags, nil,
+ transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneFlags, nil,
"errorprone", "errorprone")
extraJarDeps = append(extraJarDeps, errorprone)
@@ -1240,8 +1249,8 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
}
shardSize := int(*(j.properties.Javac_shard_size))
var shardSrcs []android.Paths
- if len(uniqueSrcFiles) > 0 {
- shardSrcs = android.ShardPaths(uniqueSrcFiles, shardSize)
+ if len(uniqueJavaFiles) > 0 {
+ shardSrcs = android.ShardPaths(uniqueJavaFiles, shardSize)
for idx, shardSrc := range shardSrcs {
classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
nil, flags, extraJarDeps)
@@ -1254,7 +1263,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
jars = append(jars, classes)
}
} else {
- classes := j.compileJavaClasses(ctx, jarName, -1, uniqueSrcFiles, srcJars, flags, extraJarDeps)
+ classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
jars = append(jars, classes)
}
if ctx.Failed() {
@@ -1435,10 +1444,6 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
j.headerJarFile = j.implementationJarFile
}
- if j.shouldInstrumentInApex(ctx) {
- j.properties.Instrument = true
- }
-
// enforce syntax check to jacoco filters for any build (http://b/183622051)
specs := j.jacocoModuleToZipCommand(ctx)
if ctx.Failed() {
@@ -1956,7 +1961,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
if dep, ok := module.(SdkLibraryDependency); ok {
switch tag {
- case libTag:
+ case sdkLibTag, libTag:
depHeaderJars := dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))
deps.classpath = append(deps.classpath, depHeaderJars...)
deps.dexClasspath = append(deps.dexClasspath, depHeaderJars...)
@@ -1976,7 +1981,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
switch tag {
case bootClasspathTag:
deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...)
- case libTag, instrumentationForTag:
+ case sdkLibTag, libTag, instrumentationForTag:
if _, ok := module.(*Plugin); ok {
ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a libs dependency", otherName)
}
@@ -2049,7 +2054,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
}
} else if dep, ok := module.(android.SourceFileProducer); ok {
switch tag {
- case libTag:
+ case sdkLibTag, libTag:
checkProducesJars(ctx, dep)
deps.classpath = append(deps.classpath, dep.Srcs()...)
deps.dexClasspath = append(deps.classpath, dep.Srcs()...)
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 93168070e..3a28c5910 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -257,14 +257,14 @@ type commonBootclasspathFragment interface {
// Returns a *HiddenAPIOutput containing the paths for the generated files. Returns nil if the
// module cannot contribute to hidden API processing, e.g. because it is a prebuilt module in a
// versioned sdk.
- produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput
+ produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput
// produceBootImageFiles will attempt to produce rules to create the boot image files at the paths
// predefined in the bootImageConfig.
//
// If it could not create the files then it will return nil. Otherwise, it will return a map from
// android.ArchType to the predefined paths of the boot image files.
- produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch
+ produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs
}
var _ commonBootclasspathFragment = (*BootclasspathFragmentModule)(nil)
@@ -583,23 +583,24 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
// Perform hidden API processing.
hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments)
- var bootImageFilesByArch bootImageFilesByArch
+ var bootImageFiles bootImageOutputs
if imageConfig != nil {
// Delegate the production of the boot image files to a module type specific method.
common := ctx.Module().(commonBootclasspathFragment)
- bootImageFilesByArch = common.produceBootImageFiles(ctx, imageConfig)
+ bootImageFiles = common.produceBootImageFiles(ctx, imageConfig)
if shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) {
// Zip the boot image files up, if available. This will generate the zip file in a
// predefined location.
- buildBootImageZipInPredefinedLocation(ctx, imageConfig, bootImageFilesByArch)
+ buildBootImageZipInPredefinedLocation(ctx, imageConfig, bootImageFiles.byArch)
// Copy the dex jars of this fragment's content modules to their predefined locations.
copyBootJarsToPredefinedLocations(ctx, hiddenAPIOutput.EncodedBootDexFilesByModule, imageConfig.dexPathsByModule)
}
- for _, variant := range imageConfig.apexVariants() {
- arch := variant.target.Arch.ArchType.String()
+ for _, variant := range bootImageFiles.variants {
+ archType := variant.config.target.Arch.ArchType
+ arch := archType.String()
for _, install := range variant.deviceInstalls {
// Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT.
installDir := strings.TrimPrefix(filepath.Dir(install.To), "/")
@@ -620,7 +621,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
// A prebuilt fragment cannot contribute to an apex.
if !android.IsModulePrebuilt(ctx.Module()) {
// Provide the apex content info.
- b.provideApexContentInfo(ctx, imageConfig, hiddenAPIOutput, bootImageFilesByArch)
+ b.provideApexContentInfo(ctx, imageConfig, hiddenAPIOutput, bootImageFiles)
}
} else {
// Versioned fragments are not needed by make.
@@ -663,7 +664,7 @@ func shouldCopyBootFilesToPredefinedLocations(ctx android.ModuleContext, imageCo
// provideApexContentInfo creates, initializes and stores the apex content info for use by other
// modules.
-func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, hiddenAPIOutput *HiddenAPIOutput, bootImageFilesByArch bootImageFilesByArch) {
+func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, hiddenAPIOutput *HiddenAPIOutput, bootImageFiles bootImageOutputs) {
// Construct the apex content info from the config.
info := BootclasspathFragmentApexContentInfo{
// Populate the apex content info with paths to the dex jars.
@@ -674,14 +675,14 @@ func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleC
info.modules = imageConfig.modules
global := dexpreopt.GetGlobalConfig(ctx)
if !global.DisableGenerateProfile {
- info.profilePathOnHost = imageConfig.profilePathOnHost
+ info.profilePathOnHost = bootImageFiles.profile
info.profileInstallPathInApex = imageConfig.profileInstallPathInApex
}
info.shouldInstallBootImageInApex = imageConfig.shouldInstallInApex()
}
- info.bootImageFilesByArch = bootImageFilesByArch
+ info.bootImageFilesByArch = bootImageFiles.byArch
// Make the apex content info available for other modules.
ctx.SetProvider(BootclasspathFragmentApexContentInfoProvider, info)
@@ -716,8 +717,6 @@ func (b *BootclasspathFragmentModule) configuredJars(ctx android.ModuleContext)
// This is an exception to support end-to-end test for SdkExtensions, until such support exists.
if android.InList("test_framework-sdkextensions", possibleUpdatableModules) {
jars = jars.Append("com.android.sdkext", "test_framework-sdkextensions")
- } else if android.InList("AddNewActivity", possibleUpdatableModules) {
- jars = jars.Append("test_com.android.cts.frameworkresapkplits", "AddNewActivity")
} else if android.InList("test_framework-apexd", possibleUpdatableModules) {
jars = jars.Append("com.android.apex.test_package", "test_framework-apexd")
} else if global.ApexBootJars.Len() != 0 && !android.IsModuleInVersionedSdk(ctx.Module()) {
@@ -761,7 +760,7 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.
// Delegate the production of the hidden API all-flags.csv file to a module type specific method.
common := ctx.Module().(commonBootclasspathFragment)
- output := common.produceHiddenAPIOutput(ctx, contents, input)
+ output := common.produceHiddenAPIOutput(ctx, contents, fragments, input)
// If the source or prebuilts module does not provide a signature patterns file then generate one
// from the flags.
@@ -769,7 +768,7 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.
// their own.
if output.SignaturePatternsPath == nil {
output.SignaturePatternsPath = buildRuleSignaturePatternsFile(
- ctx, output.AllFlagsPath, []string{"*"}, nil, nil)
+ ctx, output.AllFlagsPath, []string{"*"}, nil, nil, "")
}
// Initialize a HiddenAPIInfo structure.
@@ -840,30 +839,15 @@ func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.Modul
// isTestFragment returns true if the current module is a test bootclasspath_fragment.
func (b *BootclasspathFragmentModule) isTestFragment() bool {
- if b.testFragment {
- return true
- }
-
- // TODO(b/194063708): Once test fragments all use bootclasspath_fragment_test
- // Some temporary exceptions until all test fragments use the
- // bootclasspath_fragment_test module type.
- name := b.BaseModuleName()
- if strings.HasPrefix(name, "test_") {
- return true
- }
- if name == "apex.apexd_test_bootclasspath-fragment" {
- return true
- }
-
- return false
+ return b.testFragment
}
-// produceHiddenAPIOutput produces the hidden API all-flags.csv file (and supporting files)
-// for the fragment as well as encoding the flags in the boot dex jars.
-func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
+// generateHiddenApiFlagRules generates rules to generate hidden API flags and compute the signature
+// patterns file.
+func (b *BootclasspathFragmentModule) generateHiddenApiFlagRules(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput, bootDexInfoByModule bootDexInfoByModule, suffix string) HiddenAPIFlagOutput {
// Generate the rules to create the hidden API flags and update the supplied hiddenAPIInfo with the
// paths to the created files.
- output := hiddenAPIRulesForBootclasspathFragment(ctx, contents, input)
+ flagOutput := hiddenAPIFlagRulesForBootclasspathFragment(ctx, bootDexInfoByModule, contents, input, suffix)
// If the module specifies split_packages or package_prefixes then use those to generate the
// signature patterns.
@@ -871,8 +855,8 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleC
packagePrefixes := input.PackagePrefixes
singlePackages := input.SinglePackages
if splitPackages != nil || packagePrefixes != nil || singlePackages != nil {
- output.SignaturePatternsPath = buildRuleSignaturePatternsFile(
- ctx, output.AllFlagsPath, splitPackages, packagePrefixes, singlePackages)
+ flagOutput.SignaturePatternsPath = buildRuleSignaturePatternsFile(
+ ctx, flagOutput.AllFlagsPath, splitPackages, packagePrefixes, singlePackages, suffix)
} else if !b.isTestFragment() {
ctx.ModuleErrorf(`Must specify at least one of the split_packages, package_prefixes and single_packages properties
If this is a new bootclasspath_fragment or you are unsure what to do add the
@@ -884,14 +868,76 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleC
should specify here. If you are happy with its suggestions then you can add
the --fix option and it will fix them for you.`, b.BaseModuleName())
}
+ return flagOutput
+}
+
+// produceHiddenAPIOutput produces the hidden API all-flags.csv file (and supporting files)
+// for the fragment as well as encoding the flags in the boot dex jars.
+func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
+ // Gather information about the boot dex files for the boot libraries provided by this fragment.
+ bootDexInfoByModule := extractBootDexInfoFromModules(ctx, contents)
+
+ // Generate the flag file needed to encode into the dex files.
+ flagOutput := b.generateHiddenApiFlagRules(ctx, contents, input, bootDexInfoByModule, "")
+
+ // Encode those flags into the dex files of the contents of this fragment.
+ encodedBootDexFilesByModule := hiddenAPIEncodeRulesForBootclasspathFragment(ctx, bootDexInfoByModule, flagOutput.AllFlagsPath)
+
+ // Store that information for return for use by other rules.
+ output := &HiddenAPIOutput{
+ HiddenAPIFlagOutput: flagOutput,
+ EncodedBootDexFilesByModule: encodedBootDexFilesByModule,
+ }
+
+ // Get the ApiLevel associated with SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE, defaulting to current
+ // if not set.
+ config := ctx.Config()
+ targetApiLevel := android.ApiLevelOrPanic(ctx,
+ config.GetenvWithDefault("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE", "current"))
+
+ // Filter the contents list to remove any modules that do not support the target build release.
+ // The current build release supports all the modules.
+ contentsForSdkSnapshot := []android.Module{}
+ for _, module := range contents {
+ // If the module has a min_sdk_version that is higher than the target build release then it will
+ // not work on the target build release and so must not be included in the sdk snapshot.
+ minApiLevel := android.MinApiLevelForSdkSnapshot(ctx, module)
+ if minApiLevel.GreaterThan(targetApiLevel) {
+ continue
+ }
+
+ contentsForSdkSnapshot = append(contentsForSdkSnapshot, module)
+ }
+
+ var flagFilesByCategory FlagFilesByCategory
+ if len(contentsForSdkSnapshot) != len(contents) {
+ // The sdk snapshot has different contents to the runtime fragment so it is not possible to
+ // reuse the hidden API information generated for the fragment. So, recompute that information
+ // for the sdk snapshot.
+ filteredInput := b.createHiddenAPIFlagInput(ctx, contentsForSdkSnapshot, fragments)
+
+ // Gather information about the boot dex files for the boot libraries provided by this fragment.
+ filteredBootDexInfoByModule := extractBootDexInfoFromModules(ctx, contentsForSdkSnapshot)
+ flagOutput = b.generateHiddenApiFlagRules(ctx, contentsForSdkSnapshot, filteredInput, filteredBootDexInfoByModule, "-for-sdk-snapshot")
+ flagFilesByCategory = filteredInput.FlagFilesByCategory
+ } else {
+ // The sdk snapshot has the same contents as the runtime fragment so reuse that information.
+ flagFilesByCategory = input.FlagFilesByCategory
+ }
+
+ // Make the information available for the sdk snapshot.
+ ctx.SetProvider(HiddenAPIInfoForSdkProvider, HiddenAPIInfoForSdk{
+ FlagFilesByCategory: flagFilesByCategory,
+ HiddenAPIFlagOutput: flagOutput,
+ })
return output
}
// produceBootImageFiles builds the boot image files from the source if it is required.
-func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch {
+func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
if SkipDexpreoptBootJars(ctx) {
- return nil
+ return bootImageOutputs{}
}
// Only generate the boot image if the configuration does not skip it.
@@ -903,21 +949,21 @@ func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleCo
//
// If it could not create the files then it will return nil. Otherwise, it will return a map from
// android.ArchType to the predefined paths of the boot image files.
-func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch {
+func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
global := dexpreopt.GetGlobalConfig(ctx)
if !shouldBuildBootImages(ctx.Config(), global) {
- return nil
+ return bootImageOutputs{}
}
// Bootclasspath fragment modules that are for the platform do not produce a boot image.
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
if apexInfo.IsForPlatform() {
- return nil
+ return bootImageOutputs{}
}
// Bootclasspath fragment modules that are versioned do not produce a boot image.
if android.IsModuleInVersionedSdk(ctx.Module()) {
- return nil
+ return bootImageOutputs{}
}
// Build a profile for the image config and then use that to build the boot image.
@@ -927,11 +973,11 @@ func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.
buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
// Build boot image files for the android variants.
- androidBootImageFilesByArch := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
+ bootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
// Return the boot image files for the android variants for inclusion in an APEX and to be zipped
// up for the dist.
- return androidBootImageFilesByArch
+ return bootImageFiles
}
func (b *BootclasspathFragmentModule) AndroidMkEntries() []android.AndroidMkEntries {
@@ -1049,7 +1095,7 @@ func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx andro
// Get the hidden API information from the module.
mctx := ctx.SdkModuleContext()
- hiddenAPIInfo := mctx.OtherModuleProvider(module, HiddenAPIInfoProvider).(HiddenAPIInfo)
+ hiddenAPIInfo := mctx.OtherModuleProvider(module, HiddenAPIInfoForSdkProvider).(HiddenAPIInfoForSdk)
b.Flag_files_by_category = hiddenAPIInfo.FlagFilesByCategory
// Copy all the generated file paths.
@@ -1191,7 +1237,7 @@ func (module *PrebuiltBootclasspathFragmentModule) Name() string {
}
// produceHiddenAPIOutput returns a path to the prebuilt all-flags.csv or nil if none is specified.
-func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
+func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
pathForOptionalSrc := func(src *string, defaultPath android.Path) android.Path {
if src == nil {
return defaultPath
@@ -1232,14 +1278,14 @@ func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx an
}
// produceBootImageFiles extracts the boot image files from the APEX if available.
-func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch {
+func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
if !shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) {
- return nil
+ return bootImageOutputs{}
}
di := android.FindDeapexerProviderForModule(ctx)
if di == nil {
- return nil // An error has been reported by FindDeapexerProviderForModule.
+ return bootImageOutputs{} // An error has been reported by FindDeapexerProviderForModule.
}
profile := (android.WritablePath)(nil)
@@ -1257,8 +1303,17 @@ func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx and
// If the boot image files for the android variants are in the prebuilt apex, we must use those
// rather than building new ones because those boot image files are going to be used on device.
files := bootImageFilesByArch{}
+ bootImageFiles := bootImageOutputs{
+ byArch: files,
+ profile: profile,
+ }
for _, variant := range imageConfig.apexVariants() {
arch := variant.target.Arch.ArchType
+ bootImageFiles.variants = append(bootImageFiles.variants, bootImageVariantOutputs{
+ variant,
+ // No device installs needed when installed in APEX.
+ nil,
+ })
for _, toPath := range variant.imagesDeps {
apexRelativePath := apexRootRelativePathToBootImageFile(arch, toPath.Base())
// Get the path to the file that the deapexer extracted from the prebuilt apex file.
@@ -1276,11 +1331,11 @@ func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx and
})
}
}
- return files
+ return bootImageFiles
} else {
if profile == nil {
ctx.ModuleErrorf("Unable to produce boot image files: neither boot image files nor profiles exists in the prebuilt apex")
- return nil
+ return bootImageOutputs{}
}
// Build boot image files for the android variants from the dex files provided by the contents
// of this module.
diff --git a/java/bootclasspath_fragment_test.go b/java/bootclasspath_fragment_test.go
index 2bfb255af..2541f14ff 100644
--- a/java/bootclasspath_fragment_test.go
+++ b/java/bootclasspath_fragment_test.go
@@ -96,23 +96,6 @@ func TestBootclasspathFragmentInconsistentArtConfiguration_ApexMixture(t *testin
}
func TestBootclasspathFragment_Coverage(t *testing.T) {
- prepareForTestWithFrameworkCoverage := android.GroupFixturePreparers(
- android.FixtureMergeEnv(map[string]string{
- "EMMA_INSTRUMENT": "true",
- "EMMA_INSTRUMENT_FRAMEWORK": "true",
- }),
- // need to mock jacocoagent here to satisfy dependency added for
- // instrumented libraries at build time
- android.FixtureAddFile("jacocoagent/Android.bp", []byte(`
- java_library {
- name: "jacocoagent",
- srcs: ["Test.java"],
- system_modules: "none",
- sdk_version: "none",
- }
- `)),
- )
-
prepareWithBp := android.FixtureWithRootAndroidBp(`
bootclasspath_fragment {
name: "myfragment",
@@ -191,7 +174,7 @@ func TestBootclasspathFragment_Coverage(t *testing.T) {
t.Run("with coverage", func(t *testing.T) {
result := android.GroupFixturePreparers(
- prepareForTestWithFrameworkCoverage,
+ prepareForTestWithFrameworkJacocoInstrumentation,
preparer,
).RunTest(t)
checkContents(t, result, "mybootlib", "coveragelib")
@@ -425,22 +408,6 @@ func TestBootclasspathFragment_Test(t *testing.T) {
},
}
- bootclasspath_fragment {
- name: "test_fragment",
- contents: ["mysdklibrary"],
- hidden_api: {
- split_packages: [],
- },
- }
-
- bootclasspath_fragment {
- name: "apex.apexd_test_bootclasspath-fragment",
- contents: ["mysdklibrary"],
- hidden_api: {
- split_packages: [],
- },
- }
-
bootclasspath_fragment_test {
name: "a_test_fragment",
contents: ["mysdklibrary"],
@@ -462,12 +429,6 @@ func TestBootclasspathFragment_Test(t *testing.T) {
fragment := result.Module("myfragment", "android_common").(*BootclasspathFragmentModule)
android.AssertBoolEquals(t, "not a test fragment", false, fragment.isTestFragment())
- fragment = result.Module("test_fragment", "android_common").(*BootclasspathFragmentModule)
- android.AssertBoolEquals(t, "is a test fragment by prefix", true, fragment.isTestFragment())
-
fragment = result.Module("a_test_fragment", "android_common").(*BootclasspathFragmentModule)
android.AssertBoolEquals(t, "is a test fragment by type", true, fragment.isTestFragment())
-
- fragment = result.Module("apex.apexd_test_bootclasspath-fragment", "android_common").(*BootclasspathFragmentModule)
- android.AssertBoolEquals(t, "is a test fragment by name", true, fragment.isTestFragment())
}
diff --git a/java/config/config.go b/java/config/config.go
index 422f86002..45b668b0c 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -78,12 +78,12 @@ var (
func init() {
pctx.Import("github.com/google/blueprint/bootstrap")
- exportedVars.ExportStringStaticVariable("JavacHeapSize", "2048M")
+ exportedVars.ExportStringStaticVariable("JavacHeapSize", "4096M")
exportedVars.ExportStringStaticVariable("JavacHeapFlags", "-J-Xmx${JavacHeapSize}")
// ErrorProne can use significantly more memory than javac alone, give it a higher heap
// size (b/221480398).
- exportedVars.ExportStringStaticVariable("ErrorProneHeapSize", "4096M")
+ exportedVars.ExportStringStaticVariable("ErrorProneHeapSize", "8192M")
exportedVars.ExportStringStaticVariable("ErrorProneHeapFlags", "-J-Xmx${ErrorProneHeapSize}")
// D8 invocations are shorter lived, so we restrict their JIT tiering relative to R8.
@@ -128,12 +128,7 @@ func init() {
if override := ctx.Config().Getenv("OVERRIDE_JLINK_VERSION_NUMBER"); override != "" {
return override
}
- switch ctx.Config().Getenv("EXPERIMENTAL_USE_OPENJDK17_TOOLCHAIN") {
- case "true":
- return "17"
- default:
- return "11"
- }
+ return "17"
})
pctx.SourcePathVariable("JavaToolchain", "${JavaHome}/bin")
@@ -160,6 +155,7 @@ func init() {
pctx.HostBinToolVariable("ApiCheckCmd", "apicheck")
pctx.HostBinToolVariable("D8Cmd", "d8")
pctx.HostBinToolVariable("R8Cmd", "r8")
+ pctx.HostBinToolVariable("ResourceShrinkerCmd", "resourceshrinker")
pctx.HostBinToolVariable("HiddenAPICmd", "hiddenapi")
pctx.HostBinToolVariable("ExtractApksCmd", "extract_apks")
pctx.VariableFunc("TurbineJar", func(ctx android.PackageVarContext) string {
diff --git a/java/dex.go b/java/dex.go
index a44d7921f..de36b1865 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -63,6 +63,8 @@ type DexProperties struct {
// classes referenced by the app manifest. Defaults to false.
No_aapt_flags *bool
+ Shrink_resources *bool
+
// Flags to pass to proguard.
Proguard_flags []string
@@ -200,6 +202,16 @@ func (d *dexer) dexCommonFlags(ctx android.ModuleContext,
"--verbose")
}
+ // Supplying the platform build flag disables various features like API modeling and desugaring.
+ // For targets with a stable min SDK version (i.e., when the min SDK is both explicitly specified
+ // and managed+versioned), we suppress this flag to ensure portability.
+ // Note: Targets with a min SDK kind of core_platform (e.g., framework.jar) or unspecified (e.g.,
+ // services.jar), are not classified as stable, which is WAI.
+ // TODO(b/232073181): Expand to additional min SDK cases after validation.
+ if !minSdkVersion.Stable() {
+ flags = append(flags, "--android-platform-build")
+ }
+
effectiveVersion, err := minSdkVersion.EffectiveVersion(ctx)
if err != nil {
ctx.PropertyErrorf("min_sdk_version", "%s", err)
diff --git a/java/dex_test.go b/java/dex_test.go
index a3e2deda4..66178732a 100644
--- a/java/dex_test.go
+++ b/java/dex_test.go
@@ -30,6 +30,19 @@ func TestR8(t *testing.T) {
platform_apis: true,
}
+ android_app {
+ name: "stable_app",
+ srcs: ["foo.java"],
+ sdk_version: "current",
+ min_sdk_version: "31",
+ }
+
+ android_app {
+ name: "core_platform_app",
+ srcs: ["foo.java"],
+ sdk_version: "core_platform",
+ }
+
java_library {
name: "lib",
srcs: ["foo.java"],
@@ -42,11 +55,15 @@ func TestR8(t *testing.T) {
`)
app := result.ModuleForTests("app", "android_common")
+ stableApp := result.ModuleForTests("stable_app", "android_common")
+ corePlatformApp := result.ModuleForTests("core_platform_app", "android_common")
lib := result.ModuleForTests("lib", "android_common")
staticLib := result.ModuleForTests("static_lib", "android_common")
appJavac := app.Rule("javac")
appR8 := app.Rule("r8")
+ stableAppR8 := stableApp.Rule("r8")
+ corePlatformAppR8 := corePlatformApp.Rule("r8")
libHeader := lib.Output("turbine-combined/lib.jar").Output
staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
@@ -61,6 +78,12 @@ func TestR8(t *testing.T) {
appR8.Args["r8Flags"], staticLibHeader.String())
android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
appR8.Args["r8Flags"], "-ignorewarnings")
+ android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
+ appR8.Args["r8Flags"], "--android-platform-build")
+ android.AssertStringDoesNotContain(t, "expected no --android-platform-build in stable_app r8 flags",
+ stableAppR8.Args["r8Flags"], "--android-platform-build")
+ android.AssertStringDoesContain(t, "expected --android-platform-build in core_platform_app r8 flags",
+ corePlatformAppR8.Args["r8Flags"], "--android-platform-build")
}
func TestR8Flags(t *testing.T) {
@@ -88,7 +111,8 @@ func TestR8Flags(t *testing.T) {
appR8.Args["r8Flags"], "-dontobfuscate")
android.AssertStringDoesNotContain(t, "expected no -ignorewarnings in app r8 flags",
appR8.Args["r8Flags"], "-ignorewarnings")
-
+ android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
+ appR8.Args["r8Flags"], "--android-platform-build")
}
func TestD8(t *testing.T) {
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 4e416fc82..b3faae895 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -228,6 +228,11 @@ func init() {
}
// Target-independent description of a boot image.
+//
+// WARNING: All fields in this struct should be initialized in the genBootImageConfigs function.
+// Failure to do so can lead to data races if there is no synchronization enforced ordering between
+// the writer and the reader. Fields which break this rule are marked as deprecated and should be
+// removed and replaced with something else, e.g. providers.
type bootImageConfig struct {
// If this image is an extension, the image that it extends.
extends *bootImageConfig
@@ -268,14 +273,15 @@ type bootImageConfig struct {
zip android.WritablePath
// Rules which should be used in make to install the outputs.
+ //
+ // Deprecated: Not initialized correctly, see struct comment.
profileInstalls android.RuleBuilderInstalls
// Path to the license metadata file for the module that built the profile.
+ //
+ // Deprecated: Not initialized correctly, see struct comment.
profileLicenseMetadataFile android.OptionalPath
- // Path to the image profile file on host (or empty, if profile is not generated).
- profilePathOnHost android.Path
-
// Target-dependent fields.
variants []*bootImageVariant
@@ -284,6 +290,8 @@ type bootImageConfig struct {
}
// Target-dependent description of a boot image.
+//
+// WARNING: The warning comment on bootImageConfig applies here too.
type bootImageVariant struct {
*bootImageConfig
@@ -314,14 +322,23 @@ type bootImageVariant struct {
primaryImagesDeps android.Paths
// Rules which should be used in make to install the outputs on host.
- installs android.RuleBuilderInstalls
- vdexInstalls android.RuleBuilderInstalls
- unstrippedInstalls android.RuleBuilderInstalls
+ //
+ // Deprecated: Not initialized correctly, see struct comment.
+ installs android.RuleBuilderInstalls
- // Rules which should be used in make to install the outputs on device.
- deviceInstalls android.RuleBuilderInstalls
+ // Rules which should be used in make to install the vdex outputs on host.
+ //
+ // Deprecated: Not initialized correctly, see struct comment.
+ vdexInstalls android.RuleBuilderInstalls
+
+ // Rules which should be used in make to install the unstripped outputs on host.
+ //
+ // Deprecated: Not initialized correctly, see struct comment.
+ unstrippedInstalls android.RuleBuilderInstalls
// Path to the license metadata file for the module that built the image.
+ //
+ // Deprecated: Not initialized correctly, see struct comment.
licenseMetadataFile android.OptionalPath
}
@@ -548,7 +565,7 @@ func copyBootJarsToPredefinedLocations(ctx android.ModuleContext, srcBootDexJars
// boot image files.
//
// The paths are returned because they are needed elsewhere in Soong, e.g. for populating an APEX.
-func buildBootImageVariantsForAndroidOs(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) bootImageFilesByArch {
+func buildBootImageVariantsForAndroidOs(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) bootImageOutputs {
return buildBootImageForOsType(ctx, image, profile, android.Android)
}
@@ -563,21 +580,38 @@ func buildBootImageVariantsForBuildOs(ctx android.ModuleContext, image *bootImag
buildBootImageForOsType(ctx, image, profile, ctx.Config().BuildOS)
}
+// bootImageOutputs encapsulates information about boot images that were created/obtained by
+// commonBootclasspathFragment.produceBootImageFiles.
+type bootImageOutputs struct {
+ // Map from arch to the paths to the boot image files created/obtained for that arch.
+ byArch bootImageFilesByArch
+
+ variants []bootImageVariantOutputs
+
+ // The path to the profile file created/obtained for the boot image.
+ profile android.WritablePath
+}
+
// buildBootImageForOsType takes a bootImageConfig, a profile file and an android.OsType
// boot image files are required for and it creates rules to build the boot image
// files for all the required architectures for them.
//
// It returns a map from android.ArchType to the predefined paths of the boot image files.
-func buildBootImageForOsType(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath, requiredOsType android.OsType) bootImageFilesByArch {
+func buildBootImageForOsType(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath, requiredOsType android.OsType) bootImageOutputs {
filesByArch := bootImageFilesByArch{}
+ imageOutputs := bootImageOutputs{
+ byArch: filesByArch,
+ profile: profile,
+ }
for _, variant := range image.variants {
if variant.target.Os == requiredOsType {
- buildBootImageVariant(ctx, variant, profile)
+ variantOutputs := buildBootImageVariant(ctx, variant, profile)
+ imageOutputs.variants = append(imageOutputs.variants, variantOutputs)
filesByArch[variant.target.Arch.ArchType] = variant.imagesDeps.Paths()
}
}
- return filesByArch
+ return imageOutputs
}
// buildBootImageZipInPredefinedLocation generates a zip file containing all the boot image files.
@@ -605,8 +639,13 @@ func buildBootImageZipInPredefinedLocation(ctx android.ModuleContext, image *boo
rule.Build("zip_"+image.name, "zip "+image.name+" image")
}
+type bootImageVariantOutputs struct {
+ config *bootImageVariant
+ deviceInstalls android.RuleBuilderInstalls
+}
+
// Generate boot image build rules for a specific target.
-func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, profile android.Path) {
+func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, profile android.Path) bootImageVariantOutputs {
globalSoong := dexpreopt.GetGlobalSoongConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
@@ -764,11 +803,20 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
rule.Build(image.name+"JarsDexpreopt_"+image.target.String(), "dexpreopt "+image.name+" jars "+arch.String())
// save output and installed files for makevars
+ // TODO - these are always the same and so should be initialized in genBootImageConfigs
image.installs = rule.Installs()
image.vdexInstalls = vdexInstalls
image.unstrippedInstalls = unstrippedInstalls
- image.deviceInstalls = deviceInstalls
- image.licenseMetadataFile = android.OptionalPathForPath(ctx.LicenseMetadataFile())
+
+ // Only set the licenseMetadataFile from the active module.
+ if isActiveModule(ctx.Module()) {
+ image.licenseMetadataFile = android.OptionalPathForPath(ctx.LicenseMetadataFile())
+ }
+
+ return bootImageVariantOutputs{
+ image,
+ deviceInstalls,
+ }
}
const failureMessage = `ERROR: Dex2oat failed to compile a boot image.
@@ -824,8 +872,6 @@ func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) and
rule.Build("bootJarsProfile", "profile boot jars")
- image.profilePathOnHost = profile
-
return profile
}
diff --git a/java/dexpreopt_config_test.go b/java/dexpreopt_config_test.go
new file mode 100644
index 000000000..b704d09d2
--- /dev/null
+++ b/java/dexpreopt_config_test.go
@@ -0,0 +1,35 @@
+// Copyright 2022 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+ "runtime"
+ "testing"
+
+ "android/soong/android"
+)
+
+func TestBootImageConfig(t *testing.T) {
+ if runtime.GOOS != "linux" {
+ t.Skipf("Skipping as boot image config test is only supported on linux not %s", runtime.GOOS)
+ }
+
+ result := android.GroupFixturePreparers(
+ PrepareForBootImageConfigTest,
+ ).RunTest(t)
+
+ CheckArtBootImageConfig(t, result)
+ CheckFrameworkBootImageConfig(t, result)
+}
diff --git a/java/dexpreopt_config_testing.go b/java/dexpreopt_config_testing.go
new file mode 100644
index 000000000..1c236d8af
--- /dev/null
+++ b/java/dexpreopt_config_testing.go
@@ -0,0 +1,768 @@
+// Copyright 2022 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Testing support for dexpreopt config.
+//
+// The bootImageConfig/bootImageVariant structs returned by genBootImageConfigs are used in many
+// places in the build and are currently mutated in a number of those locations. This provides
+// comprehensive tests of the fields in those structs to ensure that they have been initialized
+// correctly and where relevant, mutated correctly.
+//
+// This is used in TestBootImageConfig to verify that the
+
+package java
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+
+ "android/soong/android"
+)
+
+// PrepareForBootImageConfigTest is the minimal set of preparers that are needed to be able to use
+// the Check*BootImageConfig methods define here.
+var PrepareForBootImageConfigTest = android.GroupFixturePreparers(
+ android.PrepareForTestWithArchMutator,
+ android.PrepareForTestAccessingMakeVars,
+ FixtureConfigureBootJars("com.android.art:core1", "com.android.art:core2", "platform:framework"),
+)
+
+// normalizedInstall represents a android.RuleBuilderInstall that has been normalized to remove
+// test specific parts of the From path.
+type normalizedInstall struct {
+ from string
+ to string
+}
+
+// normalizeInstalls converts a slice of android.RuleBuilderInstall into a slice of
+// normalizedInstall to allow them to be compared using android.AssertDeepEquals.
+func normalizeInstalls(installs android.RuleBuilderInstalls) []normalizedInstall {
+ var normalized []normalizedInstall
+ for _, install := range installs {
+ normalized = append(normalized, normalizedInstall{
+ from: install.From.RelativeToTop().String(),
+ to: install.To,
+ })
+ }
+ return normalized
+}
+
+// assertInstallsEqual normalized the android.RuleBuilderInstalls and compares against the expected
+// normalizedInstalls.
+func assertInstallsEqual(t *testing.T, message string, expected []normalizedInstall, actual android.RuleBuilderInstalls) {
+ t.Helper()
+ normalizedActual := normalizeInstalls(actual)
+ android.AssertDeepEquals(t, message, expected, normalizedActual)
+}
+
+// expectedConfig encapsulates the expected properties that will be set in a bootImageConfig
+//
+// Each field <x> in here is compared against the corresponding field <x> in bootImageConfig.
+type expectedConfig struct {
+ name string
+ stem string
+ dir string
+ symbolsDir string
+ installDirOnDevice string
+ installDirOnHost string
+ profileInstallPathInApex string
+ modules android.ConfiguredJarList
+ dexPaths []string
+ dexPathsDeps []string
+ zip string
+ variants []*expectedVariant
+
+ // Mutated fields
+ profileInstalls []normalizedInstall
+ profileLicenseMetadataFile string
+}
+
+// expectedVariant encapsulates the expected properties that will be set in a bootImageVariant
+//
+// Each field <x> in here is compared against the corresponding field <x> in bootImageVariant
+// except for archType which is compared against the target.Arch.ArchType field in bootImageVariant.
+type expectedVariant struct {
+ archType android.ArchType
+ dexLocations []string
+ dexLocationsDeps []string
+ imagePathOnHost string
+ imagePathOnDevice string
+ imagesDeps []string
+ primaryImages string
+ primaryImagesDeps []string
+
+ // Mutated fields
+ installs []normalizedInstall
+ vdexInstalls []normalizedInstall
+ unstrippedInstalls []normalizedInstall
+ licenseMetadataFile string
+}
+
+// CheckArtBootImageConfig checks the status of the fields of the bootImageConfig and
+// bootImageVariant structures that are returned from artBootImageConfig.
+//
+// This is before any fields are mutated.
+func CheckArtBootImageConfig(t *testing.T, result *android.TestResult) {
+ checkArtBootImageConfig(t, result, false, "")
+}
+
+// getArtImageConfig gets the ART bootImageConfig that was created during the test.
+func getArtImageConfig(result *android.TestResult) *bootImageConfig {
+ pathCtx := &android.TestPathContext{TestResult: result}
+ imageConfig := artBootImageConfig(pathCtx)
+ return imageConfig
+}
+
+// checkArtBootImageConfig checks the ART boot image.
+//
+// mutated is true if this is called after fields in the image have been mutated by the ART
+// bootclasspath_fragment and false otherwise.
+func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated bool, expectedLicenseMetadataFile string) {
+ imageConfig := getArtImageConfig(result)
+
+ expected := &expectedConfig{
+ name: "art",
+ stem: "boot",
+ dir: "out/soong/test_device/dex_artjars",
+ symbolsDir: "out/soong/test_device/dex_artjars_unstripped",
+ installDirOnDevice: "system/framework",
+ installDirOnHost: "apex/art_boot_images/javalib",
+ profileInstallPathInApex: "etc/boot-image.prof",
+ modules: android.CreateTestConfiguredJarList([]string{"com.android.art:core1", "com.android.art:core2"}),
+ dexPaths: []string{"out/soong/test_device/dex_artjars_input/core1.jar", "out/soong/test_device/dex_artjars_input/core2.jar"},
+ dexPathsDeps: []string{"out/soong/test_device/dex_artjars_input/core1.jar", "out/soong/test_device/dex_artjars_input/core2.jar"},
+ zip: "out/soong/test_device/dex_artjars/art.zip",
+ variants: []*expectedVariant{
+ {
+ archType: android.Arm64,
+ dexLocations: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"},
+ dexLocationsDeps: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"},
+ imagePathOnHost: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art",
+ imagePathOnDevice: "/system/framework/arm64/boot.art",
+ imagesDeps: []string{
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex",
+ },
+ installs: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art",
+ to: "/apex/art_boot_images/javalib/arm64/boot.art",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat",
+ to: "/apex/art_boot_images/javalib/arm64/boot.oat",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art",
+ to: "/apex/art_boot_images/javalib/arm64/boot-core2.art",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat",
+ to: "/apex/art_boot_images/javalib/arm64/boot-core2.oat",
+ },
+ },
+ vdexInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex",
+ to: "/apex/art_boot_images/javalib/arm64/boot.vdex",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex",
+ to: "/apex/art_boot_images/javalib/arm64/boot-core2.vdex",
+ },
+ },
+ unstrippedInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot.oat",
+ to: "/apex/art_boot_images/javalib/arm64/boot.oat",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-core2.oat",
+ to: "/apex/art_boot_images/javalib/arm64/boot-core2.oat",
+ },
+ },
+ licenseMetadataFile: expectedLicenseMetadataFile,
+ },
+ {
+ archType: android.Arm,
+ dexLocations: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"},
+ dexLocationsDeps: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"},
+ imagePathOnHost: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art",
+ imagePathOnDevice: "/system/framework/arm/boot.art",
+ imagesDeps: []string{
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex",
+ },
+ installs: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art",
+ to: "/apex/art_boot_images/javalib/arm/boot.art",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat",
+ to: "/apex/art_boot_images/javalib/arm/boot.oat",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art",
+ to: "/apex/art_boot_images/javalib/arm/boot-core2.art",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat",
+ to: "/apex/art_boot_images/javalib/arm/boot-core2.oat",
+ },
+ },
+ vdexInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex",
+ to: "/apex/art_boot_images/javalib/arm/boot.vdex",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex",
+ to: "/apex/art_boot_images/javalib/arm/boot-core2.vdex",
+ },
+ },
+ unstrippedInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot.oat",
+ to: "/apex/art_boot_images/javalib/arm/boot.oat",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat",
+ to: "/apex/art_boot_images/javalib/arm/boot-core2.oat",
+ },
+ },
+ licenseMetadataFile: expectedLicenseMetadataFile,
+ },
+ {
+ archType: android.X86_64,
+ dexLocations: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"},
+ dexLocationsDeps: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"},
+ imagePathOnHost: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art",
+ imagePathOnDevice: "/system/framework/x86_64/boot.art",
+ imagesDeps: []string{
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex",
+ },
+ installs: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art",
+ to: "/apex/art_boot_images/javalib/x86_64/boot.art",
+ }, {
+ from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat",
+ to: "/apex/art_boot_images/javalib/x86_64/boot.oat",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art",
+ to: "/apex/art_boot_images/javalib/x86_64/boot-core2.art",
+ }, {
+ from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat",
+ to: "/apex/art_boot_images/javalib/x86_64/boot-core2.oat",
+ },
+ },
+ vdexInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex",
+ to: "/apex/art_boot_images/javalib/x86_64/boot.vdex",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex",
+ to: "/apex/art_boot_images/javalib/x86_64/boot-core2.vdex",
+ },
+ },
+ unstrippedInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat",
+ to: "/apex/art_boot_images/javalib/x86_64/boot.oat",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat",
+ to: "/apex/art_boot_images/javalib/x86_64/boot-core2.oat",
+ },
+ },
+ licenseMetadataFile: expectedLicenseMetadataFile,
+ },
+ {
+ archType: android.X86,
+ dexLocations: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"},
+ dexLocationsDeps: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"},
+ imagePathOnHost: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art",
+ imagePathOnDevice: "/system/framework/x86/boot.art",
+ imagesDeps: []string{
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex",
+ },
+ installs: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art",
+ to: "/apex/art_boot_images/javalib/x86/boot.art",
+ }, {
+ from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat",
+ to: "/apex/art_boot_images/javalib/x86/boot.oat",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art",
+ to: "/apex/art_boot_images/javalib/x86/boot-core2.art",
+ }, {
+ from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat",
+ to: "/apex/art_boot_images/javalib/x86/boot-core2.oat",
+ },
+ },
+ vdexInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex",
+ to: "/apex/art_boot_images/javalib/x86/boot.vdex",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex",
+ to: "/apex/art_boot_images/javalib/x86/boot-core2.vdex",
+ },
+ },
+ unstrippedInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat",
+ to: "/apex/art_boot_images/javalib/x86/boot.oat",
+ },
+ {
+ from: "out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat",
+ to: "/apex/art_boot_images/javalib/x86/boot-core2.oat",
+ },
+ },
+ licenseMetadataFile: expectedLicenseMetadataFile,
+ },
+ },
+ }
+
+ checkBootImageConfig(t, imageConfig, mutated, expected)
+}
+
+// getFrameworkImageConfig gets the framework bootImageConfig that was created during the test.
+func getFrameworkImageConfig(result *android.TestResult) *bootImageConfig {
+ pathCtx := &android.TestPathContext{TestResult: result}
+ imageConfig := defaultBootImageConfig(pathCtx)
+ return imageConfig
+}
+
+// CheckFrameworkBootImageConfig checks the status of the fields of the bootImageConfig and
+// bootImageVariant structures that are returned from defaultBootImageConfig.
+//
+// This is before any fields are mutated.
+func CheckFrameworkBootImageConfig(t *testing.T, result *android.TestResult) {
+ checkFrameworkBootImageConfig(t, result, false, "")
+}
+
+// checkFrameworkBootImageConfig checks the framework boot image.
+//
+// mutated is true if this is called after fields in the image have been mutated by the
+// platform_bootclasspath and false otherwise.
+func checkFrameworkBootImageConfig(t *testing.T, result *android.TestResult, mutated bool, expectedLicenseMetadataFile string) {
+ imageConfig := getFrameworkImageConfig(result)
+
+ expected := &expectedConfig{
+ name: "boot",
+ stem: "boot",
+ dir: "out/soong/test_device/dex_bootjars",
+ symbolsDir: "out/soong/test_device/dex_bootjars_unstripped",
+ installDirOnDevice: "system/framework",
+ installDirOnHost: "system/framework",
+ profileInstallPathInApex: "",
+ modules: android.CreateTestConfiguredJarList([]string{"platform:framework"}),
+ dexPaths: []string{"out/soong/test_device/dex_bootjars_input/framework.jar"},
+ dexPathsDeps: []string{"out/soong/test_device/dex_artjars_input/core1.jar", "out/soong/test_device/dex_artjars_input/core2.jar", "out/soong/test_device/dex_bootjars_input/framework.jar"},
+ zip: "out/soong/test_device/dex_bootjars/boot.zip",
+ variants: []*expectedVariant{
+ {
+ archType: android.Arm64,
+ dexLocations: []string{"/system/framework/framework.jar"},
+ dexLocationsDeps: []string{
+ "/apex/com.android.art/javalib/core1.jar",
+ "/apex/com.android.art/javalib/core2.jar",
+ "/system/framework/framework.jar",
+ },
+ imagePathOnHost: "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art",
+ imagePathOnDevice: "/system/framework/arm64/boot-framework.art",
+ imagesDeps: []string{
+ "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art",
+ "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.oat",
+ "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.vdex",
+ },
+ primaryImages: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art",
+ primaryImagesDeps: []string{
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex",
+ },
+ installs: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art",
+ to: "/system/framework/arm64/boot-framework.art",
+ },
+ {
+ from: "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.oat",
+ to: "/system/framework/arm64/boot-framework.oat",
+ },
+ },
+ vdexInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.vdex",
+ to: "/system/framework/arm64/boot-framework.vdex",
+ },
+ },
+ unstrippedInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_bootjars_unstripped/android/system/framework/arm64/boot-framework.oat",
+ to: "/system/framework/arm64/boot-framework.oat",
+ },
+ },
+ licenseMetadataFile: expectedLicenseMetadataFile,
+ },
+ {
+ archType: android.Arm,
+ dexLocations: []string{"/system/framework/framework.jar"},
+ dexLocationsDeps: []string{
+ "/apex/com.android.art/javalib/core1.jar",
+ "/apex/com.android.art/javalib/core2.jar",
+ "/system/framework/framework.jar",
+ },
+ imagePathOnHost: "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art",
+ imagePathOnDevice: "/system/framework/arm/boot-framework.art",
+ imagesDeps: []string{
+ "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art",
+ "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.oat",
+ "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.vdex",
+ },
+ primaryImages: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art",
+ primaryImagesDeps: []string{
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat",
+ "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex",
+ },
+ installs: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art",
+ to: "/system/framework/arm/boot-framework.art",
+ },
+ {
+ from: "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.oat",
+ to: "/system/framework/arm/boot-framework.oat",
+ },
+ },
+ vdexInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.vdex",
+ to: "/system/framework/arm/boot-framework.vdex",
+ },
+ },
+ unstrippedInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_bootjars_unstripped/android/system/framework/arm/boot-framework.oat",
+ to: "/system/framework/arm/boot-framework.oat",
+ },
+ },
+ licenseMetadataFile: expectedLicenseMetadataFile,
+ },
+ {
+ archType: android.X86_64,
+ dexLocations: []string{"host/linux-x86/system/framework/framework.jar"},
+ dexLocationsDeps: []string{
+ "host/linux-x86/apex/com.android.art/javalib/core1.jar",
+ "host/linux-x86/apex/com.android.art/javalib/core2.jar",
+ "host/linux-x86/system/framework/framework.jar",
+ },
+ imagePathOnHost: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art",
+ imagePathOnDevice: "/system/framework/x86_64/boot-framework.art",
+ imagesDeps: []string{
+ "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art",
+ "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.oat",
+ "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.vdex",
+ },
+ primaryImages: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art",
+ primaryImagesDeps: []string{
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex",
+ },
+ installs: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art",
+ to: "/system/framework/x86_64/boot-framework.art",
+ },
+ {
+ from: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.oat",
+ to: "/system/framework/x86_64/boot-framework.oat",
+ },
+ },
+ vdexInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.vdex",
+ to: "/system/framework/x86_64/boot-framework.vdex",
+ },
+ },
+ unstrippedInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_bootjars_unstripped/linux_glibc/system/framework/x86_64/boot-framework.oat",
+ to: "/system/framework/x86_64/boot-framework.oat",
+ },
+ },
+ licenseMetadataFile: expectedLicenseMetadataFile,
+ },
+ {
+ archType: android.X86,
+ dexLocations: []string{"host/linux-x86/system/framework/framework.jar"},
+ dexLocationsDeps: []string{
+ "host/linux-x86/apex/com.android.art/javalib/core1.jar",
+ "host/linux-x86/apex/com.android.art/javalib/core2.jar",
+ "host/linux-x86/system/framework/framework.jar",
+ },
+ imagePathOnHost: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art",
+ imagePathOnDevice: "/system/framework/x86/boot-framework.art",
+ imagesDeps: []string{
+ "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art",
+ "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat",
+ "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex",
+ },
+ primaryImages: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art",
+ primaryImagesDeps: []string{
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat",
+ "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex",
+ },
+ installs: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art",
+ to: "/system/framework/x86/boot-framework.art",
+ },
+ {
+ from: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat",
+ to: "/system/framework/x86/boot-framework.oat",
+ },
+ },
+ vdexInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex",
+ to: "/system/framework/x86/boot-framework.vdex",
+ },
+ },
+ unstrippedInstalls: []normalizedInstall{
+ {
+ from: "out/soong/test_device/dex_bootjars_unstripped/linux_glibc/system/framework/x86/boot-framework.oat",
+ to: "/system/framework/x86/boot-framework.oat",
+ },
+ },
+ licenseMetadataFile: expectedLicenseMetadataFile,
+ },
+ },
+ profileInstalls: []normalizedInstall{
+ {from: "out/soong/test_device/dex_bootjars/boot.bprof", to: "/system/etc/boot-image.bprof"},
+ {from: "out/soong/test_device/dex_bootjars/boot.prof", to: "/system/etc/boot-image.prof"},
+ },
+ profileLicenseMetadataFile: expectedLicenseMetadataFile,
+ }
+
+ checkBootImageConfig(t, imageConfig, mutated, expected)
+}
+
+// clearMutatedFields clears fields in the expectedConfig that correspond to fields in the
+// bootImageConfig/bootImageVariant structs which are mutated outside the call to
+// genBootImageConfigs.
+//
+// This allows the resulting expectedConfig struct to be compared against the values of those boot
+// image structs immediately the call to genBootImageConfigs. If this is not called then the
+// expectedConfig struct will expect the boot image structs to have been mutated by the ART
+// bootclasspath_fragment and the platform_bootclasspath.
+func clearMutatedFields(expected *expectedConfig) {
+ expected.profileInstalls = nil
+ expected.profileLicenseMetadataFile = ""
+ for _, variant := range expected.variants {
+ variant.installs = nil
+ variant.vdexInstalls = nil
+ variant.unstrippedInstalls = nil
+ variant.licenseMetadataFile = ""
+ }
+}
+
+// checkBootImageConfig checks a boot image against the expected contents.
+//
+// If mutated is false then this will clear any mutated fields in the expected contents back to the
+// zero value so that they will match the unmodified values in the boot image.
+//
+// It runs the checks in an image specific subtest of the current test.
+func checkBootImageConfig(t *testing.T, imageConfig *bootImageConfig, mutated bool, expected *expectedConfig) {
+ if !mutated {
+ clearMutatedFields(expected)
+ }
+
+ t.Run(imageConfig.name, func(t *testing.T) {
+ nestedCheckBootImageConfig(t, imageConfig, expected)
+ })
+}
+
+// nestedCheckBootImageConfig does the work of comparing the image against the expected values and
+// is run in an image specific subtest.
+func nestedCheckBootImageConfig(t *testing.T, imageConfig *bootImageConfig, expected *expectedConfig) {
+ android.AssertStringEquals(t, "name", expected.name, imageConfig.name)
+ android.AssertStringEquals(t, "stem", expected.stem, imageConfig.stem)
+ android.AssertPathRelativeToTopEquals(t, "dir", expected.dir, imageConfig.dir)
+ android.AssertPathRelativeToTopEquals(t, "symbolsDir", expected.symbolsDir, imageConfig.symbolsDir)
+ android.AssertStringEquals(t, "installDirOnDevice", expected.installDirOnDevice, imageConfig.installDirOnDevice)
+ android.AssertStringEquals(t, "installDirOnHost", expected.installDirOnHost, imageConfig.installDirOnHost)
+ android.AssertStringEquals(t, "profileInstallPathInApex", expected.profileInstallPathInApex, imageConfig.profileInstallPathInApex)
+ android.AssertDeepEquals(t, "modules", expected.modules, imageConfig.modules)
+ android.AssertPathsRelativeToTopEquals(t, "dexPaths", expected.dexPaths, imageConfig.dexPaths.Paths())
+ android.AssertPathsRelativeToTopEquals(t, "dexPathsDeps", expected.dexPathsDeps, imageConfig.dexPathsDeps.Paths())
+ // dexPathsByModule is just a different representation of the other information in the config.
+ android.AssertPathRelativeToTopEquals(t, "zip", expected.zip, imageConfig.zip)
+ assertInstallsEqual(t, "profileInstalls", expected.profileInstalls, imageConfig.profileInstalls)
+ android.AssertStringEquals(t, "profileLicenseMetadataFile", expected.profileLicenseMetadataFile, imageConfig.profileLicenseMetadataFile.RelativeToTop().String())
+
+ android.AssertIntEquals(t, "variant count", 4, len(imageConfig.variants))
+ for i, variant := range imageConfig.variants {
+ expectedVariant := expected.variants[i]
+ t.Run(variant.target.Arch.ArchType.String(), func(t *testing.T) {
+ android.AssertDeepEquals(t, "archType", expectedVariant.archType, variant.target.Arch.ArchType)
+ android.AssertDeepEquals(t, "dexLocations", expectedVariant.dexLocations, variant.dexLocations)
+ android.AssertDeepEquals(t, "dexLocationsDeps", expectedVariant.dexLocationsDeps, variant.dexLocationsDeps)
+ android.AssertPathRelativeToTopEquals(t, "imagePathOnHost", expectedVariant.imagePathOnHost, variant.imagePathOnHost)
+ android.AssertStringEquals(t, "imagePathOnDevice", expectedVariant.imagePathOnDevice, variant.imagePathOnDevice)
+ android.AssertPathsRelativeToTopEquals(t, "imagesDeps", expectedVariant.imagesDeps, variant.imagesDeps.Paths())
+ android.AssertPathRelativeToTopEquals(t, "primaryImages", expectedVariant.primaryImages, variant.primaryImages)
+ android.AssertPathsRelativeToTopEquals(t, "primaryImagesDeps", expectedVariant.primaryImagesDeps, variant.primaryImagesDeps)
+ assertInstallsEqual(t, "installs", expectedVariant.installs, variant.installs)
+ assertInstallsEqual(t, "vdexInstalls", expectedVariant.vdexInstalls, variant.vdexInstalls)
+ assertInstallsEqual(t, "unstrippedInstalls", expectedVariant.unstrippedInstalls, variant.unstrippedInstalls)
+ android.AssertStringEquals(t, "licenseMetadataFile", expectedVariant.licenseMetadataFile, variant.licenseMetadataFile.RelativeToTop().String())
+ })
+ }
+}
+
+// CheckMutatedArtBootImageConfig checks the mutated fields in the bootImageConfig/Variant for ART.
+func CheckMutatedArtBootImageConfig(t *testing.T, result *android.TestResult, expectedLicenseMetadataFile string) {
+ checkArtBootImageConfig(t, result, true, expectedLicenseMetadataFile)
+
+ // Check the dexpreopt make vars. Do it in here as it depends on the expected license metadata
+ // file at the moment and it
+ checkDexpreoptMakeVars(t, result, expectedLicenseMetadataFile)
+}
+
+// CheckMutatedFrameworkBootImageConfig checks the mutated fields in the bootImageConfig/Variant for framework.
+func CheckMutatedFrameworkBootImageConfig(t *testing.T, result *android.TestResult, expectedLicenseMetadataFile string) {
+ checkFrameworkBootImageConfig(t, result, true, expectedLicenseMetadataFile)
+}
+
+// checkDexpreoptMakeVars checks the DEXPREOPT_ prefixed make vars produced by dexpreoptBootJars
+// singleton.
+func checkDexpreoptMakeVars(t *testing.T, result *android.TestResult, expectedLicenseMetadataFile string) {
+ vars := result.MakeVarsForTesting(func(variable android.MakeVarVariable) bool {
+ return strings.HasPrefix(variable.Name(), "DEXPREOPT_")
+ })
+
+ out := &strings.Builder{}
+ for _, v := range vars {
+ fmt.Fprintf(out, "%s=%s\n", v.Name(), android.StringRelativeToTop(result.Config, v.Value()))
+ }
+ format := `
+DEXPREOPT_BOOTCLASSPATH_DEX_FILES=out/soong/test_device/dex_artjars_input/core1.jar out/soong/test_device/dex_artjars_input/core2.jar out/soong/test_device/dex_bootjars_input/framework.jar
+DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS=/apex/com.android.art/javalib/core1.jar /apex/com.android.art/javalib/core2.jar /system/framework/framework.jar
+DEXPREOPT_BOOT_JARS_MODULES=platform:framework
+DEXPREOPT_GEN=out/host/linux-x86/bin/dexpreopt_gen
+DEXPREOPT_IMAGE_BUILT_INSTALLED_art_arm=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art:/apex/art_boot_images/javalib/arm/boot.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art:/apex/art_boot_images/javalib/arm/boot-core2.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat
+DEXPREOPT_IMAGE_BUILT_INSTALLED_art_arm64=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art:/apex/art_boot_images/javalib/arm64/boot.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art:/apex/art_boot_images/javalib/arm64/boot-core2.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat
+DEXPREOPT_IMAGE_BUILT_INSTALLED_art_host_x86=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art:/apex/art_boot_images/javalib/x86/boot.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art:/apex/art_boot_images/javalib/x86/boot-core2.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat
+DEXPREOPT_IMAGE_BUILT_INSTALLED_art_host_x86_64=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art:/apex/art_boot_images/javalib/x86_64/boot.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat:/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art:/apex/art_boot_images/javalib/x86_64/boot-core2.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat:/apex/art_boot_images/javalib/x86_64/boot-core2.oat
+DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_arm=out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art:/system/framework/arm/boot-framework.art out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.oat:/system/framework/arm/boot-framework.oat
+DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art:/system/framework/arm64/boot-framework.art out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.oat:/system/framework/arm64/boot-framework.oat
+DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art:/system/framework/x86/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat:/system/framework/x86/boot-framework.oat
+DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art:/system/framework/x86_64/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.oat:/system/framework/x86_64/boot-framework.oat
+DEXPREOPT_IMAGE_DEPS_art_arm=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex
+DEXPREOPT_IMAGE_DEPS_art_arm64=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex
+DEXPREOPT_IMAGE_DEPS_art_host_x86=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex
+DEXPREOPT_IMAGE_DEPS_art_host_x86_64=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex
+DEXPREOPT_IMAGE_DEPS_boot_arm=out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.oat out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.vdex
+DEXPREOPT_IMAGE_DEPS_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.oat out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.vdex
+DEXPREOPT_IMAGE_DEPS_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex
+DEXPREOPT_IMAGE_DEPS_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.oat out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.vdex
+DEXPREOPT_IMAGE_LICENSE_METADATA_art_arm=%[1]s
+DEXPREOPT_IMAGE_LICENSE_METADATA_art_arm64=%[1]s
+DEXPREOPT_IMAGE_LICENSE_METADATA_art_host_x86=%[1]s
+DEXPREOPT_IMAGE_LICENSE_METADATA_art_host_x86_64=%[1]s
+DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
+DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
+DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
+DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86_64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
+DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEart=/system/framework/boot.art
+DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEboot=/system/framework/boot.art:/system/framework/boot-framework.art
+DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTart=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/boot.art
+DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTboot=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/boot.art:out/soong/test_device/dex_bootjars/android/system/framework/boot-framework.art
+DEXPREOPT_IMAGE_NAMES=art boot
+DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED=out/soong/test_device/dex_bootjars/boot.bprof:/system/etc/boot-image.bprof out/soong/test_device/dex_bootjars/boot.prof:/system/etc/boot-image.prof
+DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
+DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm=out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat
+DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm64=out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat
+DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86=out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat
+DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86_64=out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat:/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat:/apex/art_boot_images/javalib/x86_64/boot-core2.oat
+DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_arm=out/soong/test_device/dex_bootjars_unstripped/android/system/framework/arm/boot-framework.oat:/system/framework/arm/boot-framework.oat
+DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_arm64=out/soong/test_device/dex_bootjars_unstripped/android/system/framework/arm64/boot-framework.oat:/system/framework/arm64/boot-framework.oat
+DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_host_x86=out/soong/test_device/dex_bootjars_unstripped/linux_glibc/system/framework/x86/boot-framework.oat:/system/framework/x86/boot-framework.oat
+DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_host_x86_64=out/soong/test_device/dex_bootjars_unstripped/linux_glibc/system/framework/x86_64/boot-framework.oat:/system/framework/x86_64/boot-framework.oat
+DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex:/apex/art_boot_images/javalib/arm/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex:/apex/art_boot_images/javalib/arm/boot-core2.vdex
+DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm64=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex:/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex:/apex/art_boot_images/javalib/arm64/boot-core2.vdex
+DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_host_x86=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex:/apex/art_boot_images/javalib/x86/boot.vdex out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex:/apex/art_boot_images/javalib/x86/boot-core2.vdex
+DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_host_x86_64=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex:/apex/art_boot_images/javalib/x86_64/boot.vdex out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex:/apex/art_boot_images/javalib/x86_64/boot-core2.vdex
+DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_arm=out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.vdex:/system/framework/arm/boot-framework.vdex
+DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.vdex:/system/framework/arm64/boot-framework.vdex
+DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex:/system/framework/x86/boot-framework.vdex
+DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.vdex:/system/framework/x86_64/boot-framework.vdex
+DEXPREOPT_IMAGE_ZIP_art=out/soong/test_device/dex_artjars/art.zip
+DEXPREOPT_IMAGE_ZIP_boot=out/soong/test_device/dex_bootjars/boot.zip
+DEXPREOPT_IMAGE_art_arm=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art
+DEXPREOPT_IMAGE_art_arm64=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art
+DEXPREOPT_IMAGE_art_host_x86=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art
+DEXPREOPT_IMAGE_art_host_x86_64=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art
+DEXPREOPT_IMAGE_boot_arm=out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art
+DEXPREOPT_IMAGE_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art
+DEXPREOPT_IMAGE_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art
+DEXPREOPT_IMAGE_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art
+`
+ expected := strings.TrimSpace(fmt.Sprintf(format, expectedLicenseMetadataFile))
+ actual := strings.TrimSpace(out.String())
+ android.AssertStringEquals(t, "vars", expected, actual)
+}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 9b1f43b4c..2173dae30 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -267,7 +267,7 @@ func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
- ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...)
+ ctx.AddVariationDependencies(nil, sdkLibTag, sdkDep.classpath...)
}
}
@@ -367,7 +367,7 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
} else {
panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
}
- case libTag:
+ case libTag, sdkLibTag:
if dep, ok := module.(SdkLibraryDependency); ok {
deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...)
} else if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
@@ -684,7 +684,7 @@ func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs andro
outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
cmd := rule.Command().
- BuiltTool("soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
+ BuiltTool("soong_javac_wrapper").Tool(android.PathForSource(ctx, "prebuilts/jdk/jdk11/linux-x86/bin/javadoc")).
Flag(config.JavacVmFlags).
FlagWithArg("-encoding ", "UTF-8").
FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "javadoc.rsp"), srcs).
@@ -755,6 +755,7 @@ func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
return rule.Command().
BuiltTool("dokka").
Flag(config.JavacVmFlags).
+ Flag("-J--add-opens=java.base/java.lang=ALL-UNNAMED").
Flag(srcJarDir.String()).
FlagWithInputList("-classpath ", dokkaClasspath, ":").
FlagWithArg("-format ", "dac").
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 12590ca50..5777b185c 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -17,6 +17,7 @@ package java
import (
"fmt"
"path/filepath"
+ "regexp"
"strings"
"github.com/google/blueprint/proptools"
@@ -27,7 +28,7 @@ import (
)
// The values allowed for Droidstubs' Api_levels_sdk_type
-var allowedApiLevelSdkTypes = []string{"public", "system", "module-lib"}
+var allowedApiLevelSdkTypes = []string{"public", "system", "module-lib", "system-server"}
func init() {
RegisterStubsBuildComponents(android.InitRegistrationContext)
@@ -133,7 +134,7 @@ type DroidstubsProperties struct {
// the dirs which Metalava extracts API levels annotations from.
Api_levels_annotations_dirs []string
- // the sdk kind which Metalava extracts API levels annotations from. Supports 'public', 'system' and 'module-lib' for now; defaults to public.
+ // the sdk kind which Metalava extracts API levels annotations from. Supports 'public', 'system', 'module-lib' and 'system-server'; defaults to public.
Api_levels_sdk_type *string
// the filename which Metalava extracts API levels annotations from. Defaults to android.jar.
@@ -142,6 +143,10 @@ type DroidstubsProperties struct {
// if set to true, collect the values used by the Dev tools and
// write them in files packaged with the SDK. Defaults to false.
Write_sdk_values *bool
+
+ // path or filegroup to file defining extension an SDK name <-> numerical ID mapping and
+ // what APIs exist in which SDKs; passed to metalava via --sdk-extensions-info
+ Extensions_info_file *string `android:"path"`
}
// Used by xsd_config
@@ -398,9 +403,20 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an
filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
var dirs []string
+ var extensions_dir string
ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
if t, ok := m.(*ExportedDroiddocDir); ok {
+ extRegex := regexp.MustCompile(t.dir.String() + `/extensions/[0-9]+/public/.*\.jar`)
+
+ // Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
+ // ideally this should be read from prebuiltApis.properties.Extensions_*
for _, dep := range t.deps {
+ if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
+ if extensions_dir == "" {
+ extensions_dir = t.dir.String() + "/extensions"
+ }
+ cmd.Implicit(dep)
+ }
if dep.Base() == filename {
cmd.Implicit(dep)
}
@@ -429,6 +445,8 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an
// for older releases. Similarly, module-lib falls back to system API.
var sdkDirs []string
switch proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") {
+ case "system-server":
+ sdkDirs = []string{"system-server", "module-lib", "system", "public"}
case "module-lib":
sdkDirs = []string{"module-lib", "system", "public"}
case "system":
@@ -445,6 +463,16 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an
cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, filename))
}
}
+
+ if d.properties.Extensions_info_file != nil {
+ if extensions_dir == "" {
+ ctx.ModuleErrorf("extensions_info_file set, but no SDK extension dirs found")
+ }
+ info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
+ cmd.Implicit(info_file)
+ cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir)
+ cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
+ }
}
func metalavaUseRbe(ctx android.ModuleContext) bool {
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index 9fdfddeb1..25f8c8667 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -122,7 +122,7 @@ func getAndroidJarPatternsForDroidstubs(t *testing.T, sdkType string) []string {
"some-other-exported-dir",
],
api_levels_annotations_enabled: true,
- api_levels_sdk_type: "%s",
+ api_levels_sdk_type: "%s",
}
`, sdkType),
map[string][]byte{
@@ -169,6 +169,21 @@ func TestModuleLibDroidstubs(t *testing.T) {
}, patterns)
}
+func TestSystemServerDroidstubs(t *testing.T) {
+ patterns := getAndroidJarPatternsForDroidstubs(t, "system-server")
+
+ android.AssertArrayString(t, "order of patterns", []string{
+ "--android-jar-pattern somedir/%/system-server/android.jar",
+ "--android-jar-pattern someotherdir/%/system-server/android.jar",
+ "--android-jar-pattern somedir/%/module-lib/android.jar",
+ "--android-jar-pattern someotherdir/%/module-lib/android.jar",
+ "--android-jar-pattern somedir/%/system/android.jar",
+ "--android-jar-pattern someotherdir/%/system/android.jar",
+ "--android-jar-pattern somedir/%/public/android.jar",
+ "--android-jar-pattern someotherdir/%/public/android.jar",
+ }, patterns)
+}
+
func TestDroidstubsSandbox(t *testing.T) {
ctx, _ := testJavaWithFS(t, `
genrule {
@@ -259,3 +274,33 @@ func checkSystemModulesUseByDroidstubs(t *testing.T, ctx *android.TestContext, m
t.Errorf("inputs of %q must be []string{%q}, but was %#v.", moduleName, systemJar, systemJars)
}
}
+
+func TestDroidstubsWithSdkExtensions(t *testing.T) {
+ ctx, _ := testJavaWithFS(t, `
+ droiddoc_exported_dir {
+ name: "sdk-dir",
+ path: "sdk",
+ }
+
+ droidstubs {
+ name: "baz-stubs",
+ api_levels_annotations_dirs: ["sdk-dir"],
+ api_levels_annotations_enabled: true,
+ extensions_info_file: ":info-file",
+ }
+
+ filegroup {
+ name: "info-file",
+ srcs: ["sdk/extensions/info.txt"],
+ }
+ `,
+ map[string][]byte{
+ "sdk/extensions/1/public/some-mainline-module-stubs.jar": nil,
+ "sdk/extensions/info.txt": nil,
+ })
+ m := ctx.ModuleForTests("baz-stubs", "android_common")
+ manifest := m.Output("metalava.sbox.textproto")
+ cmdline := String(android.RuleBuilderSboxProtoForTests(t, manifest).Commands[0].Command)
+ android.AssertStringDoesContain(t, "sdk-extensions-root present", cmdline, "--sdk-extensions-root sdk/extensions")
+ android.AssertStringDoesContain(t, "sdk-extensions-info present", cmdline, "--sdk-extensions-info sdk/extensions/info.txt")
+}
diff --git a/java/fuzz.go b/java/fuzz.go
index d0f369f2f..1d6b91346 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -15,6 +15,7 @@
package java
import (
+ "path/filepath"
"sort"
"strings"
@@ -26,6 +27,11 @@ import (
"android/soong/fuzz"
)
+const (
+ hostString = "host"
+ targetString = "target"
+)
+
type jniProperties struct {
// list of jni libs
Jni_libs []string
@@ -39,8 +45,10 @@ func init() {
}
func RegisterJavaFuzzBuildComponents(ctx android.RegistrationContext) {
- ctx.RegisterModuleType("java_fuzz_host", FuzzFactory)
- ctx.RegisterSingletonType("java_fuzz_packaging", javaFuzzPackagingFactory)
+ ctx.RegisterModuleType("java_fuzz", JavaFuzzFactory)
+ ctx.RegisterModuleType("java_fuzz_host", JavaFuzzHostFactory)
+ ctx.RegisterSingletonType("java_fuzz_host_packaging", javaFuzzHostPackagingFactory)
+ ctx.RegisterSingletonType("java_fuzz_device_packaging", javaFuzzDevicePackagingFactory)
}
type JavaFuzzLibrary struct {
@@ -55,11 +63,11 @@ type JavaFuzzLibrary struct {
// sanitized for the given sanitizer or not.
func (j *JavaFuzzLibrary) IsSanitizerEnabledForJni(ctx android.BaseModuleContext, sanitizerName string) bool {
// TODO: once b/231370928 is resolved, please uncomment the loop
- // for _, s := range j.jniProperties.Sanitizers {
- // if sanitizerName == s {
- // return true
- // }
- // }
+ // for _, s := range j.jniProperties.Sanitizers {
+ // if sanitizerName == s {
+ // return true
+ // }
+ // }
return false
}
@@ -72,7 +80,6 @@ func (j *JavaFuzzLibrary) DepsMutator(mctx android.BottomUpMutatorContext) {
// this will be used by the ingestion pipeline to determine the version
// of jazzer to add to the fuzzer package
j.fuzzPackagedModule.FuzzProperties.Fuzz_config.IsJni = proptools.BoolPtr(true)
-
for _, target := range mctx.MultiTargets() {
sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
mctx.AddFarVariationDependencies(sharedLibVariations, cc.JniFuzzLibTag, j.jniProperties.Jni_libs...)
@@ -91,17 +98,28 @@ func (j *JavaFuzzLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
if j.fuzzPackagedModule.FuzzProperties.Dictionary != nil {
j.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *j.fuzzPackagedModule.FuzzProperties.Dictionary)
}
-
if j.fuzzPackagedModule.FuzzProperties.Fuzz_config != nil {
configPath := android.PathForModuleOut(ctx, "config").Join(ctx, "config.json")
android.WriteFileRule(ctx, configPath, j.fuzzPackagedModule.FuzzProperties.Fuzz_config.String())
j.fuzzPackagedModule.Config = configPath
}
- ctx.VisitDirectDepsWithTag(cc.JniFuzzLibTag, func(dep android.Module) {
+ _, sharedDeps := cc.CollectAllSharedDependencies(ctx)
+
+ for _, dep := range sharedDeps {
sharedLibInfo := ctx.OtherModuleProvider(dep, cc.SharedLibraryInfoProvider).(cc.SharedLibraryInfo)
if sharedLibInfo.SharedLibrary != nil {
- libPath := android.PathForModuleOut(ctx, sharedLibInfo.SharedLibrary.Base())
+ // The .class jars are output in slightly different locations
+ // relative to the jni libs. Therefore, for consistency across
+ // host and device fuzzers of jni lib location, we save it in a
+ // native_libs directory.
+ var relPath string
+ if sharedLibInfo.Target.Arch.ArchType.Multilib == "lib64" {
+ relPath = filepath.Join("lib64", sharedLibInfo.SharedLibrary.Base())
+ } else {
+ relPath = filepath.Join("lib", sharedLibInfo.SharedLibrary.Base())
+ }
+ libPath := android.PathForModuleOut(ctx, relPath)
ctx.Build(pctx, android.BuildParams{
Rule: android.Cp,
Input: sharedLibInfo.SharedLibrary,
@@ -111,18 +129,17 @@ func (j *JavaFuzzLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
} else {
ctx.PropertyErrorf("jni_libs", "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep))
}
- })
+ }
j.Library.GenerateAndroidBuildActions(ctx)
}
-// java_fuzz builds and links sources into a `.jar` file for the host.
+// java_fuzz_host builds and links sources into a `.jar` file for the host.
//
// By default, a java_fuzz produces a `.jar` file containing `.class` files.
// This jar is not suitable for installing on a device.
-func FuzzFactory() android.Module {
+func JavaFuzzHostFactory() android.Module {
module := &JavaFuzzLibrary{}
-
module.addHostProperties()
module.AddProperties(&module.jniProperties)
module.Module.properties.Installable = proptools.BoolPtr(true)
@@ -141,23 +158,54 @@ func FuzzFactory() android.Module {
ctx.AppendProperties(&disableLinuxBionic)
})
- module.initModuleAndImport(module)
- android.InitSdkAwareModule(module)
- InitJavaModuleMultiTargets(module, android.HostSupported)
+ InitJavaModuleMultiTargets(module, android.HostSupportedNoCross)
return module
}
-// Responsible for generating rules that package fuzz targets into
-// their architecture & target/host specific zip file.
-type javaFuzzPackager struct {
+// java_fuzz builds and links sources into a `.jar` file for the device.
+// This generates .class files in a jar which can then be instrumented before
+// fuzzing in Android Runtime (ART: Android OS on emulator or device)
+func JavaFuzzFactory() android.Module {
+ module := &JavaFuzzLibrary{}
+ module.addHostAndDeviceProperties()
+ module.AddProperties(&module.jniProperties)
+ module.Module.properties.Installable = proptools.BoolPtr(true)
+ module.AddProperties(&module.fuzzPackagedModule.FuzzProperties)
+ module.Module.dexpreopter.isTest = true
+ module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ InitJavaModuleMultiTargets(module, android.DeviceSupported)
+ return module
+}
+
+// Responsible for generating rules that package host fuzz targets into
+// a zip file.
+type javaFuzzHostPackager struct {
+ fuzz.FuzzPackager
+}
+
+// Responsible for generating rules that package device fuzz targets into
+// a zip file.
+type javaFuzzDevicePackager struct {
fuzz.FuzzPackager
}
-func javaFuzzPackagingFactory() android.Singleton {
- return &javaFuzzPackager{}
+func javaFuzzHostPackagingFactory() android.Singleton {
+ return &javaFuzzHostPackager{}
}
-func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
+func javaFuzzDevicePackagingFactory() android.Singleton {
+ return &javaFuzzDevicePackager{}
+}
+
+func (s *javaFuzzHostPackager) GenerateBuildActions(ctx android.SingletonContext) {
+ generateBuildActions(&s.FuzzPackager, hostString, ctx)
+}
+
+func (s *javaFuzzDevicePackager) GenerateBuildActions(ctx android.SingletonContext) {
+ generateBuildActions(&s.FuzzPackager, targetString, ctx)
+}
+
+func generateBuildActions(s *fuzz.FuzzPackager, hostOrTargetString string, ctx android.SingletonContext) {
// Map between each architecture + host/device combination.
archDirs := make(map[fuzz.ArchOs][]fuzz.FileToZip)
@@ -171,8 +219,14 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
return
}
- if javaFuzzModule.Target().HostCross {
- return
+ if hostOrTargetString == hostString {
+ if !javaFuzzModule.Host() {
+ return
+ }
+ } else if hostOrTargetString == targetString {
+ if javaFuzzModule.Host() || javaFuzzModule.Target().HostCross {
+ return
+ }
}
fuzzModuleValidator := fuzz.FuzzModule{
@@ -185,12 +239,7 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
return
}
- hostOrTargetString := "target"
- if javaFuzzModule.Host() {
- hostOrTargetString = "host"
- }
archString := javaFuzzModule.Arch().ArchType.String()
-
archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString)
archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
@@ -201,7 +250,7 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
files = s.PackageArtifacts(ctx, module, javaFuzzModule.fuzzPackagedModule, archDir, builder)
// Add .jar
- files = append(files, fuzz.FileToZip{javaFuzzModule.outputFile, ""})
+ files = append(files, fuzz.FileToZip{javaFuzzModule.implementationJarFile, ""})
// Add jni .so files
for _, fPath := range javaFuzzModule.jniFilePaths {
@@ -217,12 +266,22 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
s.CreateFuzzPackage(ctx, archDirs, fuzz.Java, pctx)
}
-func (s *javaFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
+func (s *javaFuzzHostPackager) MakeVars(ctx android.MakeVarsContext) {
+ packages := s.Packages.Strings()
+ sort.Strings(packages)
+
+ ctx.Strict("SOONG_JAVA_FUZZ_HOST_PACKAGING_ARCH_MODULES", strings.Join(packages, " "))
+
+ // Preallocate the slice of fuzz targets to minimize memory allocations.
+ s.PreallocateSlice(ctx, "ALL_JAVA_FUZZ_HOST_TARGETS")
+}
+
+func (s *javaFuzzDevicePackager) MakeVars(ctx android.MakeVarsContext) {
packages := s.Packages.Strings()
sort.Strings(packages)
- ctx.Strict("SOONG_JAVA_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " "))
+ ctx.Strict("SOONG_JAVA_FUZZ_DEVICE_PACKAGING_ARCH_MODULES", strings.Join(packages, " "))
// Preallocate the slice of fuzz targets to minimize memory allocations.
- s.PreallocateSlice(ctx, "ALL_JAVA_FUZZ_TARGETS")
+ s.PreallocateSlice(ctx, "ALL_JAVA_FUZZ_DEVICE_TARGETS")
}
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index 7b678037c..5474ae11e 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -594,6 +594,23 @@ func (i *HiddenAPIInfo) FlagSubset() SignatureCsvSubset {
var HiddenAPIInfoProvider = blueprint.NewProvider(HiddenAPIInfo{})
+// HiddenAPIInfoForSdk contains information provided by the hidden API processing for use
+// by the sdk snapshot.
+//
+// That includes paths resolved from HiddenAPIFlagFileProperties and also generated by hidden API
+// processing.
+type HiddenAPIInfoForSdk struct {
+ // FlagFilesByCategory maps from the flag file category to the paths containing information for
+ // that category.
+ FlagFilesByCategory FlagFilesByCategory
+
+ // The output from the hidden API processing needs to be made available to other modules.
+ HiddenAPIFlagOutput
+}
+
+// Provides hidden API info for the sdk snapshot.
+var HiddenAPIInfoForSdkProvider = blueprint.NewProvider(HiddenAPIInfoForSdk{})
+
// ModuleStubDexJars contains the stub dex jars provided by a single module.
//
// It maps a *HiddenAPIScope to the path to stub dex jars appropriate for that scope. See
@@ -1024,8 +1041,11 @@ func (s SignatureCsvSubsets) RelativeToTop() []string {
// patterns that will select a subset of the monolithic flags.
func buildRuleSignaturePatternsFile(
ctx android.ModuleContext, flagsPath android.Path,
- splitPackages []string, packagePrefixes []string, singlePackages []string) android.Path {
- patternsFile := android.PathForModuleOut(ctx, "modular-hiddenapi", "signature-patterns.csv")
+ splitPackages []string, packagePrefixes []string, singlePackages []string,
+ suffix string) android.Path {
+ hiddenApiSubDir := "modular-hiddenapi" + suffix
+
+ patternsFile := android.PathForModuleOut(ctx, hiddenApiSubDir, "signature-patterns.csv")
// Create a rule to validate the output from the following rule.
rule := android.NewRuleBuilder(pctx, ctx)
@@ -1042,7 +1062,7 @@ func buildRuleSignaturePatternsFile(
FlagForEachArg("--package-prefix ", packagePrefixes).
FlagForEachArg("--single-package ", singlePackages).
FlagWithOutput("--output ", patternsFile)
- rule.Build("hiddenAPISignaturePatterns", "hidden API signature patterns")
+ rule.Build("hiddenAPISignaturePatterns"+suffix, "hidden API signature patterns"+suffix)
return patternsFile
}
@@ -1116,8 +1136,8 @@ func buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name strin
return validFile
}
-// hiddenAPIRulesForBootclasspathFragment will generate all the flags for a fragment of the
-// bootclasspath and then encode the flags into the boot dex files.
+// hiddenAPIFlagRulesForBootclasspathFragment will generate all the flags for a fragment of the
+// bootclasspath.
//
// It takes:
// * Map from android.SdkKind to stub dex jar paths defining the API for that sdk kind.
@@ -1130,31 +1150,27 @@ func buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name strin
// * metadata.csv
// * index.csv
// * all-flags.csv
-// * encoded boot dex files
-func hiddenAPIRulesForBootclasspathFragment(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
- hiddenApiSubDir := "modular-hiddenapi"
-
- // Gather information about the boot dex files for the boot libraries provided by this fragment.
- bootDexInfoByModule := extractBootDexInfoFromModules(ctx, contents)
+func hiddenAPIFlagRulesForBootclasspathFragment(ctx android.ModuleContext, bootDexInfoByModule bootDexInfoByModule, contents []android.Module, input HiddenAPIFlagInput, suffix string) HiddenAPIFlagOutput {
+ hiddenApiSubDir := "modular-hiddenapi" + suffix
// Generate the stub-flags.csv.
stubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "stub-flags.csv")
- buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "modularHiddenAPIStubFlagsFile", "modular hiddenapi stub flags", stubFlagsCSV, bootDexInfoByModule.bootDexJars(), input, nil)
+ buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "modularHiddenAPIStubFlagsFile"+suffix, "modular hiddenapi stub flags", stubFlagsCSV, bootDexInfoByModule.bootDexJars(), input, nil)
// Extract the classes jars from the contents.
classesJars := extractClassesJarsFromModules(contents)
// Generate the set of flags from the annotations in the source code.
annotationFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "annotation-flags.csv")
- buildRuleToGenerateAnnotationFlags(ctx, "modular hiddenapi annotation flags", classesJars, stubFlagsCSV, annotationFlagsCSV)
+ buildRuleToGenerateAnnotationFlags(ctx, "modular hiddenapi annotation flags"+suffix, classesJars, stubFlagsCSV, annotationFlagsCSV)
// Generate the metadata from the annotations in the source code.
metadataCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "metadata.csv")
- buildRuleToGenerateMetadata(ctx, "modular hiddenapi metadata", classesJars, stubFlagsCSV, metadataCSV)
+ buildRuleToGenerateMetadata(ctx, "modular hiddenapi metadata"+suffix, classesJars, stubFlagsCSV, metadataCSV)
// Generate the index file from the CSV files in the classes jars.
indexCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "index.csv")
- buildRuleToGenerateIndex(ctx, "modular hiddenapi index", classesJars, indexCSV)
+ buildRuleToGenerateIndex(ctx, "modular hiddenapi index"+suffix, classesJars, indexCSV)
// Removed APIs need to be marked and in order to do that the hiddenAPIInfo needs to specify files
// containing dex signatures of all the removed APIs. In the monolithic files that is done by
@@ -1162,59 +1178,60 @@ func hiddenAPIRulesForBootclasspathFragment(ctx android.ModuleContext, contents
// signatures, see the combined-removed-dex module. This does that automatically by using the
// *removed.txt files retrieved from the java_sdk_library modules that are specified in the
// stub_libs and contents properties of a bootclasspath_fragment.
- removedDexSignatures := buildRuleToGenerateRemovedDexSignatures(ctx, input.RemovedTxtFiles)
+ removedDexSignatures := buildRuleToGenerateRemovedDexSignatures(ctx, suffix, input.RemovedTxtFiles)
// Generate the all-flags.csv which are the flags that will, in future, be encoded into the dex
// files.
allFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "all-flags.csv")
- buildRuleToGenerateHiddenApiFlags(ctx, "modularHiddenApiAllFlags", "modular hiddenapi all flags", allFlagsCSV, stubFlagsCSV, android.Paths{annotationFlagsCSV}, input.FlagFilesByCategory, nil, removedDexSignatures)
-
- // Encode the flags into the boot dex files.
- encodedBootDexJarsByModule := map[string]android.Path{}
- outputDir := android.PathForModuleOut(ctx, "hiddenapi-modular/encoded").OutputPath
- for _, name := range android.SortedStringKeys(bootDexInfoByModule) {
- bootDexInfo := bootDexInfoByModule[name]
- unencodedDex := bootDexInfo.path
- encodedDex := hiddenAPIEncodeDex(ctx, unencodedDex, allFlagsCSV, bootDexInfo.uncompressDex, bootDexInfo.minSdkVersion, outputDir)
- encodedBootDexJarsByModule[name] = encodedDex
- }
+ buildRuleToGenerateHiddenApiFlags(ctx, "modularHiddenApiAllFlags"+suffix, "modular hiddenapi all flags"+suffix, allFlagsCSV, stubFlagsCSV, android.Paths{annotationFlagsCSV}, input.FlagFilesByCategory, nil, removedDexSignatures)
// Generate the filtered-stub-flags.csv file which contains the filtered stub flags that will be
// compared against the monolithic stub flags.
filteredStubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "filtered-stub-flags.csv")
- buildRuleRemoveSignaturesWithImplementationFlags(ctx, "modularHiddenApiFilteredStubFlags",
- "modular hiddenapi filtered stub flags", stubFlagsCSV, filteredStubFlagsCSV,
+ buildRuleRemoveSignaturesWithImplementationFlags(ctx, "modularHiddenApiFilteredStubFlags"+suffix,
+ "modular hiddenapi filtered stub flags"+suffix, stubFlagsCSV, filteredStubFlagsCSV,
HIDDENAPI_STUB_FLAGS_IMPL_FLAGS)
// Generate the filtered-flags.csv file which contains the filtered flags that will be compared
// against the monolithic flags.
filteredFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "filtered-flags.csv")
- buildRuleRemoveSignaturesWithImplementationFlags(ctx, "modularHiddenApiFilteredFlags",
- "modular hiddenapi filtered flags", allFlagsCSV, filteredFlagsCSV,
+ buildRuleRemoveSignaturesWithImplementationFlags(ctx, "modularHiddenApiFilteredFlags"+suffix,
+ "modular hiddenapi filtered flags"+suffix, allFlagsCSV, filteredFlagsCSV,
HIDDENAPI_FLAGS_CSV_IMPL_FLAGS)
// Store the paths in the info for use by other modules and sdk snapshot generation.
- output := HiddenAPIOutput{
- HiddenAPIFlagOutput: HiddenAPIFlagOutput{
- AnnotationFlagsPath: annotationFlagsCSV,
- MetadataPath: metadataCSV,
- IndexPath: indexCSV,
- StubFlagsPath: stubFlagsCSV,
- AllFlagsPath: allFlagsCSV,
- FilteredStubFlagsPath: filteredStubFlagsCSV,
- FilteredFlagsPath: filteredFlagsCSV,
- },
- EncodedBootDexFilesByModule: encodedBootDexJarsByModule,
+ return HiddenAPIFlagOutput{
+ AnnotationFlagsPath: annotationFlagsCSV,
+ MetadataPath: metadataCSV,
+ IndexPath: indexCSV,
+ StubFlagsPath: stubFlagsCSV,
+ AllFlagsPath: allFlagsCSV,
+ FilteredStubFlagsPath: filteredStubFlagsCSV,
+ FilteredFlagsPath: filteredFlagsCSV,
+ }
+}
+
+// hiddenAPIEncodeRulesForBootclasspathFragment generates rules to encode hidden API flags into the
+// dex jars in bootDexInfoByModule.
+func hiddenAPIEncodeRulesForBootclasspathFragment(ctx android.ModuleContext, bootDexInfoByModule bootDexInfoByModule, allFlagsCSV android.Path) bootDexJarByModule {
+ // Encode the flags into the boot dex files.
+ encodedBootDexJarsByModule := bootDexJarByModule{}
+ outputDir := android.PathForModuleOut(ctx, "hiddenapi-modular/encoded").OutputPath
+ for _, name := range android.SortedStringKeys(bootDexInfoByModule) {
+ bootDexInfo := bootDexInfoByModule[name]
+ unencodedDex := bootDexInfo.path
+ encodedDex := hiddenAPIEncodeDex(ctx, unencodedDex, allFlagsCSV, bootDexInfo.uncompressDex, bootDexInfo.minSdkVersion, outputDir)
+ encodedBootDexJarsByModule[name] = encodedDex
}
- return &output
+ return encodedBootDexJarsByModule
}
-func buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, removedTxtFiles android.Paths) android.OptionalPath {
+func buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, suffix string, removedTxtFiles android.Paths) android.OptionalPath {
if len(removedTxtFiles) == 0 {
return android.OptionalPath{}
}
- output := android.PathForModuleOut(ctx, "modular-hiddenapi/removed-dex-signatures.txt")
+ output := android.PathForModuleOut(ctx, "module-hiddenapi"+suffix, "removed-dex-signatures.txt")
rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().
@@ -1222,7 +1239,7 @@ func buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, removedT
Flag("--no-banner").
Inputs(removedTxtFiles).
FlagWithOutput("--dex-api ", output)
- rule.Build("modular-hiddenapi-removed-dex-signatures", "modular hiddenapi removed dex signatures")
+ rule.Build("modular-hiddenapi-removed-dex-signatures"+suffix, "modular hiddenapi removed dex signatures"+suffix)
return android.OptionalPathForPath(output)
}
diff --git a/java/jacoco.go b/java/jacoco.go
index e11c2ce69..f8012b852 100644
--- a/java/jacoco.go
+++ b/java/jacoco.go
@@ -47,6 +47,34 @@ var (
"strippedJar", "stripSpec", "tmpDir", "tmpJar")
)
+func jacocoDepsMutator(ctx android.BottomUpMutatorContext) {
+ type instrumentable interface {
+ shouldInstrument(ctx android.BaseModuleContext) bool
+ shouldInstrumentInApex(ctx android.BaseModuleContext) bool
+ setInstrument(value bool)
+ }
+
+ j, ok := ctx.Module().(instrumentable)
+ if !ctx.Module().Enabled() || !ok {
+ return
+ }
+
+ if j.shouldInstrumentInApex(ctx) {
+ j.setInstrument(true)
+ }
+
+ if j.shouldInstrument(ctx) && ctx.ModuleName() != "jacocoagent" {
+ // We can use AddFarVariationDependencies here because, since this dep
+ // is added as libs only (i.e. a compiletime CLASSPATH entry only),
+ // the first variant of jacocoagent is sufficient to prevent
+ // compile time errors.
+ // At this stage in the build, AddVariationDependencies is not always
+ // able to procure a variant of jacocoagent that matches the calling
+ // module.
+ ctx.AddFarVariationDependencies(ctx.Module().Target().Variations(), libTag, "jacocoagent")
+ }
+}
+
// Instruments a jar using the Jacoco command line interface. Uses stripSpec to extract a subset
// of the classes in inputJar into strippedJar, instruments strippedJar into tmpJar, and then
// combines the classes in tmpJar with inputJar (preferring the instrumented classes in tmpJar)
diff --git a/java/java.go b/java/java.go
index 0251b5754..5091d26a2 100644
--- a/java/java.go
+++ b/java/java.go
@@ -66,6 +66,8 @@ func registerJavaBuildComponents(ctx android.RegistrationContext) {
// to support the checks in dexpreoptDisabled().
ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel()
+ // needs access to ApexInfoProvider which is available after variant creation
+ ctx.BottomUp("jacoco_deps", jacocoDepsMutator).Parallel()
})
ctx.RegisterSingletonType("logtags", LogtagsSingleton)
@@ -346,6 +348,7 @@ var (
dataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"}
staticLibTag = dependencyTag{name: "staticlib"}
libTag = dependencyTag{name: "javalib", runtimeLinked: true}
+ sdkLibTag = dependencyTag{name: "sdklib", runtimeLinked: true}
java9LibTag = dependencyTag{name: "java9lib", runtimeLinked: true}
pluginTag = dependencyTag{name: "plugin", toolchain: true}
errorpronePluginTag = dependencyTag{name: "errorprone-plugin", toolchain: true}
@@ -372,7 +375,7 @@ var (
)
func IsLibDepTag(depTag blueprint.DependencyTag) bool {
- return depTag == libTag
+ return depTag == libTag || depTag == sdkLibTag
}
func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool {
@@ -418,6 +421,7 @@ type jniLib struct {
target android.Target
coverageFile android.OptionalPath
unstrippedFile android.Path
+ partition string
}
func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) {
@@ -425,7 +429,7 @@ func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext,
if sdkDep.useModule {
ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
- ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...)
+ ctx.AddVariationDependencies(nil, sdkLibTag, sdkDep.classpath...)
if d.effectiveOptimizeEnabled() && sdkDep.hasStandardLibs() {
ctx.AddVariationDependencies(nil, proguardRaiseTag, config.LegacyCorePlatformBootclasspathLibraries...)
}
@@ -1652,7 +1656,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
switch tag {
- case libTag:
+ case libTag, sdkLibTag:
flags.classpath = append(flags.classpath, dep.HeaderJars...)
flags.dexClasspath = append(flags.dexClasspath, dep.HeaderJars...)
case staticLibTag:
@@ -1662,7 +1666,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
} else if dep, ok := module.(SdkLibraryDependency); ok {
switch tag {
- case libTag:
+ case libTag, sdkLibTag:
flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...)
}
}
@@ -2176,7 +2180,7 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module,
}
depTag := ctx.OtherModuleDependencyTag(depModule)
- if depTag == libTag {
+ if IsLibDepTag(depTag) {
// Ok, propagate <uses-library> through non-static library dependencies.
} else if tag, ok := depTag.(usesLibraryDependencyTag); ok && tag.sdkVersion == dexpreopt.AnySdkVersion {
// Ok, propagate <uses-library> through non-compatibility <uses-library> dependencies.
diff --git a/java/java_test.go b/java/java_test.go
index 7f0cea718..d2373e349 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -588,8 +588,8 @@ func TestPrebuilts(t *testing.T) {
sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").Rule("combineJar").Output
fooLibrary := fooModule.Module().(*Library)
- assertDeepEquals(t, "foo java sources incorrect",
- []string{"a.java"}, fooLibrary.compiledJavaSrcs.Strings())
+ assertDeepEquals(t, "foo unique sources incorrect",
+ []string{"a.java"}, fooLibrary.uniqueSrcFiles.Strings())
assertDeepEquals(t, "foo java source jars incorrect",
[]string{".intermediates/stubs-source/android_common/stubs-source-stubs.srcjar"},
diff --git a/java/lint.go b/java/lint.go
index 931820d74..fcd6d31ff 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -473,20 +473,23 @@ func (l *linter) lint(ctx android.ModuleContext) {
cmd.FlagWithOutput("--write-reference-baseline ", baseline)
- cmd.Text("|| (").Text("if [ -e").Input(text).Text("]; then cat").Input(text).Text("; fi; exit 7)")
-
- rule.Command().Text("rm -rf").Flag(lintPaths.cacheDir.String()).Flag(lintPaths.homeDir.String())
-
- // The HTML output contains a date, remove it to make the output deterministic.
- rule.Command().Text(`sed -i.tmp -e 's|Check performed at .*\(</nav>\)|\1|'`).Output(html)
+ cmd.Text("; EXITCODE=$?; ")
// The sources in the sandbox may have been modified by --apply-suggestions, zip them up and
- // export them out of the sandbox.
- rule.Command().BuiltTool("soong_zip").
+ // export them out of the sandbox. Do this before exiting so that the suggestions exit even after
+ // a fatal error.
+ cmd.BuiltTool("soong_zip").
FlagWithOutput("-o ", android.PathForModuleOut(ctx, "lint", "suggested-fixes.zip")).
FlagWithArg("-C ", cmd.PathForInput(android.PathForSource(ctx))).
FlagWithInput("-r ", srcsList)
+ cmd.Text("; if [ $EXITCODE != 0 ]; then if [ -e").Input(text).Text("]; then cat").Input(text).Text("; fi; exit $EXITCODE; fi")
+
+ rule.Command().Text("rm -rf").Flag(lintPaths.cacheDir.String()).Flag(lintPaths.homeDir.String())
+
+ // The HTML output contains a date, remove it to make the output deterministic.
+ rule.Command().Text(`sed -i.tmp -e 's|Check performed at .*\(</nav>\)|\1|'`).Output(html)
+
rule.Build("lint", "lint")
l.outputs = lintOutputs{
diff --git a/java/lint_defaults.txt b/java/lint_defaults.txt
index 01e7e6e75..519a702ef 100644
--- a/java/lint_defaults.txt
+++ b/java/lint_defaults.txt
@@ -39,6 +39,7 @@
# Downgrade existing errors to warnings
--warning_check AppCompatResource # 55 occurences in 10 modules
--warning_check AppLinkUrlError # 111 occurences in 53 modules
+--warning_check BinderGetCallingInMainThread
--warning_check ByteOrderMark # 2 occurences in 2 modules
--warning_check DuplicateActivity # 3 occurences in 3 modules
--warning_check DuplicateDefinition # 3623 occurences in 48 modules
@@ -91,6 +92,7 @@
--warning_check StringFormatInvalid # 148 occurences in 11 modules
--warning_check StringFormatMatches # 4800 occurences in 30 modules
--warning_check UnknownId # 8 occurences in 7 modules
+--warning_check UnspecifiedImmutableFlag
--warning_check ValidFragment # 12 occurences in 5 modules
--warning_check ValidRestrictions # 5 occurences in 1 modules
--warning_check WebViewLayout # 3 occurences in 1 modules
diff --git a/java/lint_test.go b/java/lint_test.go
index 456e6ba73..62450d573 100644
--- a/java/lint_test.go
+++ b/java/lint_test.go
@@ -271,7 +271,7 @@ func TestJavaLintDatabaseSelectionPublicFiltered(t *testing.T) {
"a.java",
],
min_sdk_version: "29",
- sdk_version: "module_current",
+ sdk_version: "XXX",
lint: {
strict_updatability_linting: true,
},
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 24f8253ae..f0de7a4d8 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -436,10 +436,10 @@ func (b *platformBootclasspathModule) generateBootImageBuildActions(ctx android.
profile := bootImageProfileRule(ctx, imageConfig)
// Build boot image files for the android variants.
- androidBootImageFilesByArch := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
+ androidBootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
// Zip the android variant boot image files up.
- buildBootImageZipInPredefinedLocation(ctx, imageConfig, androidBootImageFilesByArch)
+ buildBootImageZipInPredefinedLocation(ctx, imageConfig, androidBootImageFiles.byArch)
// Build boot image files for the host variants. There are use directly by ART host side tests.
buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 944970783..c6acd55e5 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -255,12 +255,11 @@ func prebuiltApiFiles(mctx android.LoadHookContext, p *prebuiltApis) {
if p.properties.Extensions_dir != nil {
extensionApiFiles := globExtensionDirs(mctx, p, "api/*.txt")
for k, v := range getLatest(extensionApiFiles) {
- if v.version > mctx.Config().PlatformBaseSdkExtensionVersion() {
- if _, exists := latest[k]; !exists {
- mctx.ModuleErrorf("Module %v finalized for extension %d but never during an API level; likely error", v.module, v.version)
- }
- latest[k] = v
+ if _, exists := latest[k]; !exists {
+ mctx.ModuleErrorf("Module %v finalized for extension %d but never during an API level; likely error", v.module, v.version)
}
+ // The extension version is always at least as new as the last sdk int version (potentially identical)
+ latest[k] = v
}
}
diff --git a/java/prebuilt_apis_test.go b/java/prebuilt_apis_test.go
index 75422ad45..2b8435325 100644
--- a/java/prebuilt_apis_test.go
+++ b/java/prebuilt_apis_test.go
@@ -61,7 +61,7 @@ func TestPrebuiltApis_SystemModulesCreation(t *testing.T) {
}
func TestPrebuiltApis_WithExtensions(t *testing.T) {
- runTestWithBaseExtensionLevel := func(v int) (foo_input string, bar_input string) {
+ runTestWithBaseExtensionLevel := func(v int) (foo_input, bar_input, baz_input string) {
result := android.GroupFixturePreparers(
prepareForJavaTest,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -69,7 +69,7 @@ func TestPrebuiltApis_WithExtensions(t *testing.T) {
}),
FixtureWithPrebuiltApisAndExtensions(map[string][]string{
"31": {"foo"},
- "32": {"foo", "bar"},
+ "32": {"foo", "bar", "baz"},
"current": {"foo", "bar"},
}, map[string][]string{
"1": {"foo"},
@@ -78,15 +78,24 @@ func TestPrebuiltApis_WithExtensions(t *testing.T) {
).RunTest(t)
foo_input = result.ModuleForTests("foo.api.public.latest", "").Rule("generator").Implicits[0].String()
bar_input = result.ModuleForTests("bar.api.public.latest", "").Rule("generator").Implicits[0].String()
+ baz_input = result.ModuleForTests("baz.api.public.latest", "").Rule("generator").Implicits[0].String()
return
}
- // Here, the base extension level is 1, so extension level 2 is the latest
- foo_input, bar_input := runTestWithBaseExtensionLevel(1)
- android.AssertStringEquals(t, "Expected latest = extension level 2", "prebuilts/sdk/extensions/2/public/api/foo.txt", foo_input)
- android.AssertStringEquals(t, "Expected latest = extension level 2", "prebuilts/sdk/extensions/2/public/api/bar.txt", bar_input)
+ // Extension 2 is the latest for both foo and bar, finalized after the base extension version.
+ foo_input, bar_input, baz_input := runTestWithBaseExtensionLevel(1)
+ android.AssertStringEquals(t, "Expected latest foo = extension level 2", "prebuilts/sdk/extensions/2/public/api/foo.txt", foo_input)
+ android.AssertStringEquals(t, "Expected latest bar = extension level 2", "prebuilts/sdk/extensions/2/public/api/bar.txt", bar_input)
+ android.AssertStringEquals(t, "Expected latest baz = api level 32", "prebuilts/sdk/32/public/api/baz.txt", baz_input)
- // Here, the base extension level is 2, so 2 is not later than 32.
- foo_input, bar_input = runTestWithBaseExtensionLevel(2)
- android.AssertStringEquals(t, "Expected latest = api level 32", "prebuilts/sdk/32/public/api/foo.txt", foo_input)
- android.AssertStringEquals(t, "Expected latest = api level 32", "prebuilts/sdk/32/public/api/bar.txt", bar_input)
+ // Extension 2 is the latest for both foo and bar, finalized together with 32
+ foo_input, bar_input, baz_input = runTestWithBaseExtensionLevel(2)
+ android.AssertStringEquals(t, "Expected latest foo = extension level 2", "prebuilts/sdk/extensions/2/public/api/foo.txt", foo_input)
+ android.AssertStringEquals(t, "Expected latest bar = extension level 2", "prebuilts/sdk/extensions/2/public/api/bar.txt", bar_input)
+ android.AssertStringEquals(t, "Expected latest baz = api level 32", "prebuilts/sdk/32/public/api/baz.txt", baz_input)
+
+ // Extension 3 is the current extension, but it has not yet been finalized.
+ foo_input, bar_input, baz_input = runTestWithBaseExtensionLevel(3)
+ android.AssertStringEquals(t, "Expected latest foo = extension level 2", "prebuilts/sdk/extensions/2/public/api/foo.txt", foo_input)
+ android.AssertStringEquals(t, "Expected latest bar = extension level 2", "prebuilts/sdk/extensions/2/public/api/bar.txt", bar_input)
+ android.AssertStringEquals(t, "Expected latest baz = api level 32", "prebuilts/sdk/32/public/api/baz.txt", baz_input)
}
diff --git a/java/resourceshrinker.go b/java/resourceshrinker.go
new file mode 100644
index 000000000..6d5960157
--- /dev/null
+++ b/java/resourceshrinker.go
@@ -0,0 +1,43 @@
+// Copyright 2022 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+ "android/soong/android"
+
+ "github.com/google/blueprint"
+)
+
+var shrinkResources = pctx.AndroidStaticRule("shrinkResources",
+ blueprint.RuleParams{
+ Command: `${config.ResourceShrinkerCmd} --output $out --input $in --raw_resources $raw_resources`,
+ CommandDeps: []string{"${config.ResourceShrinkerCmd}"},
+ }, "raw_resources")
+
+func ShrinkResources(ctx android.ModuleContext, apk android.Path, outputFile android.WritablePath) {
+ protoFile := android.PathForModuleOut(ctx, apk.Base()+".proto.apk")
+ aapt2Convert(ctx, protoFile, apk, "proto")
+ strictModeFile := android.PathForSource(ctx, "prebuilts/cmdline-tools/shrinker.xml")
+ protoOut := android.PathForModuleOut(ctx, apk.Base()+".proto.out.apk")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: shrinkResources,
+ Input: protoFile,
+ Output: protoOut,
+ Args: map[string]string{
+ "raw_resources": strictModeFile.String(),
+ },
+ })
+ aapt2Convert(ctx, outputFile, protoOut, "binary")
+}
diff --git a/java/robolectric.go b/java/robolectric.go
index 71ffdb175..b6116ec9d 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -23,6 +23,7 @@ import (
"android/soong/android"
"android/soong/java/config"
"android/soong/tradefed"
+
"github.com/google/blueprint/proptools"
)
@@ -166,7 +167,7 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext)
instrumentedApp.implementationAndResourcesJar,
}
- for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
+ handleLibDeps := func(dep android.Module) {
m := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
r.libs = append(r.libs, ctx.OtherModuleName(dep))
if !android.InList(ctx.OtherModuleName(dep), config.FrameworkLibraries) {
@@ -174,15 +175,22 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext)
}
}
+ for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
+ handleLibDeps(dep)
+ }
+ for _, dep := range ctx.GetDirectDepsWithTag(sdkLibTag) {
+ handleLibDeps(dep)
+ }
+
r.combinedJar = android.PathForModuleOut(ctx, "robolectric_combined", r.outputFile.Base())
TransformJarsToJar(ctx, r.combinedJar, "combine jars", combinedJarJars, android.OptionalPath{},
false, nil, nil)
// TODO: this could all be removed if tradefed was used as the test runner, it will find everything
// annotated as a test and run it.
- for _, src := range r.compiledJavaSrcs {
+ for _, src := range r.uniqueSrcFiles {
s := src.Rel()
- if !strings.HasSuffix(s, "Test.java") {
+ if !strings.HasSuffix(s, "Test.java") && !strings.HasSuffix(s, "Test.kt") {
continue
} else if strings.HasSuffix(s, "/BaseRobolectricTest.java") {
continue
diff --git a/java/rro.go b/java/rro.go
index c12e748c6..9d0667cf0 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -142,11 +142,15 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC
aaptLinkFlags = append(aaptLinkFlags,
"--rename-overlay-target-package "+*r.overridableProperties.Target_package_name)
}
- r.aapt.buildActions(ctx, r, nil, nil, aaptLinkFlags...)
+ if r.overridableProperties.Category != nil {
+ aaptLinkFlags = append(aaptLinkFlags,
+ "--rename-overlay-category "+*r.overridableProperties.Category)
+ }
+ r.aapt.buildActions(ctx, r, nil, nil, false, aaptLinkFlags...)
// Sign the built package
_, _, certificates := collectAppDeps(ctx, r, false, false)
- certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx)
+ r.certificate, certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx)
signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk")
var lineageFile android.Path
if lineage := String(r.properties.Lineage); lineage != "" {
@@ -156,7 +160,6 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC
rotationMinSdkVersion := String(r.properties.RotationMinSdkVersion)
SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil, lineageFile, rotationMinSdkVersion)
- r.certificate = certificates[0]
r.outputFile = signed
partition := rroPartition(ctx)
@@ -221,6 +224,9 @@ type OverridableRuntimeResourceOverlayProperties struct {
// the target package name of this overlay app. The target package name in the manifest file is used if one was not given.
Target_package_name *string
+
+ // the rro category of this overlay. The category in the manifest file is used if one was not given.
+ Category *string
}
type OverrideRuntimeResourceOverlay struct {
diff --git a/java/rro_test.go b/java/rro_test.go
index 00ba5ba11..8067a4703 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -201,6 +201,7 @@ func TestOverrideRuntimeResourceOverlay(t *testing.T) {
base: "foo_overlay",
package_name: "com.android.bar.overlay",
target_package_name: "com.android.bar",
+ category: "mycategory",
}
`)
@@ -212,6 +213,7 @@ func TestOverrideRuntimeResourceOverlay(t *testing.T) {
targetVariant string
packageFlag string
targetPackageFlag string
+ categoryFlag string
}{
{
variantName: "android_common",
@@ -228,6 +230,7 @@ func TestOverrideRuntimeResourceOverlay(t *testing.T) {
targetVariant: "android_common_bar",
packageFlag: "com.android.bar.overlay",
targetPackageFlag: "com.android.bar",
+ categoryFlag: "mycategory",
},
}
for _, expected := range expectedVariants {
@@ -249,6 +252,7 @@ func TestOverrideRuntimeResourceOverlay(t *testing.T) {
checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", "")
checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag)
+ checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-category", expected.categoryFlag)
}
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 8f499b101..fad1df77c 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -65,8 +65,27 @@ type apiScope struct {
name string
// The api scope that this scope extends.
+ //
+ // This organizes the scopes into an extension hierarchy.
+ //
+ // If set this means that the API provided by this scope includes the API provided by the scope
+ // set in this field.
extends *apiScope
+ // The next api scope that a library that uses this scope can access.
+ //
+ // This organizes the scopes into an access hierarchy.
+ //
+ // If set this means that a library that can access this API can also access the API provided by
+ // the scope set in this field.
+ //
+ // A module that sets sdk_version: "<scope>_current" should have access to the <scope> API of
+ // every java_sdk_library that it depends on. If the library does not provide an API for <scope>
+ // then it will traverse up this access hierarchy to find an API that it does provide.
+ //
+ // If this is not set then it defaults to the scope set in extends.
+ canAccess *apiScope
+
// The legacy enabled status for a specific scope can be dependent on other
// properties that have been specified on the library so it is provided by
// a function that can determine the status by examining those properties.
@@ -107,7 +126,7 @@ type apiScope struct {
// The scope specific prefix to add to the api file base of "current.txt" or "removed.txt".
apiFilePrefix string
- // The scope specific prefix to add to the sdk library module name to construct a scope specific
+ // The scope specific suffix to add to the sdk library module name to construct a scope specific
// module name.
moduleSuffix string
@@ -193,6 +212,11 @@ func initApiScope(scope *apiScope) *apiScope {
}
}
+ // By default, a library that can access a scope can also access the scope it extends.
+ if scope.canAccess == nil {
+ scope.canAccess = scope.extends
+ }
+
// Escape any special characters in the arguments. This is needed because droidstubs
// passes these directly to the shell command.
scope.droidstubsArgs = proptools.ShellEscapeList(scopeSpecificArgs)
@@ -310,6 +334,14 @@ var (
apiScopeSystemServer = initApiScope(&apiScope{
name: "system-server",
extends: apiScopePublic,
+
+ // The system-server scope can access the module-lib scope.
+ //
+ // A module that provides a system-server API is appended to the standard bootclasspath that is
+ // used by the system server. So, it should be able to access module-lib APIs provided by
+ // libraries on the bootclasspath.
+ canAccess: apiScopeModuleLib,
+
// The system-server scope is disabled by default in legacy mode.
//
// Enabling this would break existing usages.
@@ -539,7 +571,7 @@ type sdkLibraryProperties struct {
}
// TODO: determines whether to create HTML doc or not
- //Html_doc *bool
+ // Html_doc *bool
}
// Paths to outputs from java_sdk_library and java_sdk_library_import.
@@ -926,7 +958,7 @@ func (c *commonToSdkLibraryAndImport) findScopePaths(scope *apiScope) *scopePath
// If this does not support the requested api scope then find the closest available
// scope it does support. Returns nil if no such scope is available.
func (c *commonToSdkLibraryAndImport) findClosestScopePath(scope *apiScope) *scopePaths {
- for s := scope; s != nil; s = s.extends {
+ for s := scope; s != nil; s = s.canAccess {
if paths := c.findScopePaths(s); paths != nil {
return paths
}
@@ -1354,7 +1386,7 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
// Provide additional information for inclusion in an sdk's generated .info file.
additionalSdkInfo := map[string]interface{}{}
additionalSdkInfo["dist_stem"] = module.distStem()
- baseModuleName := module.BaseModuleName()
+ baseModuleName := module.distStem()
scopes := map[string]interface{}{}
additionalSdkInfo["scopes"] = scopes
for scope, scopePaths := range module.scopePaths {
@@ -2236,8 +2268,9 @@ func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl
Sdk_version *string
Libs []string
Jars []string
- Prefer *bool
Compile_dex *bool
+
+ android.UserSuppliedPrebuiltProperties
}{}
props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
props.Sdk_version = scopeProperties.Sdk_version
@@ -2247,7 +2280,7 @@ func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl
props.Jars = scopeProperties.Jars
// The imports are preferred if the java_sdk_library_import is preferred.
- props.Prefer = proptools.BoolPtr(module.prebuilt.Prefer())
+ props.CopyUserSuppliedPropertiesFromPrebuilt(&module.prebuilt)
// The imports need to be compiled to dex if the java_sdk_library_import requests it.
compileDex := module.properties.Compile_dex
@@ -2261,16 +2294,18 @@ func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl
func (module *SdkLibraryImport) createPrebuiltStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
props := struct {
- Name *string
- Srcs []string
- Prefer *bool
+ Name *string
+ Srcs []string
+
+ android.UserSuppliedPrebuiltProperties
}{}
props.Name = proptools.StringPtr(module.stubsSourceModuleName(apiScope))
props.Srcs = scopeProperties.Stub_srcs
- mctx.CreateModule(PrebuiltStubsSourcesFactory, &props)
// The stubs source is preferred if the java_sdk_library_import is preferred.
- props.Prefer = proptools.BoolPtr(module.prebuilt.Prefer())
+ props.CopyUserSuppliedPropertiesFromPrebuilt(&module.prebuilt)
+
+ mctx.CreateModule(PrebuiltStubsSourcesFactory, &props)
}
// Add the dependencies on the child module in the component deps mutator so that it
@@ -2904,6 +2939,18 @@ var javaSdkLibrarySdkMemberType = &sdkLibrarySdkMemberType{
type sdkLibrarySdkMemberProperties struct {
android.SdkMemberPropertiesBase
+ // Stem name for files in the sdk snapshot.
+ //
+ // This is used to construct the path names of various sdk library files in the sdk snapshot to
+ // make sure that they match the finalized versions of those files in prebuilts/sdk.
+ //
+ // This property is marked as keep so that it will be kept in all instances of this struct, will
+ // not be cleared but will be copied to common structs. That is needed because this field is used
+ // to construct many file names for other parts of this struct and so it needs to be present in
+ // all structs. If it was not marked as keep then it would be cleared in some structs and so would
+ // be unavailable for generating file names if there were other properties that were still set.
+ Stem string `sdk:"keep"`
+
// Scope to per scope properties.
Scopes map[*apiScope]*scopeProperties
@@ -2965,6 +3012,9 @@ type scopeProperties struct {
func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
sdk := variant.(*SdkLibrary)
+ // Copy the stem name for files in the sdk snapshot.
+ s.Stem = sdk.distStem()
+
s.Scopes = make(map[*apiScope]*scopeProperties)
for _, apiScope := range allApiScopes {
paths := sdk.findScopePaths(apiScope)
@@ -3017,6 +3067,8 @@ func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberCo
propertySet.AddProperty("permitted_packages", s.Permitted_packages)
}
+ stem := s.Stem
+
for _, apiScope := range allApiScopes {
if properties, ok := s.Scopes[apiScope]; ok {
scopeSet := propertySet.AddPropertySet(apiScope.propertyName)
@@ -3025,7 +3077,7 @@ func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberCo
var jars []string
for _, p := range properties.Jars {
- dest := filepath.Join(scopeDir, ctx.Name()+"-stubs.jar")
+ dest := filepath.Join(scopeDir, stem+"-stubs.jar")
ctx.SnapshotBuilder().CopyToSnapshot(p, dest)
jars = append(jars, dest)
}
@@ -3033,31 +3085,31 @@ func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberCo
if ctx.SdkModuleContext().Config().IsEnvTrue("SOONG_SDK_SNAPSHOT_USE_SRCJAR") {
// Copy the stubs source jar into the snapshot zip as is.
- srcJarSnapshotPath := filepath.Join(scopeDir, ctx.Name()+".srcjar")
+ srcJarSnapshotPath := filepath.Join(scopeDir, stem+".srcjar")
ctx.SnapshotBuilder().CopyToSnapshot(properties.StubsSrcJar, srcJarSnapshotPath)
scopeSet.AddProperty("stub_srcs", []string{srcJarSnapshotPath})
} else {
// Merge the stubs source jar into the snapshot zip so that when it is unpacked
// the source files are also unpacked.
- snapshotRelativeDir := filepath.Join(scopeDir, ctx.Name()+"_stub_sources")
+ snapshotRelativeDir := filepath.Join(scopeDir, stem+"_stub_sources")
ctx.SnapshotBuilder().UnzipToSnapshot(properties.StubsSrcJar, snapshotRelativeDir)
scopeSet.AddProperty("stub_srcs", []string{snapshotRelativeDir})
}
if properties.CurrentApiFile != nil {
- currentApiSnapshotPath := apiScope.snapshotRelativeCurrentApiTxtPath(ctx.Name())
+ currentApiSnapshotPath := apiScope.snapshotRelativeCurrentApiTxtPath(stem)
ctx.SnapshotBuilder().CopyToSnapshot(properties.CurrentApiFile, currentApiSnapshotPath)
scopeSet.AddProperty("current_api", currentApiSnapshotPath)
}
if properties.RemovedApiFile != nil {
- removedApiSnapshotPath := apiScope.snapshotRelativeRemovedApiTxtPath(ctx.Name())
+ removedApiSnapshotPath := apiScope.snapshotRelativeRemovedApiTxtPath(stem)
ctx.SnapshotBuilder().CopyToSnapshot(properties.RemovedApiFile, removedApiSnapshotPath)
scopeSet.AddProperty("removed_api", removedApiSnapshotPath)
}
if properties.AnnotationsZip != nil {
- annotationsSnapshotPath := filepath.Join(scopeDir, ctx.Name()+"_annotations.zip")
+ annotationsSnapshotPath := filepath.Join(scopeDir, stem+"_annotations.zip")
ctx.SnapshotBuilder().CopyToSnapshot(properties.AnnotationsZip, annotationsSnapshotPath)
scopeSet.AddProperty("annotations", annotationsSnapshotPath)
}
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 805bc226f..096bca8a1 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -18,6 +18,7 @@ import (
"fmt"
"path/filepath"
"regexp"
+ "strings"
"testing"
"android/soong/android"
@@ -699,6 +700,80 @@ func TestJavaSdkLibrary_SystemServer(t *testing.T) {
`)
}
+func TestJavaSdkLibrary_SystemServer_AccessToStubScopeLibs(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ PrepareForTestWithJavaSdkLibraryFiles,
+ FixtureWithLastReleaseApis("foo-public", "foo-system", "foo-module-lib", "foo-system-server"),
+ ).RunTestWithBp(t, `
+ java_sdk_library {
+ name: "foo-public",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ public: {
+ enabled: true,
+ },
+ }
+
+ java_sdk_library {
+ name: "foo-system",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ system: {
+ enabled: true,
+ },
+ }
+
+ java_sdk_library {
+ name: "foo-module-lib",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ system: {
+ enabled: true,
+ },
+ module_lib: {
+ enabled: true,
+ },
+ }
+
+ java_sdk_library {
+ name: "foo-system-server",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ system_server: {
+ enabled: true,
+ },
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["a.java"],
+ libs: ["foo-public", "foo-system", "foo-module-lib", "foo-system-server"],
+ sdk_version: "system_server_current",
+ }
+ `)
+
+ stubsPath := func(name string, scope *apiScope) string {
+ name = scope.stubsLibraryModuleName(name)
+ return fmt.Sprintf("out/soong/.intermediates/%[1]s/android_common/turbine-combined/%[1]s.jar", name)
+ }
+
+ // The bar library should depend on the highest (where system server is highest and public is
+ // lowest) API scopes provided by each of the foo-* modules. The highest API scope provided by the
+ // foo-<x> module is <x>.
+ barLibrary := result.ModuleForTests("bar", "android_common").Rule("javac")
+ stubLibraries := []string{
+ stubsPath("foo-public", apiScopePublic),
+ stubsPath("foo-system", apiScopeSystem),
+ stubsPath("foo-module-lib", apiScopeModuleLib),
+ stubsPath("foo-system-server", apiScopeSystemServer),
+ }
+ expectedPattern := fmt.Sprintf(`^-classpath .*:\Q%s\E$`, strings.Join(stubLibraries, ":"))
+ if expected, actual := expectedPattern, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
+ t.Errorf("expected pattern %q to match %#q", expected, actual)
+ }
+}
+
func TestJavaSdkLibrary_MissingScope(t *testing.T) {
prepareForJavaTest.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`requires api scope module-lib from foo but it only has \[\] available`)).
@@ -875,11 +950,12 @@ func TestJavaSdkLibraryImport_WithSource(t *testing.T) {
})
}
-func TestJavaSdkLibraryImport_Preferred(t *testing.T) {
+func testJavaSdkLibraryImport_Preferred(t *testing.T, prefer string, preparer android.FixturePreparer) {
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("sdklib"),
+ preparer,
).RunTestWithBp(t, `
java_sdk_library {
name: "sdklib",
@@ -893,11 +969,37 @@ func TestJavaSdkLibraryImport_Preferred(t *testing.T) {
java_sdk_library_import {
name: "sdklib",
- prefer: true,
+ `+prefer+`
public: {
jars: ["a.jar"],
+ stub_srcs: ["a.java"],
+ current_api: "current.txt",
+ removed_api: "removed.txt",
+ annotations: "annotations.zip",
},
}
+
+ java_library {
+ name: "combined",
+ static_libs: [
+ "sdklib.stubs",
+ ],
+ java_resources: [
+ ":sdklib.stubs.source",
+ ":sdklib{.public.api.txt}",
+ ":sdklib{.public.removed-api.txt}",
+ ":sdklib{.public.annotations.zip}",
+ ],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+
+ java_library {
+ name: "public",
+ srcs: ["a.java"],
+ libs: ["sdklib"],
+ sdk_version: "current",
+ }
`)
CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{
@@ -913,9 +1015,48 @@ func TestJavaSdkLibraryImport_Preferred(t *testing.T) {
CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{
`dex2oatd`,
`prebuilt_sdklib.stubs`,
+ `prebuilt_sdklib.stubs.source`,
`sdklib.impl`,
`sdklib.xml`,
})
+
+ // Make sure that dependencies on child modules use the prebuilt when preferred.
+ CheckModuleDependencies(t, result.TestContext, "combined", "android_common", []string{
+ // Each use of :sdklib{...} adds a dependency onto prebuilt_sdklib.
+ `prebuilt_sdklib`,
+ `prebuilt_sdklib`,
+ `prebuilt_sdklib`,
+ `prebuilt_sdklib.stubs`,
+ `prebuilt_sdklib.stubs.source`,
+ })
+
+ // Make sure that dependencies on sdklib that resolve to one of the child libraries use the
+ // prebuilt library.
+ public := result.ModuleForTests("public", "android_common")
+ rule := public.Output("javac/public.jar")
+ inputs := rule.Implicits.Strings()
+ expected := "out/soong/.intermediates/prebuilt_sdklib.stubs/android_common/combined/sdklib.stubs.jar"
+ if !android.InList(expected, inputs) {
+ t.Errorf("expected %q to contain %q", inputs, expected)
+ }
+}
+
+func TestJavaSdkLibraryImport_Preferred(t *testing.T) {
+ t.Run("prefer", func(t *testing.T) {
+ testJavaSdkLibraryImport_Preferred(t, "prefer: true,", android.NullFixturePreparer)
+ })
+
+ t.Run("use_source_config_var", func(t *testing.T) {
+ testJavaSdkLibraryImport_Preferred(t,
+ "use_source_config_var: {config_namespace: \"acme\", var_name: \"use_source\"},",
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.VendorVars = map[string]map[string]string{
+ "acme": {
+ "use_source": "false",
+ },
+ }
+ }))
+ })
}
func TestJavaSdkLibraryEnforce(t *testing.T) {
diff --git a/java/testing.go b/java/testing.go
index 511cc5ddb..49430ee05 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -59,11 +59,9 @@ var PrepareForTestWithJavaBuildComponents = android.GroupFixturePreparers(
}.AddToFixture(),
)
-// Test fixture preparer that will define all default java modules except the
-// fake_tool_binary for dex2oatd.
-var PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd = android.GroupFixturePreparers(
- // Make sure that all the module types used in the defaults are registered.
- PrepareForTestWithJavaBuildComponents,
+var prepareForTestWithFrameworkDeps = android.GroupFixturePreparers(
+ // The java default module definitions.
+ android.FixtureAddTextFile(defaultJavaDir+"/Android.bp", gatherRequiredDepsForTest()),
// Additional files needed when test disallows non-existent source.
android.MockFS{
// Needed for framework-res
@@ -77,8 +75,14 @@ var PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd = android.GroupFixtu
"build/make/core/proguard.flags": nil,
"build/make/core/proguard_basic_keeps.flags": nil,
}.AddToFixture(),
- // The java default module definitions.
- android.FixtureAddTextFile(defaultJavaDir+"/Android.bp", gatherRequiredDepsForTest()),
+)
+
+// Test fixture preparer that will define all default java modules except the
+// fake_tool_binary for dex2oatd.
+var PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd = android.GroupFixturePreparers(
+ // Make sure that all the module types used in the defaults are registered.
+ PrepareForTestWithJavaBuildComponents,
+ prepareForTestWithFrameworkDeps,
// Add dexpreopt compat libs (android.test.base, etc.) and a fake dex2oatd module.
dexpreopt.PrepareForTestWithDexpreoptCompatLibs,
)
@@ -141,6 +145,30 @@ var PrepareForTestWithPrebuiltsOfCurrentApi = FixtureWithPrebuiltApis(map[string
"30": {},
})
+var prepareForTestWithFrameworkJacocoInstrumentation = android.GroupFixturePreparers(
+ android.FixtureMergeEnv(map[string]string{
+ "EMMA_INSTRUMENT_FRAMEWORK": "true",
+ }),
+ PrepareForTestWithJacocoInstrumentation,
+)
+
+// PrepareForTestWithJacocoInstrumentation creates a mock jacocoagent library that can be
+// depended on as part of the build process for instrumented Java modules.
+var PrepareForTestWithJacocoInstrumentation = android.GroupFixturePreparers(
+ android.FixtureMergeEnv(map[string]string{
+ "EMMA_INSTRUMENT": "true",
+ }),
+ android.FixtureAddFile("jacocoagent/Test.java", nil),
+ android.FixtureAddFile("jacocoagent/Android.bp", []byte(`
+ java_library {
+ name: "jacocoagent",
+ host_supported: true,
+ srcs: ["Test.java"],
+ sdk_version: "current",
+ }
+ `)),
+)
+
// FixtureWithPrebuiltApis creates a preparer that will define prebuilt api modules for the
// specified releases and modules.
//
@@ -365,6 +393,7 @@ func gatherRequiredDepsForTest() string {
aidl: {
export_include_dirs: ["framework/aidl"],
},
+ compile_dex: true,
}
android_app {